From cc4abf7d44d2e186761e6fdf83f7adb7bf7b315d Mon Sep 17 00:00:00 2001
From: Oren Shoham
Date: Wed, 14 Aug 2019 16:39:14 -0400
Subject: [PATCH 1/4] set amplitude smoothing parameter via message port
---
src/amplitude.js | 8 +++++---
src/audioWorklet/amplitudeProcessor.js | 19 +++++--------------
2 files changed, 10 insertions(+), 17 deletions(-)
diff --git a/src/amplitude.js b/src/amplitude.js
index 1a0708ed..f300fb22 100644
--- a/src/amplitude.js
+++ b/src/amplitude.js
@@ -53,8 +53,10 @@ define(function (require) {
this.audiocontext = p5sound.audiocontext;
this._workletNode = new AudioWorkletNode(this.audiocontext, processorNames.amplitudeProcessor, {
outputChannelCount: [1],
- parameterData: { smoothing: smoothing || 0 },
- processorOptions: { normalize: false }
+ processorOptions: {
+ normalize: false,
+ smoothing: smoothing || 0
+ }
});
this._workletNode.port.onmessage = function(event) {
@@ -256,7 +258,7 @@ define(function (require) {
*/
p5.Amplitude.prototype.smooth = function(s) {
if (s >= 0 && s < 1) {
- this._workletNode.parameters.get('smoothing').value = s;
+ this._workletNode.port.postMessage({ name: 'smoothing', smoothing: s });
} else {
console.log('Error: smoothing must be between 0 and 1');
}
diff --git a/src/audioWorklet/amplitudeProcessor.js b/src/audioWorklet/amplitudeProcessor.js
index 5aa1dfd3..a6452d76 100644
--- a/src/audioWorklet/amplitudeProcessor.js
+++ b/src/audioWorklet/amplitudeProcessor.js
@@ -2,22 +2,11 @@
const processorNames = preval.require('./processorNames');
class AmplitudeProcessor extends AudioWorkletProcessor {
- static get parameterDescriptors() {
- return [
- {
- name: 'smoothing',
- defaultValue: 0,
- minValue: 0,
- maxValue: 1,
- automationRate: 'k-rate'
- }
- ];
- }
-
constructor(options) {
super();
const processorOptions = options.processorOptions || {};
+ this.smoothing = processorOptions.smoothing || 0;
this.normalize = processorOptions.normalize || false;
this.stereoVol = [0, 0];
@@ -29,15 +18,17 @@ class AmplitudeProcessor extends AudioWorkletProcessor {
const data = event.data;
if (data.name === 'toggleNormalize') {
this.normalize = data.normalize;
+ } else if (data.name === 'smoothing') {
+ this.smoothing = Math.max(0, Math.min(1, data.smoothing));
}
};
}
// TO DO make this stereo / dependent on # of audio channels
- process(inputs, outputs, parameters) {
+ process(inputs, outputs) {
const input = inputs[0];
const output = outputs[0];
- const smoothing = parameters.smoothing;
+ const smoothing = this.smoothing;
for (let channel = 0; channel < input.length; ++channel) {
const inputBuffer = input[channel];
From 0b33ccf9cbeb89ea74a117a61bb6c041a0909a5a Mon Sep 17 00:00:00 2001
From: Oren Shoham
Date: Wed, 14 Aug 2019 16:40:14 -0400
Subject: [PATCH 2/4] Don't update soundFile position when paused
---
lib/p5.sound.js | 211 ++++++++++++-------------
lib/p5.sound.js.map | 2 +-
lib/p5.sound.min.js | 2 +-
lib/p5.sound.min.js.map | 2 +-
src/audioWorklet/soundFileProcessor.js | 19 ++-
src/soundfile.js | 16 +-
6 files changed, 130 insertions(+), 122 deletions(-)
diff --git a/lib/p5.sound.js b/lib/p5.sound.js
index 02532895..86bf5b8b 100644
--- a/lib/p5.sound.js
+++ b/lib/p5.sound.js
@@ -163,7 +163,7 @@ var __WEBPACK_AMD_DEFINE_RESULT__;!(__WEBPACK_AMD_DEFINE_RESULT__ = (function(){
"use strict";
var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;
-!(__WEBPACK_AMD_DEFINE_ARRAY__ = [__webpack_require__(16)], __WEBPACK_AMD_DEFINE_RESULT__ = (function (audiocontext) {
+!(__WEBPACK_AMD_DEFINE_ARRAY__ = [__webpack_require__(17)], __WEBPACK_AMD_DEFINE_RESULT__ = (function (audiocontext) {
/**
* Master contains AudioContext and the master sound output.
* @for p5
@@ -307,7 +307,7 @@ var __WEBPACK_AMD_DEFINE_RESULT__;
!(__WEBPACK_AMD_DEFINE_RESULT__ = (function (require) {
var p5sound = __webpack_require__(1);
- var CrossFade = __webpack_require__(50);
+ var CrossFade = __webpack_require__(51);
/**
* Effect is a base class for audio effects in p5.
* This module handles the nodes and methods that are
@@ -836,7 +836,7 @@ var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;!(__WEBPACK_AMD_
/* 8 */
/***/ (function(module, exports, __webpack_require__) {
-var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;!(__WEBPACK_AMD_DEFINE_ARRAY__ = [__webpack_require__(0),__webpack_require__(20),__webpack_require__(44),__webpack_require__(45),__webpack_require__(11)], __WEBPACK_AMD_DEFINE_RESULT__ = (function(t){return t.Type={Default:"number",Time:"time",Frequency:"frequency",TransportTime:"transportTime",Ticks:"ticks",NormalRange:"normalRange",AudioRange:"audioRange",Decibels:"db",Interval:"interval",BPM:"bpm",Positive:"positive",Cents:"cents",Degrees:"degrees",MIDI:"midi",BarsBeatsSixteenths:"barsBeatsSixteenths",Samples:"samples",Hertz:"hertz",Note:"note",Milliseconds:"milliseconds",Seconds:"seconds",Notation:"notation"},t.prototype.toSeconds=function(e){return this.isNumber(e)?e:this.isUndef(e)?this.now():this.isString(e)?new t.Time(e).toSeconds():e instanceof t.TimeBase?e.toSeconds():void 0},t.prototype.toFrequency=function(e){return this.isNumber(e)?e:this.isString(e)||this.isUndef(e)?new t.Frequency(e).valueOf():e instanceof t.TimeBase?e.toFrequency():void 0},t.prototype.toTicks=function(e){return this.isNumber(e)||this.isString(e)?new t.TransportTime(e).toTicks():this.isUndef(e)?t.Transport.ticks:e instanceof t.TimeBase?e.toTicks():void 0},t}).apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__),
+var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;!(__WEBPACK_AMD_DEFINE_ARRAY__ = [__webpack_require__(0),__webpack_require__(20),__webpack_require__(45),__webpack_require__(46),__webpack_require__(11)], __WEBPACK_AMD_DEFINE_RESULT__ = (function(t){return t.Type={Default:"number",Time:"time",Frequency:"frequency",TransportTime:"transportTime",Ticks:"ticks",NormalRange:"normalRange",AudioRange:"audioRange",Decibels:"db",Interval:"interval",BPM:"bpm",Positive:"positive",Cents:"cents",Degrees:"degrees",MIDI:"midi",BarsBeatsSixteenths:"barsBeatsSixteenths",Samples:"samples",Hertz:"hertz",Note:"note",Milliseconds:"milliseconds",Seconds:"seconds",Notation:"notation"},t.prototype.toSeconds=function(e){return this.isNumber(e)?e:this.isUndef(e)?this.now():this.isString(e)?new t.Time(e).toSeconds():e instanceof t.TimeBase?e.toSeconds():void 0},t.prototype.toFrequency=function(e){return this.isNumber(e)?e:this.isString(e)||this.isUndef(e)?new t.Frequency(e).valueOf():e instanceof t.TimeBase?e.toFrequency():void 0},t.prototype.toTicks=function(e){return this.isNumber(e)||this.isString(e)?new t.TransportTime(e).toTicks():this.isUndef(e)?t.Transport.ticks:e instanceof t.TimeBase?e.toTicks():void 0},t}).apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__),
__WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));
/***/ }),
@@ -858,7 +858,7 @@ var __WEBPACK_AMD_DEFINE_RESULT__;
Helper function to generate an error
with a custom stack trace that points to the sketch
and removes other parts of the stack trace.
- @private
+ @private
@class customError
@constructor
@param {String} name custom error name
@@ -896,25 +896,35 @@ var __WEBPACK_AMD_DEFINE_RESULT__;
/* 11 */
/***/ (function(module, exports, __webpack_require__) {
-var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;!(__WEBPACK_AMD_DEFINE_ARRAY__ = [__webpack_require__(0),__webpack_require__(17)], __WEBPACK_AMD_DEFINE_RESULT__ = (function(o){function t(e,t,n){if(e.input)Array.isArray(e.input)?(o.prototype.isUndef(n)&&(n=0),this.connect(e.input[n])):this.connect(e.input,t,n);else try{e instanceof AudioNode?i.call(this,e,t,n):i.call(this,e,t)}catch(t){throw new Error("error connecting to node: "+e+"\n"+t)}}var i,r;return!window.hasOwnProperty("AudioContext")&&window.hasOwnProperty("webkitAudioContext")&&(window.AudioContext=window.webkitAudioContext),o.Context=function(t){for(var e in o.Emitter.call(this),t=t||new window.AudioContext,this._context=t,this._context)this._defineProperty(this._context,e);this._latencyHint="interactive",this._lookAhead=.1,this._updateInterval=this._lookAhead/3,this._computedUpdateInterval=0,this._worker=this._createWorker(),this._constants={}},o.extend(o.Context,o.Emitter),o.Emitter.mixin(o.Context),o.Context.prototype._defineProperty=function(e,n){this.isUndef(this[n])&&Object.defineProperty(this,n,{get:function(){return"function"==typeof e[n]?e[n].bind(e):e[n]},set:function(t){e[n]=t}})},o.Context.prototype.now=function(){return this._context.currentTime},o.Context.prototype._createWorker=function(){window.URL=window.URL||window.webkitURL;var t=new Blob(["var timeoutTime = "+(1e3*this._updateInterval).toFixed(1)+";self.onmessage = function(msg){\ttimeoutTime = parseInt(msg.data);};function tick(){\tsetTimeout(tick, timeoutTime);\tself.postMessage('tick');}tick();"]),e=URL.createObjectURL(t),n=new Worker(e);return n.addEventListener("message",function(){this.emit("tick")}.bind(this)),n.addEventListener("message",function(){var t=this.now();if(this.isNumber(this._lastUpdate)){var e=t-this._lastUpdate;this._computedUpdateInterval=Math.max(e,.97*this._computedUpdateInterval)}this._lastUpdate=t}.bind(this)),n},o.Context.prototype.getConstant=function(t){if(this._constants[t])return this._constants[t];for(var e=this._context.createBuffer(1,128,this._context.sampleRate),n=e.getChannelData(0),o=0;oe)this.cancelScheduledValues(e),this.linearRampToValueAtTime(t,e);else{var n=this._searchAfter(e);n&&(this.cancelScheduledValues(e),n.type===o.TimelineSignal.Type.Linear?this.linearRampToValueAtTime(t,e):n.type===o.TimelineSignal.Type.Exponential&&this.exponentialRampToValueAtTime(t,e)),this.setValueAtTime(t,e)}return this},o.TimelineSignal.prototype.linearRampToValueBetween=function(e,t,i){return this.setRampPoint(t),this.linearRampToValueAtTime(e,i),this},o.TimelineSignal.prototype.exponentialRampToValueBetween=function(e,t,i){return this.setRampPoint(t),this.exponentialRampToValueAtTime(e,i),this},o.TimelineSignal.prototype._searchBefore=function(e){return this._events.get(e)},o.TimelineSignal.prototype._searchAfter=function(e){return this._events.getAfter(e)},o.TimelineSignal.prototype.getValueAtTime=function(e){e=this.toSeconds(e);var t=this._searchAfter(e),i=this._searchBefore(e),n=this._initial;if(null===i)n=this._initial;else if(i.type===o.TimelineSignal.Type.Target){var a,l=this._events.getBefore(i.time);a=null===l?this._initial:l.value,n=this._exponentialApproach(i.time,a,i.value,i.constant,e)}else n=i.type===o.TimelineSignal.Type.Curve?this._curveInterpolate(i.time,i.value,i.duration,e):null===t?i.value:t.type===o.TimelineSignal.Type.Linear?this._linearInterpolate(i.time,i.value,t.time,t.value,e):t.type===o.TimelineSignal.Type.Exponential?this._exponentialInterpolate(i.time,i.value,t.time,t.value,e):i.value;return n},o.TimelineSignal.prototype.connect=o.SignalBase.prototype.connect,o.TimelineSignal.prototype._exponentialApproach=function(e,t,i,n,a){return i+(t-i)*Math.exp(-(a-e)/n)},o.TimelineSignal.prototype._linearInterpolate=function(e,t,i,n,a){return t+(a-e)/(i-e)*(n-t)},o.TimelineSignal.prototype._exponentialInterpolate=function(e,t,i,n,a){return(t=Math.max(this._minOutput,t))*Math.pow(n/t,(a-e)/(i-e))},o.TimelineSignal.prototype._curveInterpolate=function(e,t,i,n){var a=t.length;if(e+i<=n)return t[a-1];if(n<=e)return t[0];var l=(n-e)/i,s=Math.floor((a-1)*l),r=Math.ceil((a-1)*l),o=t[s],p=t[r];return r===s?o:this._linearInterpolate(s,o,r,p,l*(a-1))},o.TimelineSignal.prototype.dispose=function(){o.Signal.prototype.dispose.call(this),o.Param.prototype.dispose.call(this),this._events.dispose(),this._events=null},o.TimelineSignal}).apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__),
__WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));
/***/ }),
-/* 14 */
+/* 15 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
@@ -1237,14 +1247,14 @@ var __WEBPACK_AMD_DEFINE_RESULT__;
__WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));
/***/ }),
-/* 15 */
+/* 16 */
/***/ (function(module, exports, __webpack_require__) {
var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;!(__WEBPACK_AMD_DEFINE_ARRAY__ = [__webpack_require__(0),__webpack_require__(7),__webpack_require__(25),__webpack_require__(2),__webpack_require__(9)], __WEBPACK_AMD_DEFINE_RESULT__ = (function(n){"use strict";return n.Subtract=function(t){this.createInsOuts(2,0),this._sum=this.input[0]=this.output=new n.Gain,this._neg=new n.Negate,this._param=this.input[1]=new n.Signal(t),this._param.chain(this._neg,this._sum)},n.extend(n.Subtract,n.Signal),n.Subtract.prototype.dispose=function(){return n.prototype.dispose.call(this),this._neg.dispose(),this._neg=null,this._sum.disconnect(),this._sum=null,this._param.dispose(),this._param=null,this},n.Subtract}).apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__),
__WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));
/***/ }),
-/* 16 */
+/* 17 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
@@ -1359,22 +1369,12 @@ global.TONE_SILENCE_VERSION_LOGGING = true;
/* WEBPACK VAR INJECTION */}.call(this, __webpack_require__(34)))
/***/ }),
-/* 17 */
+/* 18 */
/***/ (function(module, exports, __webpack_require__) {
var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;!(__WEBPACK_AMD_DEFINE_ARRAY__ = [__webpack_require__(0)], __WEBPACK_AMD_DEFINE_RESULT__ = (function(o){"use strict";return o.Emitter=function(){this._events={}},o.extend(o.Emitter),o.Emitter.prototype.on=function(t,e){for(var i=t.split(/\W+/),r=0;rCreates a signal that oscillates between -1.0 and 1.0.
* By default, the oscillation takes the form of a sinusoidal
@@ -2030,7 +2030,7 @@ var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;!(__WEBPACK_AMD_
/* 27 */
/***/ (function(module, exports, __webpack_require__) {
-var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;!(__WEBPACK_AMD_DEFINE_ARRAY__ = [__webpack_require__(0),__webpack_require__(13),__webpack_require__(65),__webpack_require__(17),__webpack_require__(11)], __WEBPACK_AMD_DEFINE_RESULT__ = (function(o){"use strict";return o.Clock=function(){o.Emitter.call(this);var t=this.optionsObject(arguments,["callback","frequency"],o.Clock.defaults);this.callback=t.callback,this._nextTick=0,this._lastState=o.State.Stopped,this.frequency=new o.TimelineSignal(t.frequency,o.Type.Frequency),this._readOnly("frequency"),this.ticks=0,this._state=new o.TimelineState(o.State.Stopped),this._boundLoop=this._loop.bind(this),this.context.on("tick",this._boundLoop)},o.extend(o.Clock,o.Emitter),o.Clock.defaults={callback:o.noOp,frequency:1,lookAhead:"auto"},Object.defineProperty(o.Clock.prototype,"state",{get:function(){return this._state.getValueAtTime(this.now())}}),o.Clock.prototype.start=function(t,e){return t=this.toSeconds(t),this._state.getValueAtTime(t)!==o.State.Started&&this._state.add({state:o.State.Started,time:t,offset:e}),this},o.Clock.prototype.stop=function(t){return t=this.toSeconds(t),this._state.cancel(t),this._state.setStateAtTime(o.State.Stopped,t),this},o.Clock.prototype.pause=function(t){return t=this.toSeconds(t),this._state.getValueAtTime(t)===o.State.Started&&this._state.setStateAtTime(o.State.Paused,t),this},o.Clock.prototype._loop=function(){for(var t=this.now()+this.context.lookAhead+this.context.updateInterval+2*this.context.lag;t>this._nextTick&&this._state;){var e=this._state.getValueAtTime(this._nextTick);if(e!==this._lastState){this._lastState=e;var i=this._state.get(this._nextTick);e===o.State.Started?(this._nextTick=i.time,this.isUndef(i.offset)||(this.ticks=i.offset),this.emit("start",i.time,this.ticks)):e===o.State.Stopped?(this.ticks=0,this.emit("stop",i.time)):e===o.State.Paused&&this.emit("pause",i.time)}var s=this._nextTick;this.frequency&&(this._nextTick+=1/this.frequency.getValueAtTime(this._nextTick),e===o.State.Started&&(this.callback(s),this.ticks++))}},o.Clock.prototype.getStateAtTime=function(t){return t=this.toSeconds(t),this._state.getValueAtTime(t)},o.Clock.prototype.dispose=function(){o.Emitter.prototype.dispose.call(this),this.context.off("tick",this._boundLoop),this._writable("frequency"),this.frequency.dispose(),this.frequency=null,this._boundLoop=null,this._nextTick=1/0,this.callback=null,this._state.dispose(),this._state=null},o.Clock}).apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__),
+var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;!(__WEBPACK_AMD_DEFINE_ARRAY__ = [__webpack_require__(0),__webpack_require__(14),__webpack_require__(66),__webpack_require__(18),__webpack_require__(11)], __WEBPACK_AMD_DEFINE_RESULT__ = (function(o){"use strict";return o.Clock=function(){o.Emitter.call(this);var t=this.optionsObject(arguments,["callback","frequency"],o.Clock.defaults);this.callback=t.callback,this._nextTick=0,this._lastState=o.State.Stopped,this.frequency=new o.TimelineSignal(t.frequency,o.Type.Frequency),this._readOnly("frequency"),this.ticks=0,this._state=new o.TimelineState(o.State.Stopped),this._boundLoop=this._loop.bind(this),this.context.on("tick",this._boundLoop)},o.extend(o.Clock,o.Emitter),o.Clock.defaults={callback:o.noOp,frequency:1,lookAhead:"auto"},Object.defineProperty(o.Clock.prototype,"state",{get:function(){return this._state.getValueAtTime(this.now())}}),o.Clock.prototype.start=function(t,e){return t=this.toSeconds(t),this._state.getValueAtTime(t)!==o.State.Started&&this._state.add({state:o.State.Started,time:t,offset:e}),this},o.Clock.prototype.stop=function(t){return t=this.toSeconds(t),this._state.cancel(t),this._state.setStateAtTime(o.State.Stopped,t),this},o.Clock.prototype.pause=function(t){return t=this.toSeconds(t),this._state.getValueAtTime(t)===o.State.Started&&this._state.setStateAtTime(o.State.Paused,t),this},o.Clock.prototype._loop=function(){for(var t=this.now()+this.context.lookAhead+this.context.updateInterval+2*this.context.lag;t>this._nextTick&&this._state;){var e=this._state.getValueAtTime(this._nextTick);if(e!==this._lastState){this._lastState=e;var i=this._state.get(this._nextTick);e===o.State.Started?(this._nextTick=i.time,this.isUndef(i.offset)||(this.ticks=i.offset),this.emit("start",i.time,this.ticks)):e===o.State.Stopped?(this.ticks=0,this.emit("stop",i.time)):e===o.State.Paused&&this.emit("pause",i.time)}var s=this._nextTick;this.frequency&&(this._nextTick+=1/this.frequency.getValueAtTime(this._nextTick),e===o.State.Started&&(this.callback(s),this.ticks++))}},o.Clock.prototype.getStateAtTime=function(t){return t=this.toSeconds(t),this._state.getValueAtTime(t)},o.Clock.prototype.dispose=function(){o.Emitter.prototype.dispose.call(this),this.context.off("tick",this._boundLoop),this._writable("frequency"),this.frequency.dispose(),this.frequency=null,this._boundLoop=null,this._nextTick=1/0,this.callback=null,this._state.dispose(),this._state=null},o.Clock}).apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__),
__WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));
/***/ }),
@@ -2447,7 +2447,7 @@ var __WEBPACK_AMD_DEFINE_RESULT__;
!(__WEBPACK_AMD_DEFINE_RESULT__ = (function (require) {
var p5sound = __webpack_require__(1);
- var TimelineSignal = __webpack_require__(13);
+ var TimelineSignal = __webpack_require__(14);
var noteToFreq = __webpack_require__(6).noteToFreq;
/**
@@ -2905,7 +2905,7 @@ var __WEBPACK_AMD_DEFINE_RESULT__;
__webpack_require__(33);
- __webpack_require__(16);
+ __webpack_require__(17);
var p5SOUND = __webpack_require__(1);
@@ -2915,8 +2915,6 @@ var __WEBPACK_AMD_DEFINE_RESULT__;
__webpack_require__(36);
- __webpack_require__(39);
-
__webpack_require__(40);
__webpack_require__(41);
@@ -2925,9 +2923,9 @@ var __WEBPACK_AMD_DEFINE_RESULT__;
__webpack_require__(43);
- __webpack_require__(23);
+ __webpack_require__(44);
- __webpack_require__(46);
+ __webpack_require__(23);
__webpack_require__(47);
@@ -2935,11 +2933,11 @@ var __WEBPACK_AMD_DEFINE_RESULT__;
__webpack_require__(49);
- __webpack_require__(14);
+ __webpack_require__(50);
- __webpack_require__(58);
+ __webpack_require__(15);
- __webpack_require__(60);
+ __webpack_require__(59);
__webpack_require__(61);
@@ -2949,7 +2947,7 @@ var __WEBPACK_AMD_DEFINE_RESULT__;
__webpack_require__(64);
- __webpack_require__(66);
+ __webpack_require__(65);
__webpack_require__(67);
@@ -2961,11 +2959,13 @@ var __WEBPACK_AMD_DEFINE_RESULT__;
__webpack_require__(71);
+ __webpack_require__(72);
+
__webpack_require__(28);
__webpack_require__(30);
- __webpack_require__(72);
+ __webpack_require__(73);
__webpack_require__(29);
@@ -3424,7 +3424,7 @@ var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_
var p5sound = __webpack_require__(1);
-var moduleSources = [__webpack_require__(37)["default"], __webpack_require__(38)["default"], __webpack_require__(73)["default"]];
+var moduleSources = [__webpack_require__(37)["default"], __webpack_require__(38)["default"], __webpack_require__(39)["default"]];
var ac = p5sound.audiocontext;
function loadAudioWorkletModules() {
@@ -3467,10 +3467,18 @@ __webpack_require__.r(__webpack_exports__);
"use strict";
__webpack_require__.r(__webpack_exports__);
-/* harmony default export */ __webpack_exports__["default"] = ("function _typeof(obj) { if (typeof Symbol === \"function\" && typeof Symbol.iterator === \"symbol\") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === \"function\" && obj.constructor === Symbol && obj !== Symbol.prototype ? \"symbol\" : typeof obj; }; } return _typeof(obj); }\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\nfunction _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if (\"value\" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }\n\nfunction _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }\n\nfunction _possibleConstructorReturn(self, call) { if (call && (_typeof(call) === \"object\" || typeof call === \"function\")) { return call; } return _assertThisInitialized(self); }\n\nfunction _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError(\"this hasn't been initialised - super() hasn't been called\"); } return self; }\n\nfunction _inherits(subClass, superClass) { if (typeof superClass !== \"function\" && superClass !== null) { throw new TypeError(\"Super expression must either be null or a function\"); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, writable: true, configurable: true } }); if (superClass) _setPrototypeOf(subClass, superClass); }\n\nfunction _wrapNativeSuper(Class) { var _cache = typeof Map === \"function\" ? new Map() : undefined; _wrapNativeSuper = function _wrapNativeSuper(Class) { if (Class === null || !_isNativeFunction(Class)) return Class; if (typeof Class !== \"function\") { throw new TypeError(\"Super expression must either be null or a function\"); } if (typeof _cache !== \"undefined\") { if (_cache.has(Class)) return _cache.get(Class); _cache.set(Class, Wrapper); } function Wrapper() { return _construct(Class, arguments, _getPrototypeOf(this).constructor); } Wrapper.prototype = Object.create(Class.prototype, { constructor: { value: Wrapper, enumerable: false, writable: true, configurable: true } }); return _setPrototypeOf(Wrapper, Class); }; return _wrapNativeSuper(Class); }\n\nfunction isNativeReflectConstruct() { if (typeof Reflect === \"undefined\" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === \"function\") return true; try { Date.prototype.toString.call(Reflect.construct(Date, [], function () {})); return true; } catch (e) { return false; } }\n\nfunction _construct(Parent, args, Class) { if (isNativeReflectConstruct()) { _construct = Reflect.construct; } else { _construct = function _construct(Parent, args, Class) { var a = [null]; a.push.apply(a, args); var Constructor = Function.bind.apply(Parent, a); var instance = new Constructor(); if (Class) _setPrototypeOf(instance, Class.prototype); return instance; }; } return _construct.apply(null, arguments); }\n\nfunction _isNativeFunction(fn) { return Function.toString.call(fn).indexOf(\"[native code]\") !== -1; }\n\nfunction _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); }\n\nfunction _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); }; return _getPrototypeOf(o); }\n\n// import processor name via preval.require so that it's available as a value at compile time\nvar processorNames = {\n \"recorderProcessor\": \"recorder-processor\",\n \"soundFileProcessor\": \"sound-file-processor\",\n \"amplitudeProcessor\": \"amplitude-processor\"\n};\n\nvar SoundFileProcessor =\n/*#__PURE__*/\nfunction (_AudioWorkletProcesso) {\n _inherits(SoundFileProcessor, _AudioWorkletProcesso);\n\n function SoundFileProcessor() {\n _classCallCheck(this, SoundFileProcessor);\n\n return _possibleConstructorReturn(this, _getPrototypeOf(SoundFileProcessor).apply(this, arguments));\n }\n\n _createClass(SoundFileProcessor, [{\n key: \"process\",\n value: function process(inputs) {\n var input = inputs[0];\n var inputChannel = input[0];\n var position = inputChannel[inputChannel.length - 1] || 0;\n this.port.postMessage({\n name: 'position',\n position: position\n });\n return true;\n }\n }]);\n\n return SoundFileProcessor;\n}(_wrapNativeSuper(AudioWorkletProcessor));\n\nregisterProcessor(processorNames.soundFileProcessor, SoundFileProcessor);");
+/* harmony default export */ __webpack_exports__["default"] = ("function _typeof(obj) { if (typeof Symbol === \"function\" && typeof Symbol.iterator === \"symbol\") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === \"function\" && obj.constructor === Symbol && obj !== Symbol.prototype ? \"symbol\" : typeof obj; }; } return _typeof(obj); }\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\nfunction _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if (\"value\" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }\n\nfunction _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }\n\nfunction _possibleConstructorReturn(self, call) { if (call && (_typeof(call) === \"object\" || typeof call === \"function\")) { return call; } return _assertThisInitialized(self); }\n\nfunction _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError(\"this hasn't been initialised - super() hasn't been called\"); } return self; }\n\nfunction _inherits(subClass, superClass) { if (typeof superClass !== \"function\" && superClass !== null) { throw new TypeError(\"Super expression must either be null or a function\"); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, writable: true, configurable: true } }); if (superClass) _setPrototypeOf(subClass, superClass); }\n\nfunction _wrapNativeSuper(Class) { var _cache = typeof Map === \"function\" ? new Map() : undefined; _wrapNativeSuper = function _wrapNativeSuper(Class) { if (Class === null || !_isNativeFunction(Class)) return Class; if (typeof Class !== \"function\") { throw new TypeError(\"Super expression must either be null or a function\"); } if (typeof _cache !== \"undefined\") { if (_cache.has(Class)) return _cache.get(Class); _cache.set(Class, Wrapper); } function Wrapper() { return _construct(Class, arguments, _getPrototypeOf(this).constructor); } Wrapper.prototype = Object.create(Class.prototype, { constructor: { value: Wrapper, enumerable: false, writable: true, configurable: true } }); return _setPrototypeOf(Wrapper, Class); }; return _wrapNativeSuper(Class); }\n\nfunction isNativeReflectConstruct() { if (typeof Reflect === \"undefined\" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === \"function\") return true; try { Date.prototype.toString.call(Reflect.construct(Date, [], function () {})); return true; } catch (e) { return false; } }\n\nfunction _construct(Parent, args, Class) { if (isNativeReflectConstruct()) { _construct = Reflect.construct; } else { _construct = function _construct(Parent, args, Class) { var a = [null]; a.push.apply(a, args); var Constructor = Function.bind.apply(Parent, a); var instance = new Constructor(); if (Class) _setPrototypeOf(instance, Class.prototype); return instance; }; } return _construct.apply(null, arguments); }\n\nfunction _isNativeFunction(fn) { return Function.toString.call(fn).indexOf(\"[native code]\") !== -1; }\n\nfunction _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); }\n\nfunction _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); }; return _getPrototypeOf(o); }\n\n// import processor name via preval.require so that it's available as a value at compile time\nvar processorNames = {\n \"recorderProcessor\": \"recorder-processor\",\n \"soundFileProcessor\": \"sound-file-processor\",\n \"amplitudeProcessor\": \"amplitude-processor\"\n};\n\nvar SoundFileProcessor =\n/*#__PURE__*/\nfunction (_AudioWorkletProcesso) {\n _inherits(SoundFileProcessor, _AudioWorkletProcesso);\n\n function SoundFileProcessor() {\n var _this;\n\n _classCallCheck(this, SoundFileProcessor);\n\n _this = _possibleConstructorReturn(this, _getPrototypeOf(SoundFileProcessor).call(this));\n _this.paused = false;\n\n _this.port.onmessage = function (event) {\n var data = event.data;\n\n if (data.name === 'play') {\n _this.paused = false;\n } else if (data.name === 'pause') {\n _this.paused = true;\n }\n };\n\n return _this;\n }\n\n _createClass(SoundFileProcessor, [{\n key: \"process\",\n value: function process(inputs) {\n var input = inputs[0];\n var inputChannel = input[0];\n var position = inputChannel[inputChannel.length - 1];\n\n if (!this.paused) {\n this.port.postMessage({\n name: 'position',\n position: position\n });\n }\n\n return true;\n }\n }]);\n\n return SoundFileProcessor;\n}(_wrapNativeSuper(AudioWorkletProcessor));\n\nregisterProcessor(processorNames.soundFileProcessor, SoundFileProcessor);");
/***/ }),
/* 39 */
+/***/ (function(module, __webpack_exports__, __webpack_require__) {
+
+"use strict";
+__webpack_require__.r(__webpack_exports__);
+/* harmony default export */ __webpack_exports__["default"] = ("function _typeof(obj) { if (typeof Symbol === \"function\" && typeof Symbol.iterator === \"symbol\") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === \"function\" && obj.constructor === Symbol && obj !== Symbol.prototype ? \"symbol\" : typeof obj; }; } return _typeof(obj); }\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\nfunction _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if (\"value\" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }\n\nfunction _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }\n\nfunction _possibleConstructorReturn(self, call) { if (call && (_typeof(call) === \"object\" || typeof call === \"function\")) { return call; } return _assertThisInitialized(self); }\n\nfunction _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError(\"this hasn't been initialised - super() hasn't been called\"); } return self; }\n\nfunction _inherits(subClass, superClass) { if (typeof superClass !== \"function\" && superClass !== null) { throw new TypeError(\"Super expression must either be null or a function\"); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, writable: true, configurable: true } }); if (superClass) _setPrototypeOf(subClass, superClass); }\n\nfunction _wrapNativeSuper(Class) { var _cache = typeof Map === \"function\" ? new Map() : undefined; _wrapNativeSuper = function _wrapNativeSuper(Class) { if (Class === null || !_isNativeFunction(Class)) return Class; if (typeof Class !== \"function\") { throw new TypeError(\"Super expression must either be null or a function\"); } if (typeof _cache !== \"undefined\") { if (_cache.has(Class)) return _cache.get(Class); _cache.set(Class, Wrapper); } function Wrapper() { return _construct(Class, arguments, _getPrototypeOf(this).constructor); } Wrapper.prototype = Object.create(Class.prototype, { constructor: { value: Wrapper, enumerable: false, writable: true, configurable: true } }); return _setPrototypeOf(Wrapper, Class); }; return _wrapNativeSuper(Class); }\n\nfunction isNativeReflectConstruct() { if (typeof Reflect === \"undefined\" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === \"function\") return true; try { Date.prototype.toString.call(Reflect.construct(Date, [], function () {})); return true; } catch (e) { return false; } }\n\nfunction _construct(Parent, args, Class) { if (isNativeReflectConstruct()) { _construct = Reflect.construct; } else { _construct = function _construct(Parent, args, Class) { var a = [null]; a.push.apply(a, args); var Constructor = Function.bind.apply(Parent, a); var instance = new Constructor(); if (Class) _setPrototypeOf(instance, Class.prototype); return instance; }; } return _construct.apply(null, arguments); }\n\nfunction _isNativeFunction(fn) { return Function.toString.call(fn).indexOf(\"[native code]\") !== -1; }\n\nfunction _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); }\n\nfunction _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); }; return _getPrototypeOf(o); }\n\n// import processor name via preval.require so that it's available as a value at compile time\nvar processorNames = {\n \"recorderProcessor\": \"recorder-processor\",\n \"soundFileProcessor\": \"sound-file-processor\",\n \"amplitudeProcessor\": \"amplitude-processor\"\n};\n\nvar AmplitudeProcessor =\n/*#__PURE__*/\nfunction (_AudioWorkletProcesso) {\n _inherits(AmplitudeProcessor, _AudioWorkletProcesso);\n\n function AmplitudeProcessor(options) {\n var _this;\n\n _classCallCheck(this, AmplitudeProcessor);\n\n _this = _possibleConstructorReturn(this, _getPrototypeOf(AmplitudeProcessor).call(this));\n var processorOptions = options.processorOptions || {};\n _this.smoothing = processorOptions.smoothing || 0;\n _this.normalize = processorOptions.normalize || false;\n _this.stereoVol = [0, 0];\n _this.stereoVolNorm = [0, 0];\n _this.volMax = 0.001;\n\n _this.port.onmessage = function (event) {\n var data = event.data;\n\n if (data.name === 'toggleNormalize') {\n _this.normalize = data.normalize;\n } else if (data.name === 'smoothing') {\n _this.smoothing = Math.max(0, Math.min(1, data.smoothing));\n }\n };\n\n return _this;\n } // TO DO make this stereo / dependent on # of audio channels\n\n\n _createClass(AmplitudeProcessor, [{\n key: \"process\",\n value: function process(inputs, outputs) {\n var input = inputs[0];\n var output = outputs[0];\n var smoothing = this.smoothing;\n\n for (var channel = 0; channel < input.length; ++channel) {\n var inputBuffer = input[channel];\n var bufLength = inputBuffer.length;\n var sum = 0;\n\n for (var i = 0; i < bufLength; i++) {\n var x = inputBuffer[i];\n\n if (this.normalize) {\n sum += Math.max(Math.min(x / this.volMax, 1), -1) * Math.max(Math.min(x / this.volMax, 1), -1);\n } else {\n sum += x * x;\n }\n } // ... then take the square root of the sum.\n\n\n var rms = Math.sqrt(sum / bufLength);\n this.stereoVol[channel] = Math.max(rms, this.stereoVol[channel] * smoothing);\n this.volMax = Math.max(this.stereoVol[channel], this.volMax);\n } // calculate stero normalized volume and add volume from all channels together\n\n\n var volSum = 0;\n\n for (var index = 0; index < this.stereoVol.length; index++) {\n this.stereoVolNorm[index] = Math.max(Math.min(this.stereoVol[index] / this.volMax, 1), 0);\n volSum += this.stereoVol[index];\n } // volume is average of channels\n\n\n var volume = volSum / this.stereoVol.length; // normalized value\n\n var volNorm = Math.max(Math.min(volume / this.volMax, 1), 0);\n this.port.postMessage({\n name: 'amplitude',\n volume: volume,\n volNorm: volNorm,\n stereoVol: this.stereoVol,\n stereoVolNorm: this.stereoVolNorm\n }); // pass input through to output\n\n for (var _channel = 0; _channel < output.length; ++_channel) {\n output[_channel].set(input[_channel]);\n }\n\n return true;\n }\n }]);\n\n return AmplitudeProcessor;\n}(_wrapNativeSuper(AudioWorkletProcessor));\n\nregisterProcessor(processorNames.amplitudeProcessor, AmplitudeProcessor);");
+
+/***/ }),
+/* 40 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
@@ -3582,7 +3590,7 @@ function _typeof(obj) { if (typeof Symbol === "function" && typeof Symbol.iterat
__WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));
/***/ }),
-/* 40 */
+/* 41 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
@@ -3601,7 +3609,7 @@ function _typeof(obj) { if (typeof Symbol === "function" && typeof Symbol.iterat
var convertToWav = __webpack_require__(6).convertToWav;
- var processorNames = __webpack_require__(18);
+ var processorNames = __webpack_require__(12);
/**
*
SoundFile object with a path to a file.
*
@@ -3723,7 +3731,6 @@ function _typeof(obj) { if (typeof Symbol === "function" && typeof Symbol.iterat
this._whileLoading = function () {};
}
- this._onAudioProcess = _onAudioProcess.bind(this);
this._clearOnEnd = _clearOnEnd.bind(this);
}; // register preload handling of loadSound
@@ -3938,7 +3945,6 @@ function _typeof(obj) { if (typeof Symbol === "function" && typeof Symbol.iterat
return;
}
- var self = this;
var now = p5sound.audiocontext.currentTime;
var cueStart, cueEnd;
var time = startTime || 0;
@@ -4028,6 +4034,10 @@ function _typeof(obj) { if (typeof Symbol === "function" && typeof Symbol.iterat
this._counterNode.loopStart = cueStart;
this._counterNode.loopEnd = cueEnd;
}
+
+ this._workletNode.port.postMessage({
+ name: 'play'
+ });
};
/**
* p5.SoundFile has two play modes: restart and
@@ -4127,6 +4137,10 @@ function _typeof(obj) { if (typeof Symbol === "function" && typeof Symbol.iterat
var pTime = time + now;
if (this.isPlaying() && this.buffer && this.bufferSourceNode) {
+ this._workletNode.port.postMessage({
+ name: 'pause'
+ });
+
this.pauseTime = this.currentTime();
this.bufferSourceNode.stop(pTime);
@@ -5362,15 +5376,7 @@ function _typeof(obj) { if (typeof Symbol === "function" && typeof Symbol.iterat
return new Blob([dataView], {
type: 'audio/wav'
});
- }; // event handler to keep track of current position
-
-
- function _onAudioProcess(processEvent) {
- var inputBuffer = processEvent.inputBuffer.getChannelData(0);
- this._lastPos = inputBuffer[inputBuffer.length - 1] || 0; // do any callbacks that have been scheduled
-
- this._onTimeUpdate(self._lastPos);
- } // event handler to remove references to the bufferSourceNode when it is done playing
+ }; // event handler to remove references to the bufferSourceNode when it is done playing
function _clearOnEnd(e) {
@@ -5396,7 +5402,7 @@ function _typeof(obj) { if (typeof Symbol === "function" && typeof Symbol.iterat
__WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));
/***/ }),
-/* 41 */
+/* 42 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
@@ -5405,7 +5411,7 @@ var __WEBPACK_AMD_DEFINE_RESULT__;
!(__WEBPACK_AMD_DEFINE_RESULT__ = (function (require) {
var p5sound = __webpack_require__(1);
- var processorNames = __webpack_require__(18);
+ var processorNames = __webpack_require__(12);
/**
* Amplitude measures volume between 0.0 and 1.0.
* Listens to all p5sound by default, or use setInput()
@@ -5455,11 +5461,9 @@ var __WEBPACK_AMD_DEFINE_RESULT__;
this.audiocontext = p5sound.audiocontext;
this._workletNode = new AudioWorkletNode(this.audiocontext, processorNames.amplitudeProcessor, {
outputChannelCount: [1],
- parameterData: {
- smoothing: smoothing || 0
- },
processorOptions: {
- normalize: false
+ normalize: false,
+ smoothing: smoothing || 0
}
});
@@ -5658,7 +5662,10 @@ var __WEBPACK_AMD_DEFINE_RESULT__;
p5.Amplitude.prototype.smooth = function (s) {
if (s >= 0 && s < 1) {
- this._workletNode.parameters.get('smoothing').value = s;
+ this._workletNode.port.postMessage({
+ name: 'smoothing',
+ smoothing: s
+ });
} else {
console.log('Error: smoothing must be between 0 and 1');
}
@@ -5687,7 +5694,7 @@ var __WEBPACK_AMD_DEFINE_RESULT__;
__WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));
/***/ }),
-/* 42 */
+/* 43 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
@@ -6127,7 +6134,7 @@ var __WEBPACK_AMD_DEFINE_RESULT__;
* var rectangle_width = (log(i+1)-log(i))*(width/log(spectrum.length));
* rect(x, height, rectangle_width, -h )
* }
- * var nyquist = 22050;
+ * var nyquist = 22050;
*
* // get the centroid
* spectralCentroid = fft.getCentroid();
@@ -6337,7 +6344,7 @@ var __WEBPACK_AMD_DEFINE_RESULT__;
__WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));
/***/ }),
-/* 43 */
+/* 44 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
@@ -6352,7 +6359,7 @@ var __WEBPACK_AMD_DEFINE_RESULT__;
var Mult = __webpack_require__(3);
- var Scale = __webpack_require__(12);
+ var Scale = __webpack_require__(13);
/**
*
p5.Signal is a constant audio-rate signal used by p5.Oscillator
* and p5.Envelope for modulation math.
@@ -6514,21 +6521,21 @@ var __WEBPACK_AMD_DEFINE_RESULT__;
__WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));
/***/ }),
-/* 44 */
+/* 45 */
/***/ (function(module, exports, __webpack_require__) {
var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;!(__WEBPACK_AMD_DEFINE_ARRAY__ = [__webpack_require__(0),__webpack_require__(21)], __WEBPACK_AMD_DEFINE_RESULT__ = (function(o){o.Frequency=function(e,t){if(!(this instanceof o.Frequency))return new o.Frequency(e,t);o.TimeBase.call(this,e,t)},o.extend(o.Frequency,o.TimeBase),o.Frequency.prototype._primaryExpressions=Object.create(o.TimeBase.prototype._primaryExpressions),o.Frequency.prototype._primaryExpressions.midi={regexp:/^(\d+(?:\.\d+)?midi)/,method:function(e){return this.midiToFrequency(e)}},o.Frequency.prototype._primaryExpressions.note={regexp:/^([a-g]{1}(?:b|#|x|bb)?)(-?[0-9]+)/i,method:function(e,t){var r=n[e.toLowerCase()]+12*(parseInt(t)+1);return this.midiToFrequency(r)}},o.Frequency.prototype._primaryExpressions.tr={regexp:/^(\d+(?:\.\d+)?):(\d+(?:\.\d+)?):?(\d+(?:\.\d+)?)?/,method:function(e,t,r){var n=1;return e&&"0"!==e&&(n*=this._beatsToUnits(this._timeSignature()*parseFloat(e))),t&&"0"!==t&&(n*=this._beatsToUnits(parseFloat(t))),r&&"0"!==r&&(n*=this._beatsToUnits(parseFloat(r)/4)),n}},o.Frequency.prototype.transpose=function(e){return this._expr=function(e,t){return e()*this.intervalToFrequencyRatio(t)}.bind(this,this._expr,e),this},o.Frequency.prototype.harmonize=function(e){return this._expr=function(e,t){for(var r=e(),n=[],o=0;oEnvelopes are pre-defined amplitude distribution over time.
* Typically, envelopes are used to control the output volume
@@ -7426,7 +7433,7 @@ var __WEBPACK_AMD_DEFINE_RESULT__;
__WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));
/***/ }),
-/* 47 */
+/* 48 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
@@ -7628,7 +7635,7 @@ var __WEBPACK_AMD_DEFINE_RESULT__;
__WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));
/***/ }),
-/* 48 */
+/* 49 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
@@ -7810,7 +7817,7 @@ var __WEBPACK_AMD_DEFINE_RESULT__;
__WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));
/***/ }),
-/* 49 */
+/* 50 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
@@ -8174,63 +8181,63 @@ var __WEBPACK_AMD_DEFINE_RESULT__;
__WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));
/***/ }),
-/* 50 */
+/* 51 */
/***/ (function(module, exports, __webpack_require__) {
-var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;!(__WEBPACK_AMD_DEFINE_ARRAY__ = [__webpack_require__(0),__webpack_require__(2),__webpack_require__(51),__webpack_require__(57),__webpack_require__(9)], __WEBPACK_AMD_DEFINE_RESULT__ = (function(i){"use strict";return i.CrossFade=function(e){this.createInsOuts(2,1),this.a=this.input[0]=new i.Gain,this.b=this.input[1]=new i.Gain,this.fade=new i.Signal(this.defaultArg(e,.5),i.Type.NormalRange),this._equalPowerA=new i.EqualPowerGain,this._equalPowerB=new i.EqualPowerGain,this._invert=new i.Expr("1 - $0"),this.a.connect(this.output),this.b.connect(this.output),this.fade.chain(this._equalPowerB,this.b.gain),this.fade.chain(this._invert,this._equalPowerA,this.a.gain),this._readOnly("fade")},i.extend(i.CrossFade),i.CrossFade.prototype.dispose=function(){return i.prototype.dispose.call(this),this._writable("fade"),this._equalPowerA.dispose(),this._equalPowerA=null,this._equalPowerB.dispose(),this._equalPowerB=null,this.fade.dispose(),this.fade=null,this._invert.dispose(),this._invert=null,this.a.dispose(),this.a=null,this.b.dispose(),this.b=null,this},i.CrossFade}).apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__),
+var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;!(__WEBPACK_AMD_DEFINE_ARRAY__ = [__webpack_require__(0),__webpack_require__(2),__webpack_require__(52),__webpack_require__(58),__webpack_require__(9)], __WEBPACK_AMD_DEFINE_RESULT__ = (function(i){"use strict";return i.CrossFade=function(e){this.createInsOuts(2,1),this.a=this.input[0]=new i.Gain,this.b=this.input[1]=new i.Gain,this.fade=new i.Signal(this.defaultArg(e,.5),i.Type.NormalRange),this._equalPowerA=new i.EqualPowerGain,this._equalPowerB=new i.EqualPowerGain,this._invert=new i.Expr("1 - $0"),this.a.connect(this.output),this.b.connect(this.output),this.fade.chain(this._equalPowerB,this.b.gain),this.fade.chain(this._invert,this._equalPowerA,this.a.gain),this._readOnly("fade")},i.extend(i.CrossFade),i.CrossFade.prototype.dispose=function(){return i.prototype.dispose.call(this),this._writable("fade"),this._equalPowerA.dispose(),this._equalPowerA=null,this._equalPowerB.dispose(),this._equalPowerB=null,this.fade.dispose(),this.fade=null,this._invert.dispose(),this._invert=null,this.a.dispose(),this.a=null,this.b.dispose(),this.b=null,this},i.CrossFade}).apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__),
__WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));
/***/ }),
-/* 51 */
+/* 52 */
/***/ (function(module, exports, __webpack_require__) {
-var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;!(__WEBPACK_AMD_DEFINE_ARRAY__ = [__webpack_require__(0),__webpack_require__(7),__webpack_require__(15),__webpack_require__(3),__webpack_require__(52),__webpack_require__(26),__webpack_require__(53),__webpack_require__(25),__webpack_require__(54),__webpack_require__(55),__webpack_require__(56)], __WEBPACK_AMD_DEFINE_RESULT__ = (function(p){"use strict";function r(e,n,r){var t=new e;return r._eval(n[0]).connect(t,0,0),r._eval(n[1]).connect(t,0,1),t}function t(e,n,r){var t=new e;return r._eval(n[0]).connect(t,0,0),t}function o(e){return e?parseFloat(e):void 0}function i(e){return e&&e.args?parseFloat(e.args):void 0}return p.Expr=function(){var n=this._replacements(Array.prototype.slice.call(arguments)),e=this._parseInputs(n);this._nodes=[],this.input=new Array(e);for(var r=0;r 1){\n\t\t\tthis.input = new Array(inputs);\n\t\t}\n\n\t\t/**\n\t\t * the output node(s)\n\t\t * @type {GainNode|Array}\n\t\t */\n\t\tif (this.isUndef(outputs) || outputs === 1){\n\t\t\tthis.output = this.context.createGain();\n\t\t} else if (outputs > 1){\n\t\t\tthis.output = new Array(inputs);\n\t\t}\n\t};\n\n\t/**\n\t * Set the parameters at once. Either pass in an\n\t * object mapping parameters to values, or to set a\n\t * single parameter, by passing in a string and value.\n\t * The last argument is an optional ramp time which \n\t * will ramp any signal values to their destination value\n\t * over the duration of the rampTime.\n\t * @param {Object|string} params\n\t * @param {number=} value\n\t * @param {Time=} rampTime\n\t * @returns {Tone} this\n\t * @example\n\t * //set values using an object\n\t * filter.set({\n\t * \t\"frequency\" : 300,\n\t * \t\"type\" : highpass\n\t * });\n\t * @example\n\t * filter.set(\"type\", \"highpass\");\n\t * @example\n\t * //ramp to the value 220 over 3 seconds. \n\t * oscillator.set({\n\t * \t\"frequency\" : 220\n\t * }, 3);\n\t */\n\tTone.prototype.set = function(params, value, rampTime){\n\t\tif (this.isObject(params)){\n\t\t\trampTime = value;\n\t\t} else if (this.isString(params)){\n\t\t\tvar tmpObj = {};\n\t\t\ttmpObj[params] = value;\n\t\t\tparams = tmpObj;\n\t\t}\n\n\t\tparamLoop:\n\t\tfor (var attr in params){\n\t\t\tvalue = params[attr];\n\t\t\tvar parent = this;\n\t\t\tif (attr.indexOf(\".\") !== -1){\n\t\t\t\tvar attrSplit = attr.split(\".\");\n\t\t\t\tfor (var i = 0; i < attrSplit.length - 1; i++){\n\t\t\t\t\tparent = parent[attrSplit[i]];\n\t\t\t\t\tif (parent instanceof Tone) {\n\t\t\t\t\t\tattrSplit.splice(0,i+1);\n\t\t\t\t\t\tvar innerParam = attrSplit.join(\".\");\n\t\t\t\t\t\tparent.set(innerParam, value);\n\t\t\t\t\t\tcontinue paramLoop;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tattr = attrSplit[attrSplit.length - 1];\n\t\t\t}\n\t\t\tvar param = parent[attr];\n\t\t\tif (this.isUndef(param)){\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tif ((Tone.Signal && param instanceof Tone.Signal) || \n\t\t\t\t\t(Tone.Param && param instanceof Tone.Param)){\n\t\t\t\tif (param.value !== value){\n\t\t\t\t\tif (this.isUndef(rampTime)){\n\t\t\t\t\t\tparam.value = value;\n\t\t\t\t\t} else {\n\t\t\t\t\t\tparam.rampTo(value, rampTime);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} else if (param instanceof AudioParam){\n\t\t\t\tif (param.value !== value){\n\t\t\t\t\tparam.value = value;\n\t\t\t\t}\t\t\t\t\n\t\t\t} else if (param instanceof Tone){\n\t\t\t\tparam.set(value);\n\t\t\t} else if (param !== value){\n\t\t\t\tparent[attr] = value;\n\t\t\t}\n\t\t}\n\t\treturn this;\n\t};\n\n\t/**\n\t * Get the object's attributes. Given no arguments get\n\t * will return all available object properties and their corresponding\n\t * values. Pass in a single attribute to retrieve or an array\n\t * of attributes. The attribute strings can also include a \".\"\n\t * to access deeper properties.\n\t * @example\n\t * osc.get();\n\t * //returns {\"type\" : \"sine\", \"frequency\" : 440, ...etc}\n\t * @example\n\t * osc.get(\"type\");\n\t * //returns { \"type\" : \"sine\"}\n\t * @example\n\t * //use dot notation to access deep properties\n\t * synth.get([\"envelope.attack\", \"envelope.release\"]);\n\t * //returns {\"envelope\" : {\"attack\" : 0.2, \"release\" : 0.4}}\n\t * @param {Array=|string|undefined} params the parameters to get, otherwise will return \n\t * \t\t\t\t\t all available.\n\t * @returns {Object}\n\t */\n\tTone.prototype.get = function(params){\n\t\tif (this.isUndef(params)){\n\t\t\tparams = this._collectDefaults(this.constructor);\n\t\t} else if (this.isString(params)){\n\t\t\tparams = [params];\n\t\t} \n\t\tvar ret = {};\n\t\tfor (var i = 0; i < params.length; i++){\n\t\t\tvar attr = params[i];\n\t\t\tvar parent = this;\n\t\t\tvar subRet = ret;\n\t\t\tif (attr.indexOf(\".\") !== -1){\n\t\t\t\tvar attrSplit = attr.split(\".\");\n\t\t\t\tfor (var j = 0; j < attrSplit.length - 1; j++){\n\t\t\t\t\tvar subAttr = attrSplit[j];\n\t\t\t\t\tsubRet[subAttr] = subRet[subAttr] || {};\n\t\t\t\t\tsubRet = subRet[subAttr];\n\t\t\t\t\tparent = parent[subAttr];\n\t\t\t\t}\n\t\t\t\tattr = attrSplit[attrSplit.length - 1];\n\t\t\t}\n\t\t\tvar param = parent[attr];\n\t\t\tif (this.isObject(params[attr])){\n\t\t\t\tsubRet[attr] = param.get();\n\t\t\t} else if (Tone.Signal && param instanceof Tone.Signal){\n\t\t\t\tsubRet[attr] = param.value;\n\t\t\t} else if (Tone.Param && param instanceof Tone.Param){\n\t\t\t\tsubRet[attr] = param.value;\n\t\t\t} else if (param instanceof AudioParam){\n\t\t\t\tsubRet[attr] = param.value;\n\t\t\t} else if (param instanceof Tone){\n\t\t\t\tsubRet[attr] = param.get();\n\t\t\t} else if (!this.isFunction(param) && !this.isUndef(param)){\n\t\t\t\tsubRet[attr] = param;\n\t\t\t} \n\t\t}\n\t\treturn ret;\n\t};\n\n\t/**\n\t * collect all of the default attributes in one\n\t * @private\n\t * @param {function} constr the constructor to find the defaults from\n\t * @return {Array} all of the attributes which belong to the class\n\t */\n\tTone.prototype._collectDefaults = function(constr){\n\t\tvar ret = [];\n\t\tif (!this.isUndef(constr.defaults)){\n\t\t\tret = Object.keys(constr.defaults);\n\t\t}\n\t\tif (!this.isUndef(constr._super)){\n\t\t\tvar superDefs = this._collectDefaults(constr._super);\n\t\t\t//filter out repeats\n\t\t\tfor (var i = 0; i < superDefs.length; i++){\n\t\t\t\tif (ret.indexOf(superDefs[i]) === -1){\n\t\t\t\t\tret.push(superDefs[i]);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\treturn ret;\n\t};\n\n\t/**\n\t * @returns {string} returns the name of the class as a string\n\t */\n\tTone.prototype.toString = function(){\n\t\tfor (var className in Tone){\n\t\t\tvar isLetter = className[0].match(/^[A-Z]$/);\n\t\t\tvar sameConstructor = Tone[className] === this.constructor;\n\t\t\tif (this.isFunction(Tone[className]) && isLetter && sameConstructor){\n\t\t\t\treturn className;\n\t\t\t}\n\t\t}\n\t\treturn \"Tone\";\n\t};\n\n\t///////////////////////////////////////////////////////////////////////////\n\t//\tCLASS VARS\n\t///////////////////////////////////////////////////////////////////////////\n\n\t/**\n\t * The number of inputs feeding into the AudioNode. \n\t * For source nodes, this will be 0.\n\t * @memberOf Tone#\n\t * @name numberOfInputs\n\t * @readOnly\n\t */\n\tObject.defineProperty(Tone.prototype, \"numberOfInputs\", {\n\t\tget : function(){\n\t\t\tif (this.input){\n\t\t\t\tif (this.isArray(this.input)){\n\t\t\t\t\treturn this.input.length;\n\t\t\t\t} else {\n\t\t\t\t\treturn 1;\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\treturn 0;\n\t\t\t}\n\t\t}\n\t});\n\n\t/**\n\t * The number of outputs coming out of the AudioNode. \n\t * For source nodes, this will be 0.\n\t * @memberOf Tone#\n\t * @name numberOfInputs\n\t * @readOnly\n\t */\n\tObject.defineProperty(Tone.prototype, \"numberOfOutputs\", {\n\t\tget : function(){\n\t\t\tif (this.output){\n\t\t\t\tif (this.isArray(this.output)){\n\t\t\t\t\treturn this.output.length;\n\t\t\t\t} else {\n\t\t\t\t\treturn 1;\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\treturn 0;\n\t\t\t}\n\t\t}\n\t});\n\t\n\t///////////////////////////////////////////////////////////////////////////\n\t//\tCONNECTIONS\n\t///////////////////////////////////////////////////////////////////////////\n\n\t/**\n\t * disconnect and dispose\n\t * @returns {Tone} this\n\t */\n\tTone.prototype.dispose = function(){\n\t\tif (!this.isUndef(this.input)){\n\t\t\tif (this.input instanceof AudioNode){\n\t\t\t\tthis.input.disconnect();\n\t\t\t} \n\t\t\tthis.input = null;\n\t\t}\n\t\tif (!this.isUndef(this.output)){\n\t\t\tif (this.output instanceof AudioNode){\n\t\t\t\tthis.output.disconnect();\n\t\t\t} \n\t\t\tthis.output = null;\n\t\t}\n\t\treturn this;\n\t};\n\n\t/**\n\t * connect the output of a ToneNode to an AudioParam, AudioNode, or ToneNode\n\t * @param {Tone | AudioParam | AudioNode} unit \n\t * @param {number} [outputNum=0] optionally which output to connect from\n\t * @param {number} [inputNum=0] optionally which input to connect to\n\t * @returns {Tone} this\n\t */\n\tTone.prototype.connect = function(unit, outputNum, inputNum){\n\t\tif (Array.isArray(this.output)){\n\t\t\toutputNum = this.defaultArg(outputNum, 0);\n\t\t\tthis.output[outputNum].connect(unit, 0, inputNum);\n\t\t} else {\n\t\t\tthis.output.connect(unit, outputNum, inputNum);\n\t\t}\n\t\treturn this;\n\t};\n\n\t/**\n\t * disconnect the output\n\t * @param {Number|AudioNode} output Either the output index to disconnect\n\t * if the output is an array, or the\n\t * node to disconnect from.\n\t * @returns {Tone} this\n\t */\n\tTone.prototype.disconnect = function(destination, outputNum, inputNum){\n\t\tif (this.isArray(this.output)){\n\t\t\tif (this.isNumber(destination)){\n\t\t\t\tthis.output[destination].disconnect();\n\t\t\t} else {\n\t\t\t\toutputNum = this.defaultArg(outputNum, 0);\n\t\t\t\tthis.output[outputNum].disconnect(destination, 0, inputNum);\n\t\t\t}\n\t\t} else {\n\t\t\tthis.output.disconnect.apply(this.output, arguments);\n\t\t}\n\t};\n\n\t/**\n\t * connect together all of the arguments in series\n\t * @param {...AudioParam|Tone|AudioNode} nodes\n\t * @returns {Tone} this\n\t */\n\tTone.prototype.connectSeries = function(){\n\t\tif (arguments.length > 1){\n\t\t\tvar currentUnit = arguments[0];\n\t\t\tfor (var i = 1; i < arguments.length; i++){\n\t\t\t\tvar toUnit = arguments[i];\n\t\t\t\tcurrentUnit.connect(toUnit);\n\t\t\t\tcurrentUnit = toUnit;\n\t\t\t}\n\t\t}\n\t\treturn this;\n\t};\n\n\t/**\n\t * Connect the output of this node to the rest of the nodes in series.\n\t * @example\n\t * //connect a node to an effect, panVol and then to the master output\n\t * node.chain(effect, panVol, Tone.Master);\n\t * @param {...AudioParam|Tone|AudioNode} nodes\n\t * @returns {Tone} this\n\t */\n\tTone.prototype.chain = function(){\n\t\tif (arguments.length > 0){\n\t\t\tvar currentUnit = this;\n\t\t\tfor (var i = 0; i < arguments.length; i++){\n\t\t\t\tvar toUnit = arguments[i];\n\t\t\t\tcurrentUnit.connect(toUnit);\n\t\t\t\tcurrentUnit = toUnit;\n\t\t\t}\n\t\t}\n\t\treturn this;\n\t};\n\n\t/**\n\t * connect the output of this node to the rest of the nodes in parallel.\n\t * @param {...AudioParam|Tone|AudioNode} nodes\n\t * @returns {Tone} this\n\t */\n\tTone.prototype.fan = function(){\n\t\tif (arguments.length > 0){\n\t\t\tfor (var i = 0; i < arguments.length; i++){\n\t\t\t\tthis.connect(arguments[i]);\n\t\t\t}\n\t\t}\n\t\treturn this;\n\t};\n\n\t//give native nodes chain and fan methods\n\tAudioNode.prototype.chain = Tone.prototype.chain;\n\tAudioNode.prototype.fan = Tone.prototype.fan;\n\n\t///////////////////////////////////////////////////////////////////////////\n\t//\tUTILITIES / HELPERS / MATHS\n\t///////////////////////////////////////////////////////////////////////////\n\n\t/**\n\t * If the `given` parameter is undefined, use the `fallback`. \n\t * If both `given` and `fallback` are object literals, it will\n\t * return a deep copy which includes all of the parameters from both \n\t * objects. If a parameter is undefined in given, it will return\n\t * the fallback property. \n\t *
\n\t * WARNING: if object is self referential, it will go into an an \n\t * infinite recursive loop.\n\t * \n\t * @param {*} given \n\t * @param {*} fallback \n\t * @return {*} \n\t */\n\tTone.prototype.defaultArg = function(given, fallback){\n\t\tif (this.isObject(given) && this.isObject(fallback)){\n\t\t\tvar ret = {};\n\t\t\t//make a deep copy of the given object\n\t\t\tfor (var givenProp in given) {\n\t\t\t\tret[givenProp] = this.defaultArg(fallback[givenProp], given[givenProp]);\n\t\t\t}\n\t\t\tfor (var fallbackProp in fallback) {\n\t\t\t\tret[fallbackProp] = this.defaultArg(given[fallbackProp], fallback[fallbackProp]);\n\t\t\t}\n\t\t\treturn ret;\n\t\t} else {\n\t\t\treturn this.isUndef(given) ? fallback : given;\n\t\t}\n\t};\n\n\t/**\n\t * returns the args as an options object with given arguments\n\t * mapped to the names provided. \n\t *\n\t * if the args given is an array containing only one object, it is assumed\n\t * that that's already the options object and will just return it. \n\t * \n\t * @param {Array} values the 'arguments' object of the function\n\t * @param {Array} keys the names of the arguments as they\n\t * should appear in the options object\n\t * @param {Object=} defaults optional defaults to mixin to the returned \n\t * options object \n\t * @return {Object} the options object with the names mapped to the arguments\n\t */\n\tTone.prototype.optionsObject = function(values, keys, defaults){\n\t\tvar options = {};\n\t\tif (values.length === 1 && this.isObject(values[0])){\n\t\t\toptions = values[0];\n\t\t} else {\n\t\t\tfor (var i = 0; i < keys.length; i++){\n\t\t\t\toptions[keys[i]] = values[i];\n\t\t\t}\n\t\t}\n\t\tif (!this.isUndef(defaults)){\n\t\t\treturn this.defaultArg(options, defaults);\n\t\t} else {\n\t\t\treturn options;\n\t\t}\n\t};\n\n\t///////////////////////////////////////////////////////////////////////////\n\t// TYPE CHECKING\n\t///////////////////////////////////////////////////////////////////////////\n\n\t/**\n\t * test if the arg is undefined\n\t * @param {*} arg the argument to test\n\t * @returns {boolean} true if the arg is undefined\n\t * @function\n\t */\n\tTone.prototype.isUndef = function(val){\n\t\treturn typeof val === \"undefined\";\n\t};\n\n\t/**\n\t * test if the arg is a function\n\t * @param {*} arg the argument to test\n\t * @returns {boolean} true if the arg is a function\n\t * @function\n\t */\n\tTone.prototype.isFunction = function(val){\n\t\treturn typeof val === \"function\";\n\t};\n\n\t/**\n\t * Test if the argument is a number.\n\t * @param {*} arg the argument to test\n\t * @returns {boolean} true if the arg is a number\n\t */\n\tTone.prototype.isNumber = function(arg){\n\t\treturn (typeof arg === \"number\");\n\t};\n\n\t/**\n\t * Test if the given argument is an object literal (i.e. `{}`);\n\t * @param {*} arg the argument to test\n\t * @returns {boolean} true if the arg is an object literal.\n\t */\n\tTone.prototype.isObject = function(arg){\n\t\treturn (Object.prototype.toString.call(arg) === \"[object Object]\" && arg.constructor === Object);\n\t};\n\n\t/**\n\t * Test if the argument is a boolean.\n\t * @param {*} arg the argument to test\n\t * @returns {boolean} true if the arg is a boolean\n\t */\n\tTone.prototype.isBoolean = function(arg){\n\t\treturn (typeof arg === \"boolean\");\n\t};\n\n\t/**\n\t * Test if the argument is an Array\n\t * @param {*} arg the argument to test\n\t * @returns {boolean} true if the arg is an array\n\t */\n\tTone.prototype.isArray = function(arg){\n\t\treturn (Array.isArray(arg));\n\t};\n\n\t/**\n\t * Test if the argument is a string.\n\t * @param {*} arg the argument to test\n\t * @returns {boolean} true if the arg is a string\n\t */\n\tTone.prototype.isString = function(arg){\n\t\treturn (typeof arg === \"string\");\n\t};\n\n \t/**\n\t * An empty function.\n\t * @static\n\t */\n\tTone.noOp = function(){};\n\n\t/**\n\t * Make the property not writable. Internal use only. \n\t * @private\n\t * @param {string} property the property to make not writable\n\t */\n\tTone.prototype._readOnly = function(property){\n\t\tif (Array.isArray(property)){\n\t\t\tfor (var i = 0; i < property.length; i++){\n\t\t\t\tthis._readOnly(property[i]);\n\t\t\t}\n\t\t} else {\n\t\t\tObject.defineProperty(this, property, { \n\t\t\t\twritable: false,\n\t\t\t\tenumerable : true,\n\t\t\t});\n\t\t}\n\t};\n\n\t/**\n\t * Make an attribute writeable. Interal use only. \n\t * @private\n\t * @param {string} property the property to make writable\n\t */\n\tTone.prototype._writable = function(property){\n\t\tif (Array.isArray(property)){\n\t\t\tfor (var i = 0; i < property.length; i++){\n\t\t\t\tthis._writable(property[i]);\n\t\t\t}\n\t\t} else {\n\t\t\tObject.defineProperty(this, property, { \n\t\t\t\twritable: true,\n\t\t\t});\n\t\t}\n\t};\n\n\t/**\n\t * Possible play states. \n\t * @enum {string}\n\t */\n\tTone.State = {\n\t\tStarted : \"started\",\n\t\tStopped : \"stopped\",\n\t\tPaused : \"paused\",\n \t};\n\n\t///////////////////////////////////////////////////////////////////////////\n\t// CONVERSIONS\n\t///////////////////////////////////////////////////////////////////////////\n\n\t/**\n\t * Equal power gain scale. Good for cross-fading.\n\t * @param {NormalRange} percent (0-1)\n\t * @return {Number} output gain (0-1)\n\t */\n\tTone.prototype.equalPowerScale = function(percent){\n\t\tvar piFactor = 0.5 * Math.PI;\n\t\treturn Math.sin(percent * piFactor);\n\t};\n\n\t/**\n\t * Convert decibels into gain.\n\t * @param {Decibels} db\n\t * @return {Number} \n\t */\n\tTone.prototype.dbToGain = function(db) {\n\t\treturn Math.pow(2, db / 6);\n\t};\n\n\t/**\n\t * Convert gain to decibels.\n\t * @param {Number} gain (0-1)\n\t * @return {Decibels} \n\t */\n\tTone.prototype.gainToDb = function(gain) {\n\t\treturn 20 * (Math.log(gain) / Math.LN10);\n\t};\n\n\t/**\n\t * Convert an interval (in semitones) to a frequency ratio.\n\t * @param {Interval} interval the number of semitones above the base note\n\t * @return {number} the frequency ratio\n\t * @example\n\t * tone.intervalToFrequencyRatio(0); // 1\n\t * tone.intervalToFrequencyRatio(12); // 2\n\t * tone.intervalToFrequencyRatio(-12); // 0.5\n\t */\n\tTone.prototype.intervalToFrequencyRatio = function(interval){\n\t\treturn Math.pow(2,(interval/12));\n\t};\n\n\t///////////////////////////////////////////////////////////////////////////\n\t//\tTIMING\n\t///////////////////////////////////////////////////////////////////////////\n\n\t/**\n\t * Return the current time of the AudioContext clock.\n\t * @return {Number} the currentTime from the AudioContext\n\t */\n\tTone.prototype.now = function(){\n\t\treturn Tone.context.now();\n\t};\n\n\t/**\n\t * Return the current time of the AudioContext clock.\n\t * @return {Number} the currentTime from the AudioContext\n\t * @static\n\t */\n\tTone.now = function(){\n\t\treturn Tone.context.now();\n\t};\n\n\t///////////////////////////////////////////////////////////////////////////\n\t//\tINHERITANCE\n\t///////////////////////////////////////////////////////////////////////////\n\n\t/**\n\t * have a child inherit all of Tone's (or a parent's) prototype\n\t * to inherit the parent's properties, make sure to call \n\t * Parent.call(this) in the child's constructor\n\t *\n\t * based on closure library's inherit function\n\t *\n\t * @static\n\t * @param {function} \tchild \n\t * @param {function=} parent (optional) parent to inherit from\n\t * if no parent is supplied, the child\n\t * will inherit from Tone\n\t */\n\tTone.extend = function(child, parent){\n\t\tif (Tone.prototype.isUndef(parent)){\n\t\t\tparent = Tone;\n\t\t}\n\t\tfunction TempConstructor(){}\n\t\tTempConstructor.prototype = parent.prototype;\n\t\tchild.prototype = new TempConstructor();\n\t\t/** @override */\n\t\tchild.prototype.constructor = child;\n\t\tchild._super = parent;\n\t};\n\n\t///////////////////////////////////////////////////////////////////////////\n\t//\tCONTEXT\n\t///////////////////////////////////////////////////////////////////////////\n\n\t/**\n\t * The private audio context shared by all Tone Nodes. \n\t * @private\n\t * @type {Tone.Context|undefined}\n\t */\n\tvar audioContext;\n\n\t/**\n\t * A static pointer to the audio context accessible as Tone.context. \n\t * @type {Tone.Context}\n\t * @name context\n\t * @memberOf Tone\n\t */\n\tObject.defineProperty(Tone, \"context\", {\n\t\tget : function(){\n\t\t\treturn audioContext;\n\t\t},\n\t\tset : function(context){\n\t\t\tif (Tone.Context && context instanceof Tone.Context){\n\t\t\t\taudioContext = context;\n\t\t\t} else {\n\t\t\t\taudioContext = new Tone.Context(context);\n\t\t\t}\n\t\t\t//initialize the new audio context\n\t\t\tif (Tone.Context){\n\t\t\t\tTone.Context.emit(\"init\", audioContext);\n\t\t\t}\n\t\t}\n\t});\n\n\t/**\n\t * The AudioContext\n\t * @type {Tone.Context}\n\t * @name context\n\t * @memberOf Tone#\n\t * @readOnly\n\t */\n\tObject.defineProperty(Tone.prototype, \"context\", {\n\t\tget : function(){\n\t\t\treturn Tone.context;\n\t\t}\n\t});\n\n\t/**\n\t * Tone automatically creates a context on init, but if you are working\n\t * with other libraries which also create an AudioContext, it can be\n\t * useful to set your own. If you are going to set your own context, \n\t * be sure to do it at the start of your code, before creating any objects.\n\t * @static\n\t * @param {AudioContext} ctx The new audio context to set\n\t */\n\tTone.setContext = function(ctx){\n\t\tTone.context = ctx;\n\t};\n\n\t/**\n\t * The number of seconds of 1 processing block (128 samples)\n\t * @type {Number}\n\t * @name blockTime\n\t * @memberOf Tone#\n\t * @readOnly\n\t */\n\tObject.defineProperty(Tone.prototype, \"blockTime\", {\n\t\tget : function(){\n\t\t\treturn 128 / this.context.sampleRate;\n\t\t}\n\t});\n\n\t/**\n\t * The duration in seconds of one sample.\n\t * @type {Number}\n\t * @name sampleTime\n\t * @memberOf Tone#\n\t * @readOnly\n\t */\n\tObject.defineProperty(Tone.prototype, \"sampleTime\", {\n\t\tget : function(){\n\t\t\treturn 1 / this.context.sampleRate;\n\t\t}\n\t});\n\n\t/**\n\t * Whether or not all the technologies that Tone.js relies on are supported by the current browser. \n\t * @type {Boolean}\n\t * @name supported\n\t * @memberOf Tone\n\t * @readOnly\n\t */\n\tObject.defineProperty(Tone, \"supported\", {\n\t\tget : function(){\n\t\t\tvar hasAudioContext = window.hasOwnProperty(\"AudioContext\") || window.hasOwnProperty(\"webkitAudioContext\");\n\t\t\tvar hasPromises = window.hasOwnProperty(\"Promise\");\n\t\t\tvar hasWorkers = window.hasOwnProperty(\"Worker\");\n\t\t\treturn hasAudioContext && hasPromises && hasWorkers;\n\t\t}\n\t});\n\n\tTone.version = \"r10\";\n\n\t// allow optional silencing of this log\n\tif (!window.TONE_SILENCE_VERSION_LOGGING) {\n\t\tconsole.log(\"%c * Tone.js \" + Tone.version + \" * \", \"background: #000; color: #fff\");\n\t}\n\n\treturn Tone;\n});\n","'use strict';\r\n\r\n\r\ndefine(['audiocontext'], function (audiocontext) {\r\n /**\r\n * Master contains AudioContext and the master sound output.\r\n * @for p5\r\n */\r\n var Master = function() {\r\n this.input = audiocontext.createGain();\r\n this.output = audiocontext.createGain();\r\n\r\n //put a hard limiter on the output\r\n this.limiter = audiocontext.createDynamicsCompressor();\r\n this.limiter.threshold.value = -3;\r\n this.limiter.ratio.value = 20;\r\n this.limiter.knee.value = 1;\r\n\r\n this.audiocontext = audiocontext;\r\n\r\n this.output.disconnect();\r\n\r\n // connect input to limiter\r\n this.input.connect(this.limiter);\r\n\r\n // connect limiter to output\r\n this.limiter.connect(this.output);\r\n\r\n // meter is just for global Amplitude / FFT analysis\r\n this.meter = audiocontext.createGain();\r\n this.fftMeter = audiocontext.createGain();\r\n this.output.connect(this.meter);\r\n this.output.connect(this.fftMeter);\r\n\r\n // connect output to destination\r\n this.output.connect(this.audiocontext.destination);\r\n\r\n // an array of all sounds in the sketch\r\n this.soundArray = [];\r\n // an array of all musical parts in the sketch\r\n this.parts = [];\r\n\r\n // file extensions to search for\r\n this.extensions = [];\r\n };\r\n\r\n // create a single instance of the p5Sound / master output for use within this sketch\r\n var p5sound = new Master();\r\n\r\n /**\r\n * Returns a number representing the master amplitude (volume) for sound\r\n * in this sketch.\r\n *\r\n * @method getMasterVolume\r\n * @return {Number} Master amplitude (volume) for sound in this sketch.\r\n * Should be between 0.0 (silence) and 1.0.\r\n */\r\n p5.prototype.getMasterVolume = function() {\r\n return p5sound.output.gain.value;\r\n };\r\n\r\n /**\r\n *
Scale the output of all sound in this sketch
\r\n * Scaled between 0.0 (silence) and 1.0 (full volume).\r\n * 1.0 is the maximum amplitude of a digital sound, so multiplying\r\n * by greater than 1.0 may cause digital distortion. To\r\n * fade, provide a rampTime parameter. For more\r\n * complex fades, see the Envelope class.\r\n *\r\n * Alternately, you can pass in a signal source such as an\r\n * oscillator to modulate the amplitude with an audio signal.\r\n *\r\n *
How This Works: When you load the p5.sound module, it\r\n * creates a single instance of p5sound. All sound objects in this\r\n * module output to p5sound before reaching your computer's output.\r\n * So if you change the amplitude of p5sound, it impacts all of the\r\n * sound in this module.
\r\n *\r\n *
If no value is provided, returns a Web Audio API Gain Node
\r\n *\r\n * @method masterVolume\r\n * @param {Number|Object} volume Volume (amplitude) between 0.0\r\n * and 1.0 or modulating signal/oscillator\r\n * @param {Number} [rampTime] Fade for t seconds\r\n * @param {Number} [timeFromNow] Schedule this event to happen at\r\n * t seconds in the future\r\n */\r\n p5.prototype.masterVolume = function(vol, rampTime, tFromNow) {\r\n if (typeof vol === 'number') {\r\n var rampTime = rampTime || 0;\r\n var tFromNow = tFromNow || 0;\r\n var now = p5sound.audiocontext.currentTime;\r\n var currentVol = p5sound.output.gain.value;\r\n p5sound.output.gain.cancelScheduledValues(now + tFromNow);\r\n p5sound.output.gain.linearRampToValueAtTime(currentVol, now + tFromNow);\r\n p5sound.output.gain.linearRampToValueAtTime(vol, now + tFromNow + rampTime);\r\n }\r\n else if (vol) {\r\n vol.connect(p5sound.output.gain);\r\n } else {\r\n // return the Gain Node\r\n return p5sound.output.gain;\r\n }\r\n };\r\n\r\n /**\r\n * `p5.soundOut` is the p5.sound master output. It sends output to\r\n * the destination of this window's web audio context. It contains\r\n * Web Audio API nodes including a dyanmicsCompressor (.limiter),\r\n * and Gain Nodes for .input and .output.\r\n *\r\n * @property {Object} soundOut\r\n */\r\n p5.prototype.soundOut = p5.soundOut = p5sound;\r\n\r\n /**\r\n * a silent connection to the DesinationNode\r\n * which will ensure that anything connected to it\r\n * will not be garbage collected\r\n *\r\n * @private\r\n */\r\n p5.soundOut._silentNode = p5sound.audiocontext.createGain();\r\n p5.soundOut._silentNode.gain.value = 0;\r\n p5.soundOut._silentNode.connect(p5sound.audiocontext.destination);\r\n\r\n\r\n return p5sound;\r\n});\r\n","define([\"Tone/core/Tone\", \"Tone/signal/WaveShaper\", \"Tone/type/Type\", \"Tone/core/Param\", \"Tone/core/Gain\"], function(Tone){\n\n\t\"use strict\";\n\n\t/**\n\t * @class A signal is an audio-rate value. Tone.Signal is a core component of the library.\n\t * Unlike a number, Signals can be scheduled with sample-level accuracy. Tone.Signal\n\t * has all of the methods available to native Web Audio \n\t * [AudioParam](http://webaudio.github.io/web-audio-api/#the-audioparam-interface)\n\t * as well as additional conveniences. Read more about working with signals \n\t * [here](https://github.com/Tonejs/Tone.js/wiki/Signals).\n\t *\n\t * @constructor\n\t * @extends {Tone.Param}\n\t * @param {Number|AudioParam} [value] Initial value of the signal. If an AudioParam\n\t * is passed in, that parameter will be wrapped\n\t * and controlled by the Signal. \n\t * @param {string} [units=Number] unit The units the signal is in. \n\t * @example\n\t * var signal = new Tone.Signal(10);\n\t */\n\tTone.Signal = function(){\n\n\t\tvar options = this.optionsObject(arguments, [\"value\", \"units\"], Tone.Signal.defaults);\n\n\t\t/**\n\t\t * The node where the constant signal value is scaled.\n\t\t * @type {GainNode}\n\t\t * @private\n\t\t */\n\t\tthis.output = this._gain = this.context.createGain();\n\n\t\toptions.param = this._gain.gain;\n\t\tTone.Param.call(this, options);\n\n\t\t/**\n\t\t * The node where the value is set.\n\t\t * @type {Tone.Param}\n\t\t * @private\n\t\t */\n\t\tthis.input = this._param = this._gain.gain;\n\n\t\t//connect the const output to the node output\n\t\tthis.context.getConstant(1).chain(this._gain);\n\t};\n\n\tTone.extend(Tone.Signal, Tone.Param);\n\n\t/**\n\t * The default values\n\t * @type {Object}\n\t * @static\n\t * @const\n\t */\n\tTone.Signal.defaults = {\n\t\t\"value\" : 0,\n\t\t\"units\" : Tone.Type.Default,\n\t\t\"convert\" : true,\n\t};\n\n\t/**\n\t * When signals connect to other signals or AudioParams, \n\t * they take over the output value of that signal or AudioParam. \n\t * For all other nodes, the behavior is the same as a default connect. \n\t *\n\t * @override\n\t * @param {AudioParam|AudioNode|Tone.Signal|Tone} node \n\t * @param {number} [outputNumber=0] The output number to connect from.\n\t * @param {number} [inputNumber=0] The input number to connect to.\n\t * @returns {Tone.SignalBase} this\n\t * @method\n\t */\n\tTone.Signal.prototype.connect = Tone.SignalBase.prototype.connect;\n\n\t/**\n\t * dispose and disconnect\n\t * @returns {Tone.Signal} this\n\t */\n\tTone.Signal.prototype.dispose = function(){\n\t\tTone.Param.prototype.dispose.call(this);\n\t\tthis._param = null;\n\t\tthis._gain.disconnect();\n\t\tthis._gain = null;\n\t\treturn this;\n\t};\n\n\treturn Tone.Signal;\n});","define([\"Tone/core/Tone\", \"Tone/signal/Signal\", \"Tone/core/Gain\"], function(Tone){\n\n\t\"use strict\";\n\n\t/**\n\t * @class Multiply two incoming signals. Or, if a number is given in the constructor, \n\t * multiplies the incoming signal by that value. \n\t *\n\t * @constructor\n\t * @extends {Tone.Signal}\n\t * @param {number=} value Constant value to multiple. If no value is provided,\n\t * it will return the product of the first and second inputs\n\t * @example\n\t * var mult = new Tone.Multiply();\n\t * var sigA = new Tone.Signal(3);\n\t * var sigB = new Tone.Signal(4);\n\t * sigA.connect(mult, 0, 0);\n\t * sigB.connect(mult, 0, 1);\n\t * //output of mult is 12.\n\t * @example\n\t * var mult = new Tone.Multiply(10);\n\t * var sig = new Tone.Signal(2).connect(mult);\n\t * //the output of mult is 20. \n\t */\n\tTone.Multiply = function(value){\n\n\t\tthis.createInsOuts(2, 0);\n\n\t\t/**\n\t\t * the input node is the same as the output node\n\t\t * it is also the GainNode which handles the scaling of incoming signal\n\t\t * \n\t\t * @type {GainNode}\n\t\t * @private\n\t\t */\n\t\tthis._mult = this.input[0] = this.output = new Tone.Gain();\n\n\t\t/**\n\t\t * the scaling parameter\n\t\t * @type {AudioParam}\n\t\t * @private\n\t\t */\n\t\tthis._param = this.input[1] = this.output.gain;\n\t\t\n\t\tthis._param.value = this.defaultArg(value, 0);\n\t};\n\n\tTone.extend(Tone.Multiply, Tone.Signal);\n\n\t/**\n\t * clean up\n\t * @returns {Tone.Multiply} this\n\t */\n\tTone.Multiply.prototype.dispose = function(){\n\t\tTone.prototype.dispose.call(this);\n\t\tthis._mult.dispose();\n\t\tthis._mult = null;\n\t\tthis._param = null;\n\t\treturn this;\n\t}; \n\n\treturn Tone.Multiply;\n});\n","'use strict';\r\ndefine(function (require) {\r\n\r\n var p5sound = require('master');\r\n var CrossFade = require('Tone/component/CrossFade');\r\n\r\n /**\r\n * Effect is a base class for audio effects in p5. \r\n * This module handles the nodes and methods that are\r\n * common and useful for current and future effects.\r\n *\r\n *\r\n * This class is extended by p5.Distortion,\r\n * p5.Compressor,\r\n * p5.Delay,\r\n * p5.Filter,\r\n * p5.Reverb.\r\n *\r\n * @class p5.Effect\r\n * @constructor\r\n *\r\n * @param {Object} [ac] Reference to the audio context of the p5 object\r\n * @param {AudioNode} [input] Gain Node effect wrapper\r\n * @param {AudioNode} [output] Gain Node effect wrapper\r\n * @param {Object} [_drywet] Tone.JS CrossFade node (defaults to value: 1)\r\n * @param {AudioNode} [wet] Effects that extend this class should connect\r\n * to the wet signal to this gain node, so that dry and wet\r\n * signals are mixed properly.\r\n */\r\n p5.Effect = function() {\r\n this.ac = p5sound.audiocontext;\r\n\r\n this.input = this.ac.createGain();\r\n this.output = this.ac.createGain();\r\n\r\n /**\r\n *\tThe p5.Effect class is built\r\n * \tusing Tone.js CrossFade\r\n * \t@private\r\n */\r\n\r\n this._drywet = new CrossFade(1);\r\n\r\n /**\r\n *\tIn classes that extend\r\n *\tp5.Effect, connect effect nodes\r\n *\tto the wet parameter\r\n */\r\n this.wet = this.ac.createGain();\r\n\r\n this.input.connect(this._drywet.a);\r\n this.wet.connect(this._drywet.b);\r\n this._drywet.connect(this.output);\r\n\r\n this.connect();\r\n\r\n //Add to the soundArray\r\n p5sound.soundArray.push(this);\r\n };\r\n\r\n /**\r\n * Set the output volume of the filter.\r\n *\r\n * @method amp\r\n * @for p5.Effect\r\n * @param {Number} [vol] amplitude between 0 and 1.0\r\n * @param {Number} [rampTime] create a fade that lasts until rampTime\r\n * @param {Number} [tFromNow] schedule this event to happen in tFromNow seconds\r\n */\r\n p5.Effect.prototype.amp = function(vol, rampTime, tFromNow){\r\n var rampTime = rampTime || 0;\r\n var tFromNow = tFromNow || 0;\r\n var now = p5sound.audiocontext.currentTime;\r\n var currentVol = this.output.gain.value;\r\n this.output.gain.cancelScheduledValues(now);\r\n this.output.gain.linearRampToValueAtTime(currentVol, now + tFromNow + .001);\r\n this.output.gain.linearRampToValueAtTime(vol, now + tFromNow + rampTime + .001);\r\n };\r\n\r\n /**\r\n * Link effects together in a chain\r\n * Example usage: filter.chain(reverb, delay, panner);\r\n * May be used with an open-ended number of arguments\r\n *\r\n * @method chain\r\n * @for p5.Effect\r\n * @param {Object} [arguments] Chain together multiple sound objects\r\n */\r\n p5.Effect.prototype.chain = function(){\r\n if (arguments.length>0){\r\n this.connect(arguments[0]);\r\n for(var i=1;i\r\n * var notes = [60, 64, 67, 72];\r\n * var i = 0;\r\n *\r\n * function setup() {\r\n * osc = new p5.Oscillator('Triangle');\r\n * osc.start();\r\n * frameRate(1);\r\n * }\r\n *\r\n * function draw() {\r\n * var freq = midiToFreq(notes[i]);\r\n * osc.freq(freq);\r\n * i++;\r\n * if (i >= notes.length){\r\n * i = 0;\r\n * }\r\n * }\r\n * \r\n */\r\n var midiToFreq = p5.prototype.midiToFreq = function(m) {\r\n return 440 * Math.pow(2, (m-69)/12.0);\r\n };\r\n\r\n // This method converts ANSI notes specified as a string \"C4\", \"Eb3\" to a frequency\r\n var noteToFreq = function(note) {\r\n if (typeof note !== 'string') {\r\n return note;\r\n }\r\n var wholeNotes = {A:21, B:23, C:24, D:26, E:28, F:29, G:31};\r\n var value = wholeNotes[ note[0].toUpperCase() ];\r\n var octave = ~~note.slice(-1);\r\n value += 12 * (octave -1);\r\n\r\n switch(note[1]) {\r\n case '#':\r\n value += 1;\r\n break;\r\n case 'b':\r\n value -= 1;\r\n break;\r\n default:\r\n break;\r\n }\r\n return midiToFreq(value);\r\n };\r\n\r\n /**\r\n * List the SoundFile formats that you will include. LoadSound\r\n * will search your directory for these extensions, and will pick\r\n * a format that is compatable with the client's web browser.\r\n * Here is a free online file\r\n * converter.\r\n *\r\n * @method soundFormats\r\n * @param {String} [...formats] i.e. 'mp3', 'wav', 'ogg'\r\n * @example\r\n *
\r\n * function preload() {\r\n * // set the global sound formats\r\n * soundFormats('mp3', 'ogg');\r\n *\r\n * // load either beatbox.mp3, or .ogg, depending on browser\r\n * mySound = loadSound('assets/beatbox.mp3');\r\n * }\r\n *\r\n * function setup() {\r\n * mySound.play();\r\n * }\r\n *
\r\n */\r\n p5.prototype.soundFormats = function() {\r\n // reset extensions array\r\n p5sound.extensions = [];\r\n // add extensions\r\n for (var i = 0; i < arguments.length; i++) {\r\n arguments[i] = arguments[i].toLowerCase();\r\n if (['mp3','wav','ogg', 'm4a', 'aac'].indexOf(arguments[i]) > -1) {\r\n p5sound.extensions.push(arguments[i]);\r\n } else {\r\n throw arguments[i] + ' is not a valid sound format!';\r\n }\r\n }\r\n };\r\n\r\n p5.prototype.disposeSound = function() {\r\n for (var i = 0; i < p5sound.soundArray.length; i++) {\r\n p5sound.soundArray[i].dispose();\r\n }\r\n };\r\n\r\n // register removeSound to dispose of p5sound SoundFiles, Convolvers,\r\n // Oscillators etc when sketch ends\r\n p5.prototype.registerMethod('remove', p5.prototype.disposeSound);\r\n\r\n p5.prototype._checkFileFormats = function(paths) {\r\n var path;\r\n // if path is a single string, check to see if extension is provided\r\n if (typeof paths === 'string') {\r\n path = paths;\r\n // see if extension is provided\r\n var extTest = path.split('.').pop();\r\n // if an extension is provided...\r\n if (['mp3','wav','ogg', 'm4a', 'aac'].indexOf(extTest) > -1) {\r\n if (p5.prototype.isFileSupported(extTest)) {\r\n path = path;\r\n }\r\n else {\r\n var pathSplit = path.split('.');\r\n var pathCore = pathSplit[pathSplit.length - 1];\r\n for (var i = 0; i 1) {\r\n rightChannel = audioBuffer.getChannelData(1);\r\n } else {\r\n rightChannel = leftChannel;\r\n }\r\n\r\n var interleaved = interleave(leftChannel, rightChannel);\r\n\r\n // create the buffer and view to create the .WAV file\r\n var buffer = new window.ArrayBuffer(44 + interleaved.length * 2);\r\n var view = new window.DataView(buffer);\r\n\r\n // write the WAV container,\r\n // check spec at: https://web.archive.org/web/20171215131933/http://tiny.systems/software/soundProgrammer/WavFormatDocs.pdf\r\n\r\n // RIFF chunk descriptor\r\n writeUTFBytes(view, 0, 'RIFF');\r\n view.setUint32(4, 36 + interleaved.length * 2, true);\r\n writeUTFBytes(view, 8, 'WAVE');\r\n // FMT sub-chunk\r\n writeUTFBytes(view, 12, 'fmt ');\r\n view.setUint32(16, 16, true);\r\n view.setUint16(20, 1, true);\r\n // stereo (2 channels)\r\n view.setUint16(22, 2, true);\r\n view.setUint32(24, p5sound.audiocontext.sampleRate, true);\r\n view.setUint32(28, p5sound.audiocontext.sampleRate * 4, true);\r\n view.setUint16(32, 4, true);\r\n view.setUint16(34, 16, true);\r\n // data sub-chunk\r\n writeUTFBytes(view, 36, 'data');\r\n view.setUint32(40, interleaved.length * 2, true);\r\n\r\n // write the PCM samples\r\n var lng = interleaved.length;\r\n var index = 44;\r\n var volume = 1;\r\n for (var i = 0; i < lng; i++) {\r\n view.setInt16(index, interleaved[i] * (0x7FFF * volume), true);\r\n index += 2;\r\n }\r\n\r\n return view;\r\n }\r\n\r\n // helper methods to save waves\r\n function interleave(leftChannel, rightChannel) {\r\n var length = leftChannel.length + rightChannel.length;\r\n var result = new Float32Array(length);\r\n\r\n var inputIndex = 0;\r\n\r\n for (var index = 0; index < length;) {\r\n result[index++] = leftChannel[inputIndex];\r\n result[index++] = rightChannel[inputIndex];\r\n inputIndex++;\r\n }\r\n return result;\r\n }\r\n\r\n function writeUTFBytes(view, offset, string) {\r\n var lng = string.length;\r\n for (var i = 0; i < lng; i++) {\r\n view.setUint8(offset + i, string.charCodeAt(i));\r\n }\r\n }\r\n\r\n return {\r\n convertToWav: convertToWav,\r\n midiToFreq: midiToFreq,\r\n noteToFreq: noteToFreq\r\n };\r\n\r\n});\r\n","define([\"Tone/core/Tone\", \"Tone/signal/Signal\", \"Tone/core/Gain\"], function(Tone){\n\n\t\"use strict\";\n\n\t/**\n\t * @class Add a signal and a number or two signals. When no value is\n\t * passed into the constructor, Tone.Add will sum input[0]\n\t * and input[1]. If a value is passed into the constructor, \n\t * the it will be added to the input.\n\t * \n\t * @constructor\n\t * @extends {Tone.Signal}\n\t * @param {number=} value If no value is provided, Tone.Add will sum the first\n\t * and second inputs. \n\t * @example\n\t * var signal = new Tone.Signal(2);\n\t * var add = new Tone.Add(2);\n\t * signal.connect(add);\n\t * //the output of add equals 4\n\t * @example\n\t * //if constructed with no arguments\n\t * //it will add the first and second inputs\n\t * var add = new Tone.Add();\n\t * var sig0 = new Tone.Signal(3).connect(add, 0, 0);\n\t * var sig1 = new Tone.Signal(4).connect(add, 0, 1);\n\t * //the output of add equals 7. \n\t */\n\tTone.Add = function(value){\n\n\t\tthis.createInsOuts(2, 0);\n\n\t\t/**\n\t\t * the summing node\n\t\t * @type {GainNode}\n\t\t * @private\n\t\t */\n\t\tthis._sum = this.input[0] = this.input[1] = this.output = new Tone.Gain();\n\n\t\t/**\n\t\t * @private\n\t\t * @type {Tone.Signal}\n\t\t */\n\t\tthis._param = this.input[1] = new Tone.Signal(value);\n\n\t\tthis._param.connect(this._sum);\n\t};\n\n\tTone.extend(Tone.Add, Tone.Signal);\n\t\n\t/**\n\t * Clean up.\n\t * @returns {Tone.Add} this\n\t */\n\tTone.Add.prototype.dispose = function(){\n\t\tTone.prototype.dispose.call(this);\n\t\tthis._sum.dispose();\n\t\tthis._sum = null;\n\t\tthis._param.dispose();\n\t\tthis._param = null;\n\t\treturn this;\n\t}; \n\n\treturn Tone.Add;\n});","define([\"Tone/core/Tone\", \"Tone/type/Time\", \"Tone/type/Frequency\", \"Tone/type/TransportTime\", \"Tone/core/Context\"],\nfunction (Tone) {\t\n\n\t///////////////////////////////////////////////////////////////////////////\n\t//\tTYPES\n\t///////////////////////////////////////////////////////////////////////////\n\n\t/**\n\t * Units which a value can take on.\n\t * @enum {String}\n\t */\n\tTone.Type = {\n\t\t/** \n\t\t * Default units\n\t\t * @typedef {Default}\n\t\t */\n\t\tDefault : \"number\",\n\t\t/**\n\t\t * Time can be described in a number of ways. Read more [Time](https://github.com/Tonejs/Tone.js/wiki/Time).\n\t\t *\n\t\t *
\n\t\t *
Numbers, which will be taken literally as the time (in seconds).
\n\t\t *
Notation, (\"4n\", \"8t\") describes time in BPM and time signature relative values.
\n\t\t *
TransportTime, (\"4:3:2\") will also provide tempo and time signature relative times \n\t\t * in the form BARS:QUARTERS:SIXTEENTHS.
\n\t\t *
Frequency, (\"8hz\") is converted to the length of the cycle in seconds.
\n\t\t *
Now-Relative, (\"+1\") prefix any of the above with \"+\" and it will be interpreted as \n\t\t * \"the current time plus whatever expression follows\".
\n\t\t *
Expressions, (\"3:0 + 2 - (1m / 7)\") any of the above can also be combined \n\t\t * into a mathematical expression which will be evaluated to compute the desired time.
\n\t\t *
No Argument, for methods which accept time, no argument will be interpreted as \n\t\t * \"now\" (i.e. the currentTime).
\n\t\t *
\n\t\t * \n\t\t * @typedef {Time}\n\t\t */\n\t\tTime : \"time\",\n\t\t/**\n\t\t * Frequency can be described similar to time, except ultimately the\n\t\t * values are converted to frequency instead of seconds. A number\n\t\t * is taken literally as the value in hertz. Additionally any of the \n\t\t * Time encodings can be used. Note names in the form\n\t\t * of NOTE OCTAVE (i.e. C4) are also accepted and converted to their\n\t\t * frequency value. \n\t\t * @typedef {Frequency}\n\t\t */\n\t\tFrequency : \"frequency\",\n\t\t/**\n\t\t * TransportTime describes a position along the Transport's timeline. It is\n\t\t * similar to Time in that it uses all the same encodings, but TransportTime specifically\n\t\t * pertains to the Transport's timeline, which is startable, stoppable, loopable, and seekable. \n\t\t * [Read more](https://github.com/Tonejs/Tone.js/wiki/TransportTime)\n\t\t * @typedef {TransportTime}\n\t\t */\n\t\tTransportTime : \"transportTime\",\n\t\t/** \n\t\t * Ticks are the basic subunit of the Transport. They are\n\t\t * the smallest unit of time that the Transport supports.\n\t\t * @typedef {Ticks}\n\t\t */\n\t\tTicks : \"ticks\",\n\t\t/** \n\t\t * Normal values are within the range [0, 1].\n\t\t * @typedef {NormalRange}\n\t\t */\n\t\tNormalRange : \"normalRange\",\n\t\t/** \n\t\t * AudioRange values are between [-1, 1].\n\t\t * @typedef {AudioRange}\n\t\t */\n\t\tAudioRange : \"audioRange\",\n\t\t/** \n\t\t * Decibels are a logarithmic unit of measurement which is useful for volume\n\t\t * because of the logarithmic way that we perceive loudness. 0 decibels \n\t\t * means no change in volume. -10db is approximately half as loud and 10db \n\t\t * is twice is loud. \n\t\t * @typedef {Decibels}\n\t\t */\n\t\tDecibels : \"db\",\n\t\t/** \n\t\t * Half-step note increments, i.e. 12 is an octave above the root. and 1 is a half-step up.\n\t\t * @typedef {Interval}\n\t\t */\n\t\tInterval : \"interval\",\n\t\t/** \n\t\t * Beats per minute. \n\t\t * @typedef {BPM}\n\t\t */\n\t\tBPM : \"bpm\",\n\t\t/** \n\t\t * The value must be greater than or equal to 0.\n\t\t * @typedef {Positive}\n\t\t */\n\t\tPositive : \"positive\",\n\t\t/** \n\t\t * A cent is a hundredth of a semitone. \n\t\t * @typedef {Cents}\n\t\t */\n\t\tCents : \"cents\",\n\t\t/** \n\t\t * Angle between 0 and 360. \n\t\t * @typedef {Degrees}\n\t\t */\n\t\tDegrees : \"degrees\",\n\t\t/** \n\t\t * A number representing a midi note.\n\t\t * @typedef {MIDI}\n\t\t */\n\t\tMIDI : \"midi\",\n\t\t/** \n\t\t * A colon-separated representation of time in the form of\n\t\t * Bars:Beats:Sixteenths. \n\t\t * @typedef {BarsBeatsSixteenths}\n\t\t */\n\t\tBarsBeatsSixteenths : \"barsBeatsSixteenths\",\n\t\t/** \n\t\t * Sampling is the reduction of a continuous signal to a discrete signal.\n\t\t * Audio is typically sampled 44100 times per second. \n\t\t * @typedef {Samples}\n\t\t */\n\t\tSamples : \"samples\",\n\t\t/** \n\t\t * Hertz are a frequency representation defined as one cycle per second.\n\t\t * @typedef {Hertz}\n\t\t */\n\t\tHertz : \"hertz\",\n\t\t/** \n\t\t * A frequency represented by a letter name, \n\t\t * accidental and octave. This system is known as\n\t\t * [Scientific Pitch Notation](https://en.wikipedia.org/wiki/Scientific_pitch_notation).\n\t\t * @typedef {Note}\n\t\t */\n\t\tNote : \"note\",\n\t\t/** \n\t\t * One millisecond is a thousandth of a second. \n\t\t * @typedef {Milliseconds}\n\t\t */\n\t\tMilliseconds : \"milliseconds\",\n\t\t/** \n\t\t * Seconds are the time unit of the AudioContext. In the end, \n\t\t * all values need to be evaluated to seconds. \n\t\t * @typedef {Seconds}\n\t\t */\n\t\tSeconds : \"seconds\",\n\t\t/** \n\t\t * A string representing a duration relative to a measure. \n\t\t *
\n\t\t * \t
\"4n\" = quarter note
\n\t\t * \t
\"2m\" = two measures
\n\t\t * \t
\"8t\" = eighth-note triplet
\n\t\t *
\n\t\t * @typedef {Notation}\n\t\t */\n\t\tNotation : \"notation\",\n\t};\n\n\t///////////////////////////////////////////////////////////////////////////\n\t// AUGMENT TONE's PROTOTYPE\n\t///////////////////////////////////////////////////////////////////////////\n\n\t/**\n\t * Convert Time into seconds.\n\t * \n\t * Unlike the method which it overrides, this takes into account \n\t * transporttime and musical notation.\n\t *\n\t * Time : 1.40\n\t * Notation: 4n|1m|2t\n\t * Now Relative: +3n\n\t * Math: 3n+16n or even complicated expressions ((3n*2)/6 + 1)\n\t *\n\t * @param {Time} time \n\t * @return {Seconds} \n\t */\n\tTone.prototype.toSeconds = function(time){\n\t\tif (this.isNumber(time)){\n\t\t\treturn time;\n\t\t} else if (this.isUndef(time)){\n\t\t\treturn this.now();\t\t\t\n\t\t} else if (this.isString(time)){\n\t\t\treturn (new Tone.Time(time)).toSeconds();\n\t\t} else if (time instanceof Tone.TimeBase){\n\t\t\treturn time.toSeconds();\n\t\t}\n\t};\n\n\t/**\n\t * Convert a frequency representation into a number.\n\t * @param {Frequency} freq \n\t * @return {Hertz} the frequency in hertz\n\t */\n\tTone.prototype.toFrequency = function(freq){\n\t\tif (this.isNumber(freq)){\n\t\t\treturn freq;\n\t\t} else if (this.isString(freq) || this.isUndef(freq)){\n\t\t\treturn (new Tone.Frequency(freq)).valueOf();\n\t\t} else if (freq instanceof Tone.TimeBase){\n\t\t\treturn freq.toFrequency();\n\t\t}\n\t};\n\n\t/**\n\t * Convert a time representation into ticks.\n\t * @param {Time} time\n\t * @return {Ticks} the time in ticks\n\t */\n\tTone.prototype.toTicks = function(time){\n\t\tif (this.isNumber(time) || this.isString(time)){\n\t\t\treturn (new Tone.TransportTime(time)).toTicks();\n\t\t} else if (this.isUndef(time)){\n\t\t\treturn Tone.Transport.ticks;\t\t\t\n\t\t} else if (time instanceof Tone.TimeBase){\n\t\t\treturn time.toTicks();\n\t\t}\n\t};\n\n\treturn Tone;\n});","define([\"Tone/core/Tone\", \"Tone/core/Param\", \"Tone/type/Type\"], function (Tone) {\n\n\t\"use strict\";\n\n\t/**\n\t * createGain shim\n\t * @private\n\t */\n\tif (window.GainNode && !AudioContext.prototype.createGain){\n\t\tAudioContext.prototype.createGain = AudioContext.prototype.createGainNode;\n\t}\n\n\t/**\n\t * @class A thin wrapper around the Native Web Audio GainNode.\n\t * The GainNode is a basic building block of the Web Audio\n\t * API and is useful for routing audio and adjusting gains. \n\t * @extends {Tone}\n\t * @param {Number=} gain The initial gain of the GainNode\n\t * @param {Tone.Type=} units The units of the gain parameter. \n\t */\n\tTone.Gain = function(){\n\n\t\tvar options = this.optionsObject(arguments, [\"gain\", \"units\"], Tone.Gain.defaults);\n\n\t\t/**\n\t\t * The GainNode\n\t\t * @type {GainNode}\n\t\t * @private\n\t\t */\n\t\tthis.input = this.output = this._gainNode = this.context.createGain();\n\n\t\t/**\n\t\t * The gain parameter of the gain node.\n\t\t * @type {Tone.Param}\n\t\t * @signal\n\t\t */\n\t\tthis.gain = new Tone.Param({\n\t\t\t\"param\" : this._gainNode.gain, \n\t\t\t\"units\" : options.units,\n\t\t\t\"value\" : options.gain,\n\t\t\t\"convert\" : options.convert\n\t\t});\n\t\tthis._readOnly(\"gain\");\n\t};\n\n\tTone.extend(Tone.Gain);\n\n\t/**\n\t * The defaults\n\t * @const\n\t * @type {Object}\n\t */\n\tTone.Gain.defaults = {\n\t\t\"gain\" : 1,\n\t\t\"convert\" : true,\n\t};\n\n\t/**\n\t * Clean up.\n\t * @return {Tone.Gain} this\n\t */\n\tTone.Gain.prototype.dispose = function(){\n\t\tTone.Param.prototype.dispose.call(this);\n\t\tthis._gainNode.disconnect();\n\t\tthis._gainNode = null;\n\t\tthis._writable(\"gain\");\n\t\tthis.gain.dispose();\n\t\tthis.gain = null;\n\t};\n\n\t//STATIC///////////////////////////////////////////////////////////////////\n\n\t/**\n\t * Create input and outputs for this object.\n\t * @param {Number} input The number of inputs\n\t * @param {Number=} outputs The number of outputs\n\t * @return {Tone} this\n\t * @internal\n\t */\n\tTone.prototype.createInsOuts = function(inputs, outputs){\n\n\t\tif (inputs === 1){\n\t\t\tthis.input = new Tone.Gain();\n\t\t} else if (inputs > 1){\n\t\t\tthis.input = new Array(inputs);\n\t\t}\n\n\t\tif (outputs === 1){\n\t\t\tthis.output = new Tone.Gain();\n\t\t} else if (outputs > 1){\n\t\t\tthis.output = new Array(inputs);\n\t\t}\n\t};\n\n\t///////////////////////////////////////////////////////////////////////////\n\n\treturn Tone.Gain;\n});","'use strict';\r\n\r\ndefine(function () {\r\n /*\r\n Helper function to generate an error\r\n with a custom stack trace that points to the sketch\r\n and removes other parts of the stack trace.\r\n\r\n @private\r\n @class customError\r\n @constructor\r\n @param {String} name custom error name\r\n @param {String} errorTrace custom error trace\r\n @param {String} failedPath path to the file that failed to load\r\n @property {String} name custom error name\r\n @property {String} message custom error message\r\n @property {String} stack trace the error back to a line in the user's sketch.\r\n Note: this edits out stack trace within p5.js and p5.sound.\r\n @property {String} originalStack unedited, original stack trace\r\n @property {String} failedPath path to the file that failed to load\r\n @return {Error} returns a custom Error object\r\n */\r\n var CustomError = function(name, errorTrace, failedPath) {\r\n var err = new Error();\r\n var tempStack, splitStack;\r\n\r\n err.name = name;\r\n err.originalStack = err.stack + errorTrace;\r\n tempStack = err.stack + errorTrace;\r\n err.failedPath = failedPath;\r\n\r\n // only print the part of the stack trace that refers to the user code:\r\n var splitStack = tempStack.split('\\n');\r\n splitStack = splitStack.filter(function(ln) {\r\n return !ln.match(/(p5.|native code|globalInit)/g);\r\n });\r\n err.stack = splitStack.join('\\n');\r\n\r\n return err; // TODO: is this really a constructor?\r\n };\r\n\r\n return CustomError;\r\n});\r\n","define([\"Tone/core/Tone\", \"Tone/core/Emitter\"], function (Tone) {\n\n\t/**\n\t * shim\n\t * @private\n\t */\n\tif (!window.hasOwnProperty(\"AudioContext\") && window.hasOwnProperty(\"webkitAudioContext\")){\n\t\twindow.AudioContext = window.webkitAudioContext;\n\t}\n\n\t/**\n\t * @class Wrapper around the native AudioContext.\n\t * @extends {Tone.Emitter}\n\t * @param {AudioContext=} context optionally pass in a context\n\t */\n\tTone.Context = function(context){\n\n\t\tTone.Emitter.call(this);\n\n\t\tif (!context){\n\t\t\tcontext = new window.AudioContext();\n\t\t}\n\t\tthis._context = context;\n\t\t// extend all of the methods\n\t\tfor (var prop in this._context){\n\t\t\tthis._defineProperty(this._context, prop);\n\t\t}\n\n\t\t///////////////////////////////////////////////////////////////////////\n\t\t// WORKER\n\t\t///////////////////////////////////////////////////////////////////////\n\n\t\t/**\n\t\t * The default latency hint\n\t\t * @type {String}\n\t\t * @private\n\t\t */\n\t\tthis._latencyHint = \"interactive\";\n\n\t\t/**\n\t\t * The amount of time events are scheduled\n\t\t * into the future\n\t\t * @type {Number}\n\t\t * @private\n\t\t */\n\t\tthis._lookAhead = 0.1;\n\n\t\t/**\n\t\t * How often the update look runs\n\t\t * @type {Number}\n\t\t * @private\n\t\t */\n\t\tthis._updateInterval = this._lookAhead/3;\n\n\t\t/**\n\t\t * A reference to the actual computed update interval\n\t\t * @type {Number}\n\t\t * @private\n\t\t */\n\t\tthis._computedUpdateInterval = 0;\n\n\t\t/**\n\t\t * The web worker which is used to update Tone.Clock\n\t\t * @private\n\t\t * @type {WebWorker}\n\t\t */\n\t\tthis._worker = this._createWorker();\n\n\t\t/**\n\t\t * An object containing all of the constants AudioBufferSourceNodes\n\t\t * @type {Object}\n\t\t * @private\n\t\t */\n\t\tthis._constants = {};\n\n\t};\n\n\tTone.extend(Tone.Context, Tone.Emitter);\n\tTone.Emitter.mixin(Tone.Context);\n\n\t/**\n\t * Define a property on this Tone.Context. \n\t * This is used to extend the native AudioContext\n\t * @param {AudioContext} context\n\t * @param {String} prop \n\t * @private\n\t */\n\tTone.Context.prototype._defineProperty = function(context, prop){\n\t\tif (this.isUndef(this[prop])){\n\t\t\tObject.defineProperty(this, prop, {\n\t\t\t\tget : function(){\n\t\t\t\t\tif (typeof context[prop] === \"function\"){\n\t\t\t\t\t\treturn context[prop].bind(context);\n\t\t\t\t\t} else {\n\t\t\t\t\t\treturn context[prop];\n\t\t\t\t\t}\n\t\t\t\t},\n\t\t\t\tset : function(val){\n\t\t\t\t\tcontext[prop] = val;\n\t\t\t\t}\n\t\t\t});\n\t\t}\n\t};\n\n\t/**\n\t * The current audio context time\n\t * @return {Number}\n\t */\n\tTone.Context.prototype.now = function(){\n\t\treturn this._context.currentTime;\n\t};\n\n\t/**\n\t * Generate a web worker\n\t * @return {WebWorker}\n\t * @private\n\t */\n\tTone.Context.prototype._createWorker = function(){\n\t\t\n\t\t//URL Shim\n\t\twindow.URL = window.URL || window.webkitURL;\n\n\t\tvar blob = new Blob([\n\t\t\t//the initial timeout time\n\t\t\t\"var timeoutTime = \"+(this._updateInterval * 1000).toFixed(1)+\";\" +\n\t\t\t//onmessage callback\n\t\t\t\"self.onmessage = function(msg){\" +\n\t\t\t\"\ttimeoutTime = parseInt(msg.data);\" + \n\t\t\t\"};\" + \n\t\t\t//the tick function which posts a message\n\t\t\t//and schedules a new tick\n\t\t\t\"function tick(){\" +\n\t\t\t\"\tsetTimeout(tick, timeoutTime);\" +\n\t\t\t\"\tself.postMessage('tick');\" +\n\t\t\t\"}\" +\n\t\t\t//call tick initially\n\t\t\t\"tick();\"\n\t\t]);\n\t\tvar blobUrl = URL.createObjectURL(blob);\n\t\tvar worker = new Worker(blobUrl);\n\n\t\tworker.addEventListener(\"message\", function(){\n\t\t\t// tick the clock\n\t\t\tthis.emit(\"tick\");\n\t\t}.bind(this));\n\n\t\t//lag compensation\n\t\tworker.addEventListener(\"message\", function(){\n\t\t\tvar now = this.now();\n\t\t\tif (this.isNumber(this._lastUpdate)){\n\t\t\t\tvar diff = now - this._lastUpdate;\n\t\t\t\tthis._computedUpdateInterval = Math.max(diff, this._computedUpdateInterval * 0.97);\n\t\t\t}\n\t\t\tthis._lastUpdate = now;\n\t\t}.bind(this));\n\n\t\treturn worker;\n\t};\n\n\t/**\n\t * Generate a looped buffer at some constant value.\n\t * @param {Number} val\n\t * @return {BufferSourceNode}\n\t */\n\tTone.Context.prototype.getConstant = function(val){\n\t\tif (this._constants[val]){\n\t\t\treturn this._constants[val];\n\t\t} else {\n\t\t\tvar buffer = this._context.createBuffer(1, 128, this._context.sampleRate);\n\t\t\tvar arr = buffer.getChannelData(0);\n\t\t\tfor (var i = 0; i < arr.length; i++){\n\t\t\t\tarr[i] = val;\n\t\t\t}\n\t\t\tvar constant = this._context.createBufferSource();\n\t\t\tconstant.channelCount = 1;\n\t\t\tconstant.channelCountMode = \"explicit\";\n\t\t\tconstant.buffer = buffer;\n\t\t\tconstant.loop = true;\n\t\t\tconstant.start(0);\n\t\t\tthis._constants[val] = constant;\n\t\t\treturn constant;\n\t\t}\n\t};\n\n\t/**\n\t * This is the time that the clock is falling behind\n\t * the scheduled update interval. The Context automatically\n\t * adjusts for the lag and schedules further in advance.\n\t * @type {Number}\n\t * @memberOf Tone.Context\n\t * @name lag\n\t * @static\n\t * @readOnly\n\t */\n\tObject.defineProperty(Tone.Context.prototype, \"lag\", {\n\t\tget : function(){\n\t\t\tvar diff = this._computedUpdateInterval - this._updateInterval;\n\t\t\tdiff = Math.max(diff, 0);\n\t\t\treturn diff;\n\t\t}\n\t});\n\n\t/**\n\t * The amount of time in advance that events are scheduled.\n\t * The lookAhead will adjust slightly in response to the \n\t * measured update time to try to avoid clicks.\n\t * @type {Number}\n\t * @memberOf Tone.Context\n\t * @name lookAhead\n\t * @static\n\t */\n\tObject.defineProperty(Tone.Context.prototype, \"lookAhead\", {\n\t\tget : function(){\n\t\t\treturn this._lookAhead;\n\t\t},\n\t\tset : function(lA){\n\t\t\tthis._lookAhead = lA;\n\t\t}\n\t});\n\n\t/**\n\t * How often the Web Worker callback is invoked.\n\t * This number corresponds to how responsive the scheduling\n\t * can be. Context.updateInterval + Context.lookAhead gives you the\n\t * total latency between scheduling an event and hearing it.\n\t * @type {Number}\n\t * @memberOf Tone.Context\n\t * @name updateInterval\n\t * @static\n\t */\n\tObject.defineProperty(Tone.Context.prototype, \"updateInterval\", {\n\t\tget : function(){\n\t\t\treturn this._updateInterval;\n\t\t},\n\t\tset : function(interval){\n\t\t\tthis._updateInterval = Math.max(interval, Tone.prototype.blockTime);\n\t\t\tthis._worker.postMessage(Math.max(interval * 1000, 1));\n\t\t}\n\t});\n\n\t/**\n\t * The type of playback, which affects tradeoffs between audio \n\t * output latency and responsiveness. \n\t * \n\t * In addition to setting the value in seconds, the latencyHint also\n\t * accepts the strings \"interactive\" (prioritizes low latency), \n\t * \"playback\" (prioritizes sustained playback), \"balanced\" (balances\n\t * latency and performance), and \"fastest\" (lowest latency, might glitch more often). \n\t * @type {String|Seconds}\n\t * @memberOf Tone.Context#\n\t * @name latencyHint\n\t * @static\n\t * @example\n\t * //set the lookAhead to 0.3 seconds\n\t * Tone.context.latencyHint = 0.3;\n\t */\n\tObject.defineProperty(Tone.Context.prototype, \"latencyHint\", {\n\t\tget : function(){\n\t\t\treturn this._latencyHint;\n\t\t},\n\t\tset : function(hint){\n\t\t\tvar lookAhead = hint;\n\t\t\tthis._latencyHint = hint;\n\t\t\tif (this.isString(hint)){\n\t\t\t\tswitch(hint){\n\t\t\t\t\tcase \"interactive\" :\n\t\t\t\t\t\tlookAhead = 0.1;\n\t\t\t\t\t\tthis._context.latencyHint = hint;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase \"playback\" :\n\t\t\t\t\t\tlookAhead = 0.8;\n\t\t\t\t\t\tthis._context.latencyHint = hint;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase \"balanced\" :\n\t\t\t\t\t\tlookAhead = 0.25;\n\t\t\t\t\t\tthis._context.latencyHint = hint;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase \"fastest\" :\n\t\t\t\t\t\tlookAhead = 0.01;\n\t\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t\tthis.lookAhead = lookAhead;\n\t\t\tthis.updateInterval = lookAhead/3;\n\t\t}\n\t});\n\n\t/**\n\t * Shim all connect/disconnect and some deprecated methods which are still in\n\t * some older implementations.\n\t * @private\n\t */\n\tfunction shimConnect(){\n\n\t\tvar nativeConnect = AudioNode.prototype.connect;\n\t\tvar nativeDisconnect = AudioNode.prototype.disconnect;\n\n\t\t//replace the old connect method\n\t\tfunction toneConnect(B, outNum, inNum){\n\t\t\tif (B.input){\n\t\t\t\tif (Array.isArray(B.input)){\n\t\t\t\t\tif (Tone.prototype.isUndef(inNum)){\n\t\t\t\t\t\tinNum = 0;\n\t\t\t\t\t}\n\t\t\t\t\tthis.connect(B.input[inNum]);\n\t\t\t\t} else {\n\t\t\t\t\tthis.connect(B.input, outNum, inNum);\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\ttry {\n\t\t\t\t\tif (B instanceof AudioNode){\n\t\t\t\t\t\tnativeConnect.call(this, B, outNum, inNum);\n\t\t\t\t\t} else {\n\t\t\t\t\t\tnativeConnect.call(this, B, outNum);\n\t\t\t\t\t}\n\t\t\t\t} catch (e) {\n\t\t\t\t\tthrow new Error(\"error connecting to node: \"+B+\"\\n\"+e);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t//replace the old disconnect method\n\t\tfunction toneDisconnect(B, outNum, inNum){\n\t\t\tif (B && B.input && Array.isArray(B.input)){\n\t\t\t\tif (Tone.prototype.isUndef(inNum)){\n\t\t\t\t\tinNum = 0;\n\t\t\t\t}\n\t\t\t\tthis.disconnect(B.input[inNum], outNum, inNum);\n\t\t\t} else if (B && B.input){\n\t\t\t\tthis.disconnect(B.input, outNum, inNum);\n\t\t\t} else {\n\t\t\t\ttry {\n\t\t\t\t\tnativeDisconnect.apply(this, arguments);\n\t\t\t\t} catch (e) {\n\t\t\t\t\tthrow new Error(\"error disconnecting node: \"+B+\"\\n\"+e);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tif (AudioNode.prototype.connect !== toneConnect){\n\t\t\tAudioNode.prototype.connect = toneConnect;\n\t\t\tAudioNode.prototype.disconnect = toneDisconnect;\n\t\t}\n\t}\n\n\t// set the audio context initially\n\tif (Tone.supported){\n\t\tshimConnect();\n\t\tTone.context = new Tone.Context();\n\t} else {\n\t\tconsole.warn(\"This browser does not support Tone.js\");\n\t}\n\n\treturn Tone.Context;\n});","define([\"Tone/core/Tone\", \"Tone/signal/Add\", \"Tone/signal/Multiply\", \"Tone/signal/Signal\"], function(Tone){\n\n\t\"use strict\";\n\t\n\t/**\n\t * @class Performs a linear scaling on an input signal.\n\t * Scales a NormalRange input to between\n\t * outputMin and outputMax.\n\t *\n\t * @constructor\n\t * @extends {Tone.SignalBase}\n\t * @param {number} [outputMin=0] The output value when the input is 0. \n\t * @param {number} [outputMax=1]\tThe output value when the input is 1. \n\t * @example\n\t * var scale = new Tone.Scale(50, 100);\n\t * var signal = new Tone.Signal(0.5).connect(scale);\n\t * //the output of scale equals 75\n\t */\n\tTone.Scale = function(outputMin, outputMax){\n\n\t\t/** \n\t\t * @private\n\t\t * @type {number}\n\t\t */\n\t\tthis._outputMin = this.defaultArg(outputMin, 0);\n\n\t\t/** \n\t\t * @private\n\t\t * @type {number}\n\t\t */\n\t\tthis._outputMax = this.defaultArg(outputMax, 1);\n\n\n\t\t/** \n\t\t * @private\n\t\t * @type {Tone.Multiply}\n\t\t * @private\n\t\t */\n\t\tthis._scale = this.input = new Tone.Multiply(1);\n\t\t\n\t\t/** \n\t\t * @private\n\t\t * @type {Tone.Add}\n\t\t * @private\n\t\t */\n\t\tthis._add = this.output = new Tone.Add(0);\n\n\t\tthis._scale.connect(this._add);\n\t\tthis._setRange();\n\t};\n\n\tTone.extend(Tone.Scale, Tone.SignalBase);\n\n\t/**\n\t * The minimum output value. This number is output when \n\t * the value input value is 0. \n\t * @memberOf Tone.Scale#\n\t * @type {number}\n\t * @name min\n\t */\n\tObject.defineProperty(Tone.Scale.prototype, \"min\", {\n\t\tget : function(){\n\t\t\treturn this._outputMin;\n\t\t},\n\t\tset : function(min){\n\t\t\tthis._outputMin = min;\n\t\t\tthis._setRange();\n\t\t}\n\t});\n\n\t/**\n\t * The maximum output value. This number is output when \n\t * the value input value is 1. \n\t * @memberOf Tone.Scale#\n\t * @type {number}\n\t * @name max\n\t */\n\tObject.defineProperty(Tone.Scale.prototype, \"max\", {\n\t\tget : function(){\n\t\t\treturn this._outputMax;\n\t\t},\n\t\tset : function(max){\n\t\t\tthis._outputMax = max;\n\t\t\tthis._setRange();\n\t\t}\n\t});\n\n\t/**\n\t * set the values\n\t * @private\n\t */\n\tTone.Scale.prototype._setRange = function() {\n\t\tthis._add.value = this._outputMin;\n\t\tthis._scale.value = this._outputMax - this._outputMin;\n\t};\n\n\t/**\n\t * Clean up.\n\t * @returns {Tone.Scale} this\n\t */\n\tTone.Scale.prototype.dispose = function(){\n\t\tTone.prototype.dispose.call(this);\n\t\tthis._add.dispose();\n\t\tthis._add = null;\n\t\tthis._scale.dispose();\n\t\tthis._scale = null;\n\t\treturn this;\n\t}; \n\n\treturn Tone.Scale;\n});\n","define([\"Tone/core/Tone\", \"Tone/signal/Signal\", \"Tone/core/Timeline\"], function (Tone) {\n\n\t\"use strict\";\n\n\t/**\n\t * @class A signal which adds the method getValueAtTime. \n\t * Code and inspiration from https://github.com/jsantell/web-audio-automation-timeline\n\t * @extends {Tone.Param}\n\t * @param {Number=} value The initial value of the signal\n\t * @param {String=} units The conversion units of the signal.\n\t */\n\tTone.TimelineSignal = function(){\n\n\t\tvar options = this.optionsObject(arguments, [\"value\", \"units\"], Tone.Signal.defaults);\n\t\t\n\t\t/**\n\t\t * The scheduled events\n\t\t * @type {Tone.Timeline}\n\t\t * @private\n\t\t */\n\t\tthis._events = new Tone.Timeline(10);\n\n\t\t//constructors\n\t\tTone.Signal.apply(this, options);\n\t\toptions.param = this._param;\n\t\tTone.Param.call(this, options);\n\n\t\t/**\n\t\t * The initial scheduled value\n\t\t * @type {Number}\n\t\t * @private\n\t\t */\n\t\tthis._initial = this._fromUnits(this._param.value);\n\t};\n\n\tTone.extend(Tone.TimelineSignal, Tone.Param);\n\n\t/**\n\t * The event types of a schedulable signal.\n\t * @enum {String}\n\t * @private\n\t */\n\tTone.TimelineSignal.Type = {\n\t\tLinear : \"linear\",\n\t\tExponential : \"exponential\",\n\t\tTarget : \"target\",\n\t\tCurve : \"curve\",\n\t\tSet : \"set\"\n\t};\n\n\t/**\n\t * The current value of the signal. \n\t * @memberOf Tone.TimelineSignal#\n\t * @type {Number}\n\t * @name value\n\t */\n\tObject.defineProperty(Tone.TimelineSignal.prototype, \"value\", {\n\t\tget : function(){\n\t\t\tvar now = this.now();\n\t\t\tvar val = this.getValueAtTime(now);\n\t\t\treturn this._toUnits(val);\n\t\t},\n\t\tset : function(value){\n\t\t\tvar convertedVal = this._fromUnits(value);\n\t\t\tthis._initial = convertedVal;\n\t\t\tthis.cancelScheduledValues();\n\t\t\tthis._param.value = convertedVal;\n\t\t}\n\t});\n\n\t///////////////////////////////////////////////////////////////////////////\n\t//\tSCHEDULING\n\t///////////////////////////////////////////////////////////////////////////\n\n\t/**\n\t * Schedules a parameter value change at the given time.\n\t * @param {*}\tvalue The value to set the signal.\n\t * @param {Time} time The time when the change should occur.\n\t * @returns {Tone.TimelineSignal} this\n\t * @example\n\t * //set the frequency to \"G4\" in exactly 1 second from now. \n\t * freq.setValueAtTime(\"G4\", \"+1\");\n\t */\n\tTone.TimelineSignal.prototype.setValueAtTime = function (value, startTime) {\n\t\tvalue = this._fromUnits(value);\n\t\tstartTime = this.toSeconds(startTime);\n\t\tthis._events.add({\n\t\t\t\"type\" : Tone.TimelineSignal.Type.Set,\n\t\t\t\"value\" : value,\n\t\t\t\"time\" : startTime\n\t\t});\n\t\t//invoke the original event\n\t\tthis._param.setValueAtTime(value, startTime);\n\t\treturn this;\n\t};\n\n\t/**\n\t * Schedules a linear continuous change in parameter value from the \n\t * previous scheduled parameter value to the given value.\n\t * \n\t * @param {number} value \n\t * @param {Time} endTime \n\t * @returns {Tone.TimelineSignal} this\n\t */\n\tTone.TimelineSignal.prototype.linearRampToValueAtTime = function (value, endTime) {\n\t\tvalue = this._fromUnits(value);\n\t\tendTime = this.toSeconds(endTime);\n\t\tthis._events.add({\n\t\t\t\"type\" : Tone.TimelineSignal.Type.Linear,\n\t\t\t\"value\" : value,\n\t\t\t\"time\" : endTime\n\t\t});\n\t\tthis._param.linearRampToValueAtTime(value, endTime);\n\t\treturn this;\n\t};\n\n\t/**\n\t * Schedules an exponential continuous change in parameter value from \n\t * the previous scheduled parameter value to the given value.\n\t * \n\t * @param {number} value \n\t * @param {Time} endTime \n\t * @returns {Tone.TimelineSignal} this\n\t */\n\tTone.TimelineSignal.prototype.exponentialRampToValueAtTime = function (value, endTime) {\n\t\t//get the previous event and make sure it's not starting from 0\n\t\tendTime = this.toSeconds(endTime);\n\t\tvar beforeEvent = this._searchBefore(endTime);\n\t\tif (beforeEvent && beforeEvent.value === 0){\n\t\t\t//reschedule that event\n\t\t\tthis.setValueAtTime(this._minOutput, beforeEvent.time);\n\t\t}\n\t\tvalue = this._fromUnits(value);\n\t\tvar setValue = Math.max(value, this._minOutput);\n\t\tthis._events.add({\n\t\t\t\"type\" : Tone.TimelineSignal.Type.Exponential,\n\t\t\t\"value\" : setValue,\n\t\t\t\"time\" : endTime\n\t\t});\n\t\t//if the ramped to value is 0, make it go to the min output, and then set to 0.\n\t\tif (value < this._minOutput){\n\t\t\tthis._param.exponentialRampToValueAtTime(this._minOutput, endTime - this.sampleTime);\n\t\t\tthis.setValueAtTime(0, endTime);\n\t\t} else {\n\t\t\tthis._param.exponentialRampToValueAtTime(value, endTime);\n\t\t}\n\t\treturn this;\n\t};\n\n\t/**\n\t * Start exponentially approaching the target value at the given time with\n\t * a rate having the given time constant.\n\t * @param {number} value \n\t * @param {Time} startTime \n\t * @param {number} timeConstant \n\t * @returns {Tone.TimelineSignal} this \n\t */\n\tTone.TimelineSignal.prototype.setTargetAtTime = function (value, startTime, timeConstant) {\n\t\tvalue = this._fromUnits(value);\n\t\tvalue = Math.max(this._minOutput, value);\n\t\ttimeConstant = Math.max(this._minOutput, timeConstant);\n\t\tstartTime = this.toSeconds(startTime);\n\t\tthis._events.add({\n\t\t\t\"type\" : Tone.TimelineSignal.Type.Target,\n\t\t\t\"value\" : value,\n\t\t\t\"time\" : startTime,\n\t\t\t\"constant\" : timeConstant\n\t\t});\n\t\tthis._param.setTargetAtTime(value, startTime, timeConstant);\n\t\treturn this;\n\t};\n\n\t/**\n\t * Set an array of arbitrary values starting at the given time for the given duration.\n\t * @param {Float32Array} values \n\t * @param {Time} startTime \n\t * @param {Time} duration\n\t * @param {NormalRange} [scaling=1] If the values in the curve should be scaled by some value\n\t * @returns {Tone.TimelineSignal} this \n\t */\n\tTone.TimelineSignal.prototype.setValueCurveAtTime = function (values, startTime, duration, scaling) {\n\t\tscaling = this.defaultArg(scaling, 1);\n\t\t//copy the array\n\t\tvar floats = new Array(values.length);\n\t\tfor (var i = 0; i < floats.length; i++){\n\t\t\tfloats[i] = this._fromUnits(values[i]) * scaling;\n\t\t}\n\t\tstartTime = this.toSeconds(startTime);\n\t\tduration = this.toSeconds(duration);\n\t\tthis._events.add({\n\t\t\t\"type\" : Tone.TimelineSignal.Type.Curve,\n\t\t\t\"value\" : floats,\n\t\t\t\"time\" : startTime,\n\t\t\t\"duration\" : duration\n\t\t});\n\t\t//set the first value\n\t\tthis._param.setValueAtTime(floats[0], startTime);\n\t\t//schedule a lienar ramp for each of the segments\n\t\tfor (var j = 1; j < floats.length; j++){\n\t\t\tvar segmentTime = startTime + (j / (floats.length - 1) * duration);\n\t\t\tthis._param.linearRampToValueAtTime(floats[j], segmentTime);\n\t\t}\n\t\treturn this;\n\t};\n\n\t/**\n\t * Cancels all scheduled parameter changes with times greater than or \n\t * equal to startTime.\n\t * \n\t * @param {Time} startTime\n\t * @returns {Tone.TimelineSignal} this\n\t */\n\tTone.TimelineSignal.prototype.cancelScheduledValues = function (after) {\n\t\tafter = this.toSeconds(after);\n\t\tthis._events.cancel(after);\n\t\tthis._param.cancelScheduledValues(after);\n\t\treturn this;\n\t};\n\n\t/**\n\t * Sets the computed value at the given time. This provides\n\t * a point from which a linear or exponential curve\n\t * can be scheduled after. Will cancel events after \n\t * the given time and shorten the currently scheduled\n\t * linear or exponential ramp so that it ends at `time` .\n\t * This is to avoid discontinuities and clicks in envelopes. \n\t * @param {Time} time When to set the ramp point\n\t * @returns {Tone.TimelineSignal} this\n\t */\n\tTone.TimelineSignal.prototype.setRampPoint = function (time) {\n\t\ttime = this.toSeconds(time);\n\t\t//get the value at the given time\n\t\tvar val = this._toUnits(this.getValueAtTime(time));\n\t\t//if there is an event at the given time\n\t\t//and that even is not a \"set\"\n\t\tvar before = this._searchBefore(time);\n\t\tif (before && before.time === time){\n\t\t\t//remove everything after\n\t\t\tthis.cancelScheduledValues(time + this.sampleTime);\n\t\t} else if (before && \n\t\t\t\t before.type === Tone.TimelineSignal.Type.Curve &&\n\t\t\t\t before.time + before.duration > time){\n\t\t\t//if the curve is still playing\n\t\t\t//cancel the curve\n\t\t\tthis.cancelScheduledValues(time);\n\t\t\tthis.linearRampToValueAtTime(val, time);\n\t\t} else {\n\t\t\t//reschedule the next event to end at the given time\n\t\t\tvar after = this._searchAfter(time);\n\t\t\tif (after){\n\t\t\t\t//cancel the next event(s)\n\t\t\t\tthis.cancelScheduledValues(time);\n\t\t\t\tif (after.type === Tone.TimelineSignal.Type.Linear){\n\t\t\t\t\tthis.linearRampToValueAtTime(val, time);\n\t\t\t\t} else if (after.type === Tone.TimelineSignal.Type.Exponential){\n\t\t\t\t\tthis.exponentialRampToValueAtTime(val, time);\n\t\t\t\t}\n\t\t\t}\n\t\t\tthis.setValueAtTime(val, time);\n\t\t}\n\t\treturn this;\n\t};\n\n\t/**\n\t * Do a linear ramp to the given value between the start and finish times.\n\t * @param {Number} value The value to ramp to.\n\t * @param {Time} start The beginning anchor point to do the linear ramp\n\t * @param {Time} finish The ending anchor point by which the value of\n\t * the signal will equal the given value.\n\t * @returns {Tone.TimelineSignal} this\n\t */\n\tTone.TimelineSignal.prototype.linearRampToValueBetween = function (value, start, finish) {\n\t\tthis.setRampPoint(start);\n\t\tthis.linearRampToValueAtTime(value, finish);\n\t\treturn this;\n\t};\n\n\t/**\n\t * Do a exponential ramp to the given value between the start and finish times.\n\t * @param {Number} value The value to ramp to.\n\t * @param {Time} start The beginning anchor point to do the exponential ramp\n\t * @param {Time} finish The ending anchor point by which the value of\n\t * the signal will equal the given value.\n\t * @returns {Tone.TimelineSignal} this\n\t */\n\tTone.TimelineSignal.prototype.exponentialRampToValueBetween = function (value, start, finish) {\n\t\tthis.setRampPoint(start);\n\t\tthis.exponentialRampToValueAtTime(value, finish);\n\t\treturn this;\n\t};\n\n\t///////////////////////////////////////////////////////////////////////////\n\t//\tGETTING SCHEDULED VALUES\n\t///////////////////////////////////////////////////////////////////////////\n\n\t/**\n\t * Returns the value before or equal to the given time\n\t * @param {Number} time The time to query\n\t * @return {Object} The event at or before the given time.\n\t * @private\n\t */\n\tTone.TimelineSignal.prototype._searchBefore = function(time){\n\t\treturn this._events.get(time);\n\t};\n\n\t/**\n\t * The event after the given time\n\t * @param {Number} time The time to query.\n\t * @return {Object} The next event after the given time\n\t * @private\n\t */\n\tTone.TimelineSignal.prototype._searchAfter = function(time){\n\t\treturn this._events.getAfter(time);\n\t};\n\n\t/**\n\t * Get the scheduled value at the given time. This will\n\t * return the unconverted (raw) value.\n\t * @param {Number} time The time in seconds.\n\t * @return {Number} The scheduled value at the given time.\n\t */\n\tTone.TimelineSignal.prototype.getValueAtTime = function(time){\n\t\ttime = this.toSeconds(time);\n\t\tvar after = this._searchAfter(time);\n\t\tvar before = this._searchBefore(time);\n\t\tvar value = this._initial;\n\t\t//if it was set by\n\t\tif (before === null){\n\t\t\tvalue = this._initial;\n\t\t} else if (before.type === Tone.TimelineSignal.Type.Target){\n\t\t\tvar previous = this._events.getBefore(before.time);\n\t\t\tvar previouVal;\n\t\t\tif (previous === null){\n\t\t\t\tpreviouVal = this._initial;\n\t\t\t} else {\n\t\t\t\tpreviouVal = previous.value;\n\t\t\t}\n\t\t\tvalue = this._exponentialApproach(before.time, previouVal, before.value, before.constant, time);\n\t\t} else if (before.type === Tone.TimelineSignal.Type.Curve){\n\t\t\tvalue = this._curveInterpolate(before.time, before.value, before.duration, time);\n\t\t} else if (after === null){\n\t\t\tvalue = before.value;\n\t\t} else if (after.type === Tone.TimelineSignal.Type.Linear){\n\t\t\tvalue = this._linearInterpolate(before.time, before.value, after.time, after.value, time);\n\t\t} else if (after.type === Tone.TimelineSignal.Type.Exponential){\n\t\t\tvalue = this._exponentialInterpolate(before.time, before.value, after.time, after.value, time);\n\t\t} else {\n\t\t\tvalue = before.value;\n\t\t}\n\t\treturn value;\n\t};\n\n\t/**\n\t * When signals connect to other signals or AudioParams, \n\t * they take over the output value of that signal or AudioParam. \n\t * For all other nodes, the behavior is the same as a default connect. \n\t *\n\t * @override\n\t * @param {AudioParam|AudioNode|Tone.Signal|Tone} node \n\t * @param {number} [outputNumber=0] The output number to connect from.\n\t * @param {number} [inputNumber=0] The input number to connect to.\n\t * @returns {Tone.TimelineSignal} this\n\t * @method\n\t */\n\tTone.TimelineSignal.prototype.connect = Tone.SignalBase.prototype.connect;\n\n\n\t///////////////////////////////////////////////////////////////////////////\n\t//\tAUTOMATION CURVE CALCULATIONS\n\t//\tMIT License, copyright (c) 2014 Jordan Santell\n\t///////////////////////////////////////////////////////////////////////////\n\n\t/**\n\t * Calculates the the value along the curve produced by setTargetAtTime\n\t * @private\n\t */\n\tTone.TimelineSignal.prototype._exponentialApproach = function (t0, v0, v1, timeConstant, t) {\n\t\treturn v1 + (v0 - v1) * Math.exp(-(t - t0) / timeConstant);\n\t};\n\n\t/**\n\t * Calculates the the value along the curve produced by linearRampToValueAtTime\n\t * @private\n\t */\n\tTone.TimelineSignal.prototype._linearInterpolate = function (t0, v0, t1, v1, t) {\n\t\treturn v0 + (v1 - v0) * ((t - t0) / (t1 - t0));\n\t};\n\n\t/**\n\t * Calculates the the value along the curve produced by exponentialRampToValueAtTime\n\t * @private\n\t */\n\tTone.TimelineSignal.prototype._exponentialInterpolate = function (t0, v0, t1, v1, t) {\n\t\tv0 = Math.max(this._minOutput, v0);\n\t\treturn v0 * Math.pow(v1 / v0, (t - t0) / (t1 - t0));\n\t};\n\n\t/**\n\t * Calculates the the value along the curve produced by setValueCurveAtTime\n\t * @private\n\t */\n\tTone.TimelineSignal.prototype._curveInterpolate = function (start, curve, duration, time) {\n\t\tvar len = curve.length;\n\t\t// If time is after duration, return the last curve value\n\t\tif (time >= start + duration) {\n\t\t\treturn curve[len - 1];\n\t\t} else if (time <= start){\n\t\t\treturn curve[0];\n\t\t} else {\n\t\t\tvar progress = (time - start) / duration;\n\t\t\tvar lowerIndex = Math.floor((len - 1) * progress);\n\t\t\tvar upperIndex = Math.ceil((len - 1) * progress);\n\t\t\tvar lowerVal = curve[lowerIndex];\n\t\t\tvar upperVal = curve[upperIndex];\n\t\t\tif (upperIndex === lowerIndex){\n\t\t\t\treturn lowerVal;\n\t\t\t} else {\n\t\t\t\treturn this._linearInterpolate(lowerIndex, lowerVal, upperIndex, upperVal, progress * (len - 1));\n\t\t\t}\n\t\t}\n\t};\n\n\t/**\n\t * Clean up.\n\t * @return {Tone.TimelineSignal} this\n\t */\n\tTone.TimelineSignal.prototype.dispose = function(){\n\t\tTone.Signal.prototype.dispose.call(this);\n\t\tTone.Param.prototype.dispose.call(this);\n\t\tthis._events.dispose();\n\t\tthis._events = null;\n\t};\n\n\treturn Tone.TimelineSignal;\n});","'use strict';\r\n\r\ndefine(function (require) {\r\n var Effect = require('effect');\r\n\r\n /**\r\n *
A p5.Filter uses a Web Audio Biquad Filter to filter\r\n * the frequency response of an input source. Subclasses\r\n * include:
\r\n * p5.LowPass:\r\n * Allows frequencies below the cutoff frequency to pass through,\r\n * and attenuates frequencies above the cutoff. \r\n * p5.HighPass:\r\n * The opposite of a lowpass filter. \r\n * p5.BandPass:\r\n * Allows a range of frequencies to pass through and attenuates\r\n * the frequencies below and above this frequency range. \r\n *\r\n * The .res() method controls either width of the\r\n * bandpass, or resonance of the low/highpass cutoff frequency.\r\n *\r\n * This class extends p5.Effect.\r\n * Methods amp(), chain(),\r\n * drywet(), connect(), and\r\n * disconnect() are available.\r\n *\r\n * @class p5.Filter\r\n * @extends p5.Effect\r\n * @constructor\r\n * @param {String} [type] 'lowpass' (default), 'highpass', 'bandpass'\r\n * @example\r\n *
\r\n * var fft, noise, filter;\r\n *\r\n * function setup() {\r\n * fill(255, 40, 255);\r\n *\r\n * filter = new p5.BandPass();\r\n *\r\n * noise = new p5.Noise();\r\n * // disconnect unfiltered noise,\r\n * // and connect to filter\r\n * noise.disconnect();\r\n * noise.connect(filter);\r\n * noise.start();\r\n *\r\n * fft = new p5.FFT();\r\n * }\r\n *\r\n * function draw() {\r\n * background(30);\r\n *\r\n * // set the BandPass frequency based on mouseX\r\n * var freq = map(mouseX, 0, width, 20, 10000);\r\n * filter.freq(freq);\r\n * // give the filter a narrow band (lower res = wider bandpass)\r\n * filter.res(50);\r\n *\r\n * // draw filtered spectrum\r\n * var spectrum = fft.analyze();\r\n * noStroke();\r\n * for (var i = 0; i < spectrum.length; i++) {\r\n * var x = map(i, 0, spectrum.length, 0, width);\r\n * var h = -height + map(spectrum[i], 0, 255, height, 0);\r\n * rect(x, height, width/spectrum.length, h);\r\n * }\r\n *\r\n * isMouseOverCanvas();\r\n * }\r\n *\r\n * function isMouseOverCanvas() {\r\n * var mX = mouseX, mY = mouseY;\r\n * if (mX > 0 && mX < width && mY < height && mY > 0) {\r\n * noise.amp(0.5, 0.2);\r\n * } else {\r\n * noise.amp(0, 0.2);\r\n * }\r\n * }\r\n *
\r\n */\r\n p5.Filter = function (type) {\r\n\r\n Effect.call(this);\r\n //add extend Effect by adding a Biquad Filter\r\n\r\n /**\r\n * The p5.Filter is built with a\r\n * \r\n * Web Audio BiquadFilter Node.\r\n *\r\n * @property {DelayNode} biquadFilter\r\n\t */\r\n\r\n this.biquad = this.ac.createBiquadFilter();\r\n\r\n this.input.connect(this.biquad);\r\n\r\n this.biquad.connect(this.wet);\r\n\r\n if (type) {\r\n this.setType(type);\r\n }\r\n\r\n //Properties useful for the toggle method.\r\n this._on = true;\r\n this._untoggledType = this.biquad.type;\r\n };\r\n p5.Filter.prototype = Object.create(Effect.prototype);\r\n\r\n\r\n /**\r\n * Filter an audio signal according to a set\r\n * of filter parameters.\r\n *\r\n * @method process\r\n * @param {Object} Signal An object that outputs audio\r\n * @param {Number} [freq] Frequency in Hz, from 10 to 22050\r\n * @param {Number} [res] Resonance/Width of the filter frequency\r\n * from 0.001 to 1000\r\n */\r\n p5.Filter.prototype.process = function(src, freq, res, time) {\r\n src.connect(this.input);\r\n this.set(freq, res, time);\r\n };\r\n\r\n\r\n /**\r\n * Set the frequency and the resonance of the filter.\r\n *\r\n * @method set\r\n * @param {Number} [freq] Frequency in Hz, from 10 to 22050\r\n * @param {Number} [res] Resonance (Q) from 0.001 to 1000\r\n * @param {Number} [timeFromNow] schedule this event to happen\r\n * seconds from now\r\n */\r\n p5.Filter.prototype.set = function(freq, res, time) {\r\n if (freq) {\r\n this.freq(freq, time);\r\n }\r\n if (res) {\r\n this.res(res, time);\r\n }\r\n };\r\n\r\n /**\r\n * Set the filter frequency, in Hz, from 10 to 22050 (the range of\r\n * human hearing, although in reality most people hear in a narrower\r\n * range).\r\n *\r\n * @method freq\r\n * @param {Number} freq Filter Frequency\r\n * @param {Number} [timeFromNow] schedule this event to happen\r\n * seconds from now\r\n * @return {Number} value Returns the current frequency value\r\n */\r\n p5.Filter.prototype.freq = function(freq, time) {\r\n var t = time || 0;\r\n if (freq <= 0) {\r\n freq = 1;\r\n }\r\n if (typeof freq === 'number') {\r\n this.biquad.frequency.cancelScheduledValues(this.ac.currentTime + 0.01 + t);\r\n this.biquad.frequency.exponentialRampToValueAtTime(freq, this.ac.currentTime + 0.02 + t);\r\n } else if (freq) {\r\n freq.connect(this.biquad.frequency);\r\n }\r\n return this.biquad.frequency.value;\r\n };\r\n\r\n /**\r\n * Controls either width of a bandpass frequency,\r\n * or the resonance of a low/highpass cutoff frequency.\r\n *\r\n * @method res\r\n * @param {Number} res Resonance/Width of filter freq\r\n * from 0.001 to 1000\r\n * @param {Number} [timeFromNow] schedule this event to happen\r\n * seconds from now\r\n * @return {Number} value Returns the current res value\r\n */\r\n p5.Filter.prototype.res = function(res, time) {\r\n var t = time || 0;\r\n if (typeof res === 'number') {\r\n this.biquad.Q.value = res;\r\n this.biquad.Q.cancelScheduledValues(this.ac.currentTime + 0.01 + t);\r\n this.biquad.Q.linearRampToValueAtTime(res, this.ac.currentTime + 0.02 + t);\r\n } else if (res) {\r\n res.connect(this.biquad.Q);\r\n }\r\n return this.biquad.Q.value;\r\n };\r\n\r\n /**\r\n * Controls the gain attribute of a Biquad Filter.\r\n * This is distinctly different from .amp() which is inherited from p5.Effect\r\n * .amp() controls the volume via the output gain node\r\n * p5.Filter.gain() controls the gain parameter of a Biquad Filter node.\r\n *\r\n * @method gain\r\n * @param {Number} gain\r\n * @return {Number} Returns the current or updated gain value\r\n */\r\n p5.Filter.prototype.gain = function(gain, time) {\r\n var t = time || 0;\r\n if (typeof gain === 'number') {\r\n this.biquad.gain.value = gain;\r\n this.biquad.gain.cancelScheduledValues(this.ac.currentTime + 0.01 + t);\r\n this.biquad.gain.linearRampToValueAtTime(gain, this.ac.currentTime + 0.02 + t);\r\n } else if (gain) {\r\n gain.connect(this.biquad.gain);\r\n }\r\n return this.biquad.gain.value;\r\n };\r\n\r\n\r\n /**\r\n * Toggle function. Switches between the specified type and allpass\r\n *\r\n * @method toggle\r\n * @return {boolean} [Toggle value]\r\n */\r\n p5.Filter.prototype.toggle = function() {\r\n this._on = !this._on;\r\n\r\n if (this._on === true) {\r\n this.biquad.type = this._untoggledType;\r\n } else if (this._on === false) {\r\n this.biquad.type = 'allpass';\r\n }\r\n\r\n return this._on;\r\n };\r\n\r\n /**\r\n * Set the type of a p5.Filter. Possible types include:\r\n * \"lowpass\" (default), \"highpass\", \"bandpass\",\r\n * \"lowshelf\", \"highshelf\", \"peaking\", \"notch\",\r\n * \"allpass\".\r\n *\r\n * @method setType\r\n * @param {String} t\r\n */\r\n p5.Filter.prototype.setType = function(t) {\r\n this.biquad.type = t;\r\n this._untoggledType = this.biquad.type;\r\n };\r\n\r\n p5.Filter.prototype.dispose = function() {\r\n // remove reference from soundArray\r\n Effect.prototype.dispose.apply(this);\r\n if (this.biquad) {\r\n this.biquad.disconnect();\r\n delete this.biquad;\r\n }\r\n };\r\n\r\n /**\r\n * Constructor: new p5.LowPass() Filter.\r\n * This is the same as creating a p5.Filter and then calling\r\n * its method setType('lowpass').\r\n * See p5.Filter for methods.\r\n *\r\n * @class p5.LowPass\r\n * @constructor\r\n * @extends p5.Filter\r\n */\r\n p5.LowPass = function() {\r\n p5.Filter.call(this, 'lowpass');\r\n };\r\n p5.LowPass.prototype = Object.create(p5.Filter.prototype);\r\n\r\n /**\r\n * Constructor: new p5.HighPass() Filter.\r\n * This is the same as creating a p5.Filter and then calling\r\n * its method setType('highpass').\r\n * See p5.Filter for methods.\r\n *\r\n * @class p5.HighPass\r\n * @constructor\r\n * @extends p5.Filter\r\n */\r\n p5.HighPass = function() {\r\n p5.Filter.call(this, 'highpass');\r\n };\r\n p5.HighPass.prototype = Object.create(p5.Filter.prototype);\r\n\r\n /**\r\n * Constructor: new p5.BandPass() Filter.\r\n * This is the same as creating a p5.Filter and then calling\r\n * its method setType('bandpass').\r\n * See p5.Filter for methods.\r\n *\r\n * @class p5.BandPass\r\n * @constructor\r\n * @extends p5.Filter\r\n */\r\n p5.BandPass = function() {\r\n p5.Filter.call(this, 'bandpass');\r\n };\r\n p5.BandPass.prototype = Object.create(p5.Filter.prototype);\r\n\r\n return p5.Filter;\r\n});\r\n","define([\"Tone/core/Tone\", \"Tone/signal/Add\", \"Tone/signal/Negate\", \"Tone/signal/Signal\", \"Tone/core/Gain\"], function(Tone){\n\n\t\"use strict\";\n\n\t/**\n\t * @class Subtract the signal connected to input[1] from the signal connected \n\t * to input[0]. If an argument is provided in the constructor, the \n\t * signals .value will be subtracted from the incoming signal.\n\t *\n\t * @extends {Tone.Signal}\n\t * @constructor\n\t * @param {number=} value The value to subtract from the incoming signal. If the value\n\t * is omitted, it will subtract the second signal from the first.\n\t * @example\n\t * var sub = new Tone.Subtract(1);\n\t * var sig = new Tone.Signal(4).connect(sub);\n\t * //the output of sub is 3. \n\t * @example\n\t * var sub = new Tone.Subtract();\n\t * var sigA = new Tone.Signal(10);\n\t * var sigB = new Tone.Signal(2.5);\n\t * sigA.connect(sub, 0, 0);\n\t * sigB.connect(sub, 0, 1);\n\t * //output of sub is 7.5\n\t */\n\tTone.Subtract = function(value){\n\n\t\tthis.createInsOuts(2, 0);\n\n\t\t/**\n\t\t * the summing node\n\t\t * @type {GainNode}\n\t\t * @private\n\t\t */\n\t\tthis._sum = this.input[0] = this.output = new Tone.Gain();\n\n\t\t/**\n\t\t * negate the input of the second input before connecting it\n\t\t * to the summing node.\n\t\t * @type {Tone.Negate}\n\t\t * @private\n\t\t */\n\t\tthis._neg = new Tone.Negate();\n\n\t\t/**\n\t\t * the node where the value is set\n\t\t * @private\n\t\t * @type {Tone.Signal}\n\t\t */\n\t\tthis._param = this.input[1] = new Tone.Signal(value);\n\n\t\tthis._param.chain(this._neg, this._sum);\n\t};\n\n\tTone.extend(Tone.Subtract, Tone.Signal);\n\n\t/**\n\t * Clean up.\n\t * @returns {Tone.SignalBase} this\n\t */\n\tTone.Subtract.prototype.dispose = function(){\n\t\tTone.prototype.dispose.call(this);\n\t\tthis._neg.dispose();\n\t\tthis._neg = null;\n\t\tthis._sum.disconnect();\n\t\tthis._sum = null;\n\t\tthis._param.dispose();\n\t\tthis._param = null;\n\t\treturn this;\n\t};\n\n\treturn Tone.Subtract;\n});","'use strict';\r\n\r\nglobal.TONE_SILENCE_VERSION_LOGGING = true;\r\n\r\ndefine(['startaudiocontext', 'Tone/core/Context', 'Tone/core/Tone'], function (StartAudioContext, Context, Tone) {\r\n // Create the Audio Context\r\n const audiocontext = new window.AudioContext();\r\n\r\n // Tone and p5.sound share the same audio context\r\n Tone.context.dispose();\r\n Tone.setContext(audiocontext);\r\n\r\n /**\r\n *
Returns the Audio Context for this sketch. Useful for users\r\n * who would like to dig deeper into the Web Audio API\r\n * .
\r\n *\r\n *
Some browsers require users to startAudioContext\r\n * with a user gesture, such as touchStarted in the example below.
\r\n *\r\n * @method getAudioContext\r\n * @return {Object} AudioContext for this sketch\r\n * @example\r\n *
\r\n * function draw() {\r\n * background(255);\r\n * textAlign(CENTER);\r\n *\r\n * if (getAudioContext().state !== 'running') {\r\n * text('click to start audio', width/2, height/2);\r\n * } else {\r\n * text('audio is enabled', width/2, height/2);\r\n * }\r\n * }\r\n *\r\n * function touchStarted() {\r\n * if (getAudioContext().state !== 'running') {\r\n * getAudioContext().resume();\r\n * }\r\n * var synth = new p5.MonoSynth();\r\n * synth.play('A4', 0.5, 0, 0.2);\r\n * }\r\n *\r\n *
It is a good practice to give users control over starting audio playback.\r\n * This practice is enforced by Google Chrome's autoplay policy as of r70\r\n * (info), iOS Safari, and other browsers.\r\n *
\r\n *\r\n *
\r\n * userStartAudio() starts the Audio Context on a user gesture. It utilizes\r\n * the StartAudioContext library by\r\n * Yotam Mann (MIT Licence, 2016). Read more at https://github.com/tambien/StartAudioContext.\r\n *
\r\n *\r\n *
Starting the audio context on a user gesture can be as simple as userStartAudio().\r\n * Optional parameters let you decide on a specific element that will start the audio context,\r\n * and/or call a function once the audio context is started.
\r\n * @param {Element|Array} [element(s)] This argument can be an Element,\r\n * Selector String, NodeList, p5.Element,\r\n * jQuery Element, or an Array of any of those.\r\n * @param {Function} [callback] Callback to invoke when the AudioContext has started\r\n * @return {Promise} Returns a Promise which is resolved when\r\n * the AudioContext state is 'running'\r\n * @method userStartAudio\r\n * @for p5\r\n * @example\r\n *
\r\n * function setup() {\r\n * var myDiv = createDiv('click to start audio');\r\n * myDiv.position(0, 0);\r\n *\r\n * var mySynth = new p5.MonoSynth();\r\n *\r\n * // This won't play until the context has started\r\n * mySynth.play('A6');\r\n *\r\n * // Start the audio context on a click/touch event\r\n * userStartAudio().then(function() {\r\n * myDiv.remove();\r\n * });\r\n * }\r\n *
\r\n */\r\n p5.prototype.userStartAudio = function(elements, callback) {\r\n var elt = elements;\r\n if (elements instanceof p5.Element) {\r\n elt = elements.elt;\r\n } else if (elements instanceof Array && elements[0] instanceof p5.Element ) {\r\n elt = elements.map(function(e) { return e.elt});\r\n }\r\n return StartAudioContext(audiocontext, elt, callback);\r\n };\r\n\r\n return audiocontext;\r\n});\r\n","define([\"Tone/core/Tone\"], function (Tone) {\n\n\t\"use strict\";\n\n\t/**\n\t * @class Tone.Emitter gives classes which extend it\n\t * the ability to listen for and emit events. \n\t * Inspiration and reference from Jerome Etienne's [MicroEvent](https://github.com/jeromeetienne/microevent.js).\n\t * MIT (c) 2011 Jerome Etienne.\n\t * \n\t * @extends {Tone}\n\t */\n\tTone.Emitter = function(){\n\t\t/**\n\t\t * Contains all of the events.\n\t\t * @private\n\t\t * @type {Object}\n\t\t */\n\t\tthis._events = {};\n\t};\n\n\tTone.extend(Tone.Emitter);\n\n\t/**\n\t * Bind a callback to a specific event.\n\t * @param {String} event The name of the event to listen for.\n\t * @param {Function} callback The callback to invoke when the\n\t * event is emitted\n\t * @return {Tone.Emitter} this\n\t */\n\tTone.Emitter.prototype.on = function(event, callback){\n\t\t//split the event\n\t\tvar events = event.split(/\\W+/);\n\t\tfor (var i = 0; i < events.length; i++){\n\t\t\tvar eventName = events[i];\n\t\t\tif (!this._events.hasOwnProperty(eventName)){\n\t\t\t\tthis._events[eventName] = [];\n\t\t\t}\n\t\t\tthis._events[eventName].push(callback);\n\t\t}\n\t\treturn this;\n\t};\n\n\t/**\n\t * Remove the event listener.\n\t * @param {String} event The event to stop listening to.\n\t * @param {Function=} callback The callback which was bound to \n\t * the event with Tone.Emitter.on.\n\t * If no callback is given, all callbacks\n\t * events are removed.\n\t * @return {Tone.Emitter} this\n\t */\n\tTone.Emitter.prototype.off = function(event, callback){\n\t\tvar events = event.split(/\\W+/);\n\t\tfor (var ev = 0; ev < events.length; ev++){\n\t\t\tevent = events[ev];\n\t\t\tif (this._events.hasOwnProperty(event)){\n\t\t\t\tif (Tone.prototype.isUndef(callback)){\n\t\t\t\t\tthis._events[event] = [];\n\t\t\t\t} else {\n\t\t\t\t\tvar eventList = this._events[event];\n\t\t\t\t\tfor (var i = 0; i < eventList.length; i++){\n\t\t\t\t\t\tif (eventList[i] === callback){\n\t\t\t\t\t\t\teventList.splice(i, 1);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\treturn this;\n\t};\n\n\t/**\n\t * Invoke all of the callbacks bound to the event\n\t * with any arguments passed in. \n\t * @param {String} event The name of the event.\n\t * @param {*...} args The arguments to pass to the functions listening.\n\t * @return {Tone.Emitter} this\n\t */\n\tTone.Emitter.prototype.emit = function(event){\n\t\tif (this._events){\n\t\t\tvar args = Array.apply(null, arguments).slice(1);\n\t\t\tif (this._events.hasOwnProperty(event)){\n\t\t\t\tvar eventList = this._events[event];\n\t\t\t\tfor (var i = 0, len = eventList.length; i < len; i++){\n\t\t\t\t\teventList[i].apply(this, args);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\treturn this;\n\t};\n\n\t/**\n\t * Add Emitter functions (on/off/emit) to the object\n\t * @param {Object|Function} object The object or class to extend.\n\t */\n\tTone.Emitter.mixin = function(object){\n\t\tvar functions = [\"on\", \"off\", \"emit\"];\n\t\tobject._events = {};\n\t\tfor (var i = 0; i < functions.length; i++){\n\t\t\tvar func = functions[i];\n\t\t\tvar emitterFunc = Tone.Emitter.prototype[func];\n\t\t\tobject[func] = emitterFunc;\n\t\t}\n\t};\n\n\t/**\n\t * Clean up\n\t * @return {Tone.Emitter} this\n\t */\n\tTone.Emitter.prototype.dispose = function(){\n\t\tTone.prototype.dispose.call(this);\n\t\tthis._events = null;\n\t\treturn this;\n\t};\n\n\treturn Tone.Emitter;\n});","module.exports = {\r\n recorderProcessor: 'recorder-processor',\r\n soundFileProcessor: 'sound-file-processor',\r\n amplitudeProcessor: 'amplitude-processor'\r\n};\r\n","define([\"Tone/core/Tone\"], function(Tone){\n\n\t\"use strict\";\n\n\t/**\n\t * @class Base class for all Signals. Used Internally. \n\t *\n\t * @constructor\n\t * @extends {Tone}\n\t */\n\tTone.SignalBase = function(){};\n\n\tTone.extend(Tone.SignalBase);\n\n\t/**\n\t * When signals connect to other signals or AudioParams, \n\t * they take over the output value of that signal or AudioParam. \n\t * For all other nodes, the behavior is the same as a default connect. \n\t *\n\t * @override\n\t * @param {AudioParam|AudioNode|Tone.Signal|Tone} node \n\t * @param {number} [outputNumber=0] The output number to connect from.\n\t * @param {number} [inputNumber=0] The input number to connect to.\n\t * @returns {Tone.SignalBase} this\n\t */\n\tTone.SignalBase.prototype.connect = function(node, outputNumber, inputNumber){\n\t\t//zero it out so that the signal can have full control\n\t\tif ((Tone.Signal && Tone.Signal === node.constructor) || \n\t\t\t\t(Tone.Param && Tone.Param === node.constructor) || \n\t\t\t\t(Tone.TimelineSignal && Tone.TimelineSignal === node.constructor)){\n\t\t\t//cancel changes\n\t\t\tnode._param.cancelScheduledValues(0);\n\t\t\t//reset the value\n\t\t\tnode._param.value = 0;\n\t\t\t//mark the value as overridden\n\t\t\tnode.overridden = true;\n\t\t} else if (node instanceof AudioParam){\n\t\t\tnode.cancelScheduledValues(0);\n\t\t\tnode.value = 0;\n\t\t} \n\t\tTone.prototype.connect.call(this, node, outputNumber, inputNumber);\n\t\treturn this;\n\t};\n\n\treturn Tone.SignalBase;\n});","define([\"Tone/core/Tone\", \"Tone/type/TimeBase\"], function (Tone) {\n\n\t/**\n\t * @class Tone.Time is a primitive type for encoding Time values. \n\t * Eventually all time values are evaluated to seconds\n\t * using the `eval` method. Tone.Time can be constructed\n\t * with or without the `new` keyword. Tone.Time can be passed\n\t * into the parameter of any method which takes time as an argument. \n\t * @constructor\n\t * @extends {Tone.TimeBase}\n\t * @param {String|Number} val The time value.\n\t * @param {String=} units The units of the value.\n\t * @example\n\t * var t = Tone.Time(\"4n\");//encodes a quarter note\n\t * t.mult(4); // multiply that value by 4\n\t * t.toNotation(); //returns \"1m\"\n\t */\n\tTone.Time = function(val, units){\n\t\tif (this instanceof Tone.Time){\n\n\t\t\t/**\n\t\t\t * If the current clock time should\n\t\t\t * be added to the output\n\t\t\t * @type {Boolean}\n\t\t\t * @private\n\t\t\t */\n\t\t\tthis._plusNow = false;\n\t\t\t\n\t\t\tTone.TimeBase.call(this, val, units);\n\n\t\t} else {\n\t\t\treturn new Tone.Time(val, units);\n\t\t}\n\t};\n\n\tTone.extend(Tone.Time, Tone.TimeBase);\n\n\t//clone the expressions so that \n\t//we can add more without modifying the original\n\tTone.Time.prototype._unaryExpressions = Object.create(Tone.TimeBase.prototype._unaryExpressions);\n\n\t/*\n\t * Adds an additional unary expression\n\t * which quantizes values to the next subdivision\n\t * @type {Object}\n\t * @private\n\t */\n\tTone.Time.prototype._unaryExpressions.quantize = {\n\t\tregexp : /^@/,\n\t\tmethod : function(rh){\n\t\t\treturn Tone.Transport.nextSubdivision(rh());\n\t\t}\n\t};\n\n\t/*\n\t * Adds an additional unary expression\n\t * which adds the current clock time.\n\t * @type {Object}\n\t * @private\n\t */\n\tTone.Time.prototype._unaryExpressions.now = {\n\t\tregexp : /^\\+/,\n\t\tmethod : function(lh){\n\t\t\tthis._plusNow = true;\n\t\t\treturn lh();\n\t\t}\n\t};\n\n\t/**\n\t * Quantize the time by the given subdivision. Optionally add a\n\t * percentage which will move the time value towards the ideal\n\t * quantized value by that percentage. \n\t * @param {Number|Time} val The subdivision to quantize to\n\t * @param {NormalRange} [percent=1] Move the time value\n\t * towards the quantized value by\n\t * a percentage.\n\t * @return {Tone.Time} this\n\t * @example\n\t * Tone.Time(21).quantize(2) //returns 22\n\t * Tone.Time(0.6).quantize(\"4n\", 0.5) //returns 0.55\n\t */\n\tTone.Time.prototype.quantize = function(subdiv, percent){\n\t\tpercent = this.defaultArg(percent, 1);\n\t\tthis._expr = function(expr, subdivision, percent){\n\t\t\texpr = expr();\n\t\t\tsubdivision = subdivision.toSeconds();\n\t\t\tvar multiple = Math.round(expr / subdivision);\n\t\t\tvar ideal = multiple * subdivision;\n\t\t\tvar diff = ideal - expr;\n\t\t\treturn expr + diff * percent;\n\t\t}.bind(this, this._expr, new this.constructor(subdiv), percent);\n\t\treturn this;\n\t};\n\n\t/**\n\t * Adds the clock time to the time expression at the \n\t * moment of evaluation. \n\t * @return {Tone.Time} this\n\t */\n\tTone.Time.prototype.addNow = function(){\n\t\tthis._plusNow = true;\n\t\treturn this;\n\t};\n\n\t/**\n\t * @override\n\t * Override the default value return when no arguments are passed in.\n\t * The default value is 'now'\n\t * @private\n\t */\n\tTone.Time.prototype._defaultExpr = function(){\n\t\tthis._plusNow = true;\n\t\treturn this._noOp;\n\t};\n\n\t/**\n\t * Copies the value of time to this Time\n\t * @param {Tone.Time} time\n\t * @return {Time}\n\t */\n\tTone.Time.prototype.copy = function(time){\n\t\tTone.TimeBase.prototype.copy.call(this, time);\n\t\tthis._plusNow = time._plusNow;\n\t\treturn this;\n\t};\n\n\t//CONVERSIONS//////////////////////////////////////////////////////////////\n\n\t/**\n\t * Convert a Time to Notation. Values will be thresholded to the nearest 128th note. \n\t * @return {Notation} \n\t * @example\n\t * //if the Transport is at 120bpm:\n\t * Tone.Time(2).toNotation();//returns \"1m\"\n\t */\n\tTone.Time.prototype.toNotation = function(){\n\t\tvar time = this.toSeconds();\n\t\tvar testNotations = [\"1m\", \"2n\", \"4n\", \"8n\", \"16n\", \"32n\", \"64n\", \"128n\"];\n\t\tvar retNotation = this._toNotationHelper(time, testNotations);\n\t\t//try the same thing but with tripelets\n\t\tvar testTripletNotations = [\"1m\", \"2n\", \"2t\", \"4n\", \"4t\", \"8n\", \"8t\", \"16n\", \"16t\", \"32n\", \"32t\", \"64n\", \"64t\", \"128n\"];\n\t\tvar retTripletNotation = this._toNotationHelper(time, testTripletNotations);\n\t\t//choose the simpler expression of the two\n\t\tif (retTripletNotation.split(\"+\").length < retNotation.split(\"+\").length){\n\t\t\treturn retTripletNotation;\n\t\t} else {\n\t\t\treturn retNotation;\n\t\t}\n\t};\n\n\t/**\n\t * Helper method for Tone.toNotation\n\t * @param {Number} units \n\t * @param {Array} testNotations\n\t * @return {String}\n\t * @private\n\t */\n\tTone.Time.prototype._toNotationHelper = function(units, testNotations){\n\t\t//the threshold is the last value in the array\n\t\tvar threshold = this._notationToUnits(testNotations[testNotations.length - 1]);\n\t\tvar retNotation = \"\";\n\t\tfor (var i = 0; i < testNotations.length; i++){\n\t\t\tvar notationTime = this._notationToUnits(testNotations[i]);\n\t\t\t//account for floating point errors (i.e. round up if the value is 0.999999)\n\t\t\tvar multiple = units / notationTime;\n\t\t\tvar floatingPointError = 0.000001;\n\t\t\tif (1 - multiple % 1 < floatingPointError){\n\t\t\t\tmultiple += floatingPointError;\n\t\t\t}\n\t\t\tmultiple = Math.floor(multiple);\n\t\t\tif (multiple > 0){\n\t\t\t\tif (multiple === 1){\n\t\t\t\t\tretNotation += testNotations[i];\n\t\t\t\t} else {\n\t\t\t\t\tretNotation += multiple.toString() + \"*\" + testNotations[i];\n\t\t\t\t}\n\t\t\t\tunits -= multiple * notationTime;\n\t\t\t\tif (units < threshold){\n\t\t\t\t\tbreak;\n\t\t\t\t} else {\n\t\t\t\t\tretNotation += \" + \";\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tif (retNotation === \"\"){\n\t\t\tretNotation = \"0\";\n\t\t}\n\t\treturn retNotation;\n\t};\n\n\t/**\n\t * Convert a notation value to the current units\n\t * @param {Notation} notation \n\t * @return {Number} \n\t * @private\n\t */\n\tTone.Time.prototype._notationToUnits = function(notation){\n\t\tvar primaryExprs = this._primaryExpressions;\n\t\tvar notationExprs = [primaryExprs.n, primaryExprs.t, primaryExprs.m];\n\t\tfor (var i = 0; i < notationExprs.length; i++){\n\t\t\tvar expr = notationExprs[i];\n\t\t\tvar match = notation.match(expr.regexp);\n\t\t\tif (match){\n\t\t\t\treturn expr.method.call(this, match[1]);\n\t\t\t}\n\t\t}\n\t};\n\n\t/**\n\t * Return the time encoded as Bars:Beats:Sixteenths.\n\t * @return {BarsBeatsSixteenths}\n\t */\n\tTone.Time.prototype.toBarsBeatsSixteenths = function(){\n\t\tvar quarterTime = this._beatsToUnits(1);\n\t\tvar quarters = this.toSeconds() / quarterTime;\n\t\tvar measures = Math.floor(quarters / this._timeSignature());\n\t\tvar sixteenths = (quarters % 1) * 4;\n\t\tquarters = Math.floor(quarters) % this._timeSignature();\n\t\tsixteenths = sixteenths.toString();\n\t\tif (sixteenths.length > 3){\n\t\t\tsixteenths = parseFloat(sixteenths).toFixed(3);\n\t\t}\n\t\tvar progress = [measures, quarters, sixteenths];\n\t\treturn progress.join(\":\");\n\t};\n\n\t/**\n\t * Return the time in ticks.\n\t * @return {Ticks}\n\t */\n\tTone.Time.prototype.toTicks = function(){\n\t\tvar quarterTime = this._beatsToUnits(1);\n\t\tvar quarters = this.valueOf() / quarterTime;\n\t\treturn Math.floor(quarters * Tone.Transport.PPQ);\n\t};\n\n\t/**\n\t * Return the time in samples\n\t * @return {Samples} \n\t */\n\tTone.Time.prototype.toSamples = function(){\n\t\treturn this.toSeconds() * this.context.sampleRate;\n\t};\n\n\t/**\n\t * Return the time as a frequency value\n\t * @return {Frequency} \n\t * @example\n\t * Tone.Time(2).toFrequency(); //0.5\n\t */\n\tTone.Time.prototype.toFrequency = function(){\n\t\treturn 1/this.toSeconds();\n\t};\n\n\t/**\n\t * Return the time in seconds.\n\t * @return {Seconds} \n\t */\n\tTone.Time.prototype.toSeconds = function(){\n\t\treturn this.valueOf();\n\t};\n\n\t/**\n\t * Return the time in milliseconds.\n\t * @return {Milliseconds} \n\t */\n\tTone.Time.prototype.toMilliseconds = function(){\n\t\treturn this.toSeconds() * 1000;\n\t};\n\n\t/**\n\t * Return the time in seconds.\n\t * @return {Seconds} \n\t */\n\tTone.Time.prototype.valueOf = function(){\n\t\tvar val = this._expr();\n\t\treturn val + (this._plusNow?this.now():0);\n\t};\n\n\treturn Tone.Time;\n});","define([\"Tone/core/Tone\"], function (Tone) {\n\n\t/**\n\t * @class Tone.TimeBase is a flexible encoding of time\n\t * which can be evaluated to and from a string.\n\t * Parsing code modified from https://code.google.com/p/tapdigit/\n\t * Copyright 2011 2012 Ariya Hidayat, New BSD License\n\t * @extends {Tone}\n\t * @param {Time} val The time value as a number or string\n\t * @param {String=} units Unit values\n\t * @example\n\t * Tone.TimeBase(4, \"n\")\n\t * Tone.TimeBase(2, \"t\")\n\t * Tone.TimeBase(\"2t\").add(\"1m\")\n\t * Tone.TimeBase(\"2t + 1m\");\n\t */\n\tTone.TimeBase = function(val, units){\n\n\t\t//allows it to be constructed with or without 'new'\n\t\tif (this instanceof Tone.TimeBase) {\n\n\t\t\t/**\n\t\t\t * Any expressions parsed from the Time\n\t\t\t * @type {Array}\n\t\t\t * @private\n\t\t\t */\n\t\t\tthis._expr = this._noOp;\n\n\t\t\tif (val instanceof Tone.TimeBase){\n\t\t\t\tthis.copy(val);\n\t\t\t} else if (!this.isUndef(units) || this.isNumber(val)){\n\t\t\t\t//default units\n\t\t\t\tunits = this.defaultArg(units, this._defaultUnits);\n\t\t\t\tvar method = this._primaryExpressions[units].method;\n\t\t\t\tthis._expr = method.bind(this, val);\n\t\t\t} else if (this.isString(val)){\n\t\t\t\tthis.set(val);\n\t\t\t} else if (this.isUndef(val)){\n\t\t\t\t//default expression\n\t\t\t\tthis._expr = this._defaultExpr();\n\t\t\t}\n\t\t} else {\n\n\t\t\treturn new Tone.TimeBase(val, units);\n\t\t}\n\t};\n\n\tTone.extend(Tone.TimeBase);\n\n\t/**\n\t * Repalce the current time value with the value\n\t * given by the expression string.\n\t * @param {String} exprString\n\t * @return {Tone.TimeBase} this\n\t */\n\tTone.TimeBase.prototype.set = function(exprString){\n\t\tthis._expr = this._parseExprString(exprString);\n\t\treturn this;\n\t};\n\n\t/**\n\t * Return a clone of the TimeBase object.\n\t * @return {Tone.TimeBase} The new cloned Tone.TimeBase\n\t */\n\tTone.TimeBase.prototype.clone = function(){\n\t\tvar instance = new this.constructor();\n\t\tinstance.copy(this);\n\t\treturn instance;\n\t};\n\n\t/**\n\t * Copies the value of time to this Time\n\t * @param {Tone.TimeBase} time\n\t * @return {TimeBase}\n\t */\n\tTone.TimeBase.prototype.copy = function(time){\n\t\tvar val = time._expr();\n\t\treturn this.set(val);\n\t};\n\n\t///////////////////////////////////////////////////////////////////////////\n\t//\tABSTRACT SYNTAX TREE PARSER\n\t///////////////////////////////////////////////////////////////////////////\n\n\t/**\n\t * All the primary expressions.\n\t * @private\n\t * @type {Object}\n\t */\n\tTone.TimeBase.prototype._primaryExpressions = {\n\t\t\"n\" : {\n\t\t\tregexp : /^(\\d+)n/i,\n\t\t\tmethod : function(value){\n\t\t\t\tvalue = parseInt(value);\n\t\t\t\tif (value === 1){\n\t\t\t\t\treturn this._beatsToUnits(this._timeSignature());\n\t\t\t\t} else {\n\t\t\t\t\treturn this._beatsToUnits(4 / value);\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\t\t\"t\" : {\n\t\t\tregexp : /^(\\d+)t/i,\n\t\t\tmethod : function(value){\n\t\t\t\tvalue = parseInt(value);\n\t\t\t\treturn this._beatsToUnits(8 / (parseInt(value) * 3));\n\t\t\t}\n\t\t},\n\t\t\"m\" : {\n\t\t\tregexp : /^(\\d+)m/i,\n\t\t\tmethod : function(value){\n\t\t\t\treturn this._beatsToUnits(parseInt(value) * this._timeSignature());\n\t\t\t}\n\t\t},\n\t\t\"i\" : {\n\t\t\tregexp : /^(\\d+)i/i,\n\t\t\tmethod : function(value){\n\t\t\t\treturn this._ticksToUnits(parseInt(value));\n\t\t\t}\n\t\t},\n\t\t\"hz\" : {\n\t\t\tregexp : /^(\\d+(?:\\.\\d+)?)hz/i,\n\t\t\tmethod : function(value){\n\t\t\t\treturn this._frequencyToUnits(parseFloat(value));\n\t\t\t}\n\t\t},\n\t\t\"tr\" : {\n\t\t\tregexp : /^(\\d+(?:\\.\\d+)?):(\\d+(?:\\.\\d+)?):?(\\d+(?:\\.\\d+)?)?/,\n\t\t\tmethod : function(m, q, s){\n\t\t\t\tvar total = 0;\n\t\t\t\tif (m && m !== \"0\"){\n\t\t\t\t\ttotal += this._beatsToUnits(this._timeSignature() * parseFloat(m));\n\t\t\t\t}\n\t\t\t\tif (q && q !== \"0\"){\n\t\t\t\t\ttotal += this._beatsToUnits(parseFloat(q));\n\t\t\t\t}\n\t\t\t\tif (s && s !== \"0\"){\n\t\t\t\t\ttotal += this._beatsToUnits(parseFloat(s) / 4);\n\t\t\t\t}\n\t\t\t\treturn total;\n\t\t\t}\n\t\t},\n\t\t\"s\" : {\n\t\t\tregexp : /^(\\d+(?:\\.\\d+)?s)/,\n\t\t\tmethod : function(value){\n\t\t\t\treturn this._secondsToUnits(parseFloat(value));\n\t\t\t}\n\t\t},\n\t\t\"samples\" : {\n\t\t\tregexp : /^(\\d+)samples/,\n\t\t\tmethod : function(value){\n\t\t\t\treturn parseInt(value) / this.context.sampleRate;\n\t\t\t}\n\t\t},\n\t\t\"default\" : {\n\t\t\tregexp : /^(\\d+(?:\\.\\d+)?)/,\n\t\t\tmethod : function(value){\n\t\t\t\treturn this._primaryExpressions[this._defaultUnits].method.call(this, value);\n\t\t\t}\n\t\t}\n\t};\n\n\t/**\n\t * All the binary expressions that TimeBase can accept.\n\t * @private\n\t * @type {Object}\n\t */\n\tTone.TimeBase.prototype._binaryExpressions = {\n\t\t\"+\" : {\n\t\t\tregexp : /^\\+/,\n\t\t\tprecedence : 2,\n\t\t\tmethod : function(lh, rh){\n\t\t\t\treturn lh() + rh();\n\t\t\t}\n\t\t},\n\t\t\"-\" : {\n\t\t\tregexp : /^\\-/,\n\t\t\tprecedence : 2,\n\t\t\tmethod : function(lh, rh){\n\t\t\t\treturn lh() - rh();\n\t\t\t}\n\t\t},\n\t\t\"*\" : {\n\t\t\tregexp : /^\\*/,\n\t\t\tprecedence : 1,\n\t\t\tmethod : function(lh, rh){\n\t\t\t\treturn lh() * rh();\n\t\t\t}\n\t\t},\n\t\t\"/\" : {\n\t\t\tregexp : /^\\//,\n\t\t\tprecedence : 1,\n\t\t\tmethod : function(lh, rh){\n\t\t\t\treturn lh() / rh();\n\t\t\t}\n\t\t}\n\t};\n\n\t/**\n\t * All the unary expressions.\n\t * @private\n\t * @type {Object}\n\t */\n\tTone.TimeBase.prototype._unaryExpressions = {\n\t\t\"neg\" : {\n\t\t\tregexp : /^\\-/,\n\t\t\tmethod : function(lh){\n\t\t\t\treturn -lh();\n\t\t\t}\n\t\t}\n\t};\n\n\t/**\n\t * Syntactic glue which holds expressions together\n\t * @private\n\t * @type {Object}\n\t */\n\tTone.TimeBase.prototype._syntaxGlue = {\n\t\t\"(\" : {\n\t\t\tregexp : /^\\(/\n\t\t},\n\t\t\")\" : {\n\t\t\tregexp : /^\\)/\n\t\t}\n\t};\n\n\t/**\n\t * tokenize the expression based on the Expressions object\n\t * @param {string} expr \n\t * @return {Object} returns two methods on the tokenized list, next and peek\n\t * @private\n\t */\n\tTone.TimeBase.prototype._tokenize = function(expr){\n\t\tvar position = -1;\n\t\tvar tokens = [];\n\n\t\twhile(expr.length > 0){\n\t\t\texpr = expr.trim();\n\t\t\tvar token = getNextToken(expr, this);\n\t\t\ttokens.push(token);\n\t\t\texpr = expr.substr(token.value.length);\n\t\t}\n\n\t\tfunction getNextToken(expr, context){\n\t\t\tvar expressions = [\"_binaryExpressions\", \"_unaryExpressions\", \"_primaryExpressions\", \"_syntaxGlue\"];\n\t\t\tfor (var i = 0; i < expressions.length; i++){\n\t\t\t\tvar group = context[expressions[i]];\n\t\t\t\tfor (var opName in group){\n\t\t\t\t\tvar op = group[opName];\n\t\t\t\t\tvar reg = op.regexp;\n\t\t\t\t\tvar match = expr.match(reg);\n\t\t\t\t\tif (match !== null){\n\t\t\t\t\t\treturn {\n\t\t\t\t\t\t\tmethod : op.method,\n\t\t\t\t\t\t\tprecedence : op.precedence,\n\t\t\t\t\t\t\tregexp : op.regexp,\n\t\t\t\t\t\t\tvalue : match[0],\n\t\t\t\t\t\t};\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\tthrow new SyntaxError(\"Tone.TimeBase: Unexpected token \"+expr);\n\t\t}\n\n\t\treturn {\n\t\t\tnext : function(){\n\t\t\t\treturn tokens[++position];\n\t\t\t},\n\t\t\tpeek : function(){\n\t\t\t\treturn tokens[position + 1];\n\t\t\t}\n\t\t};\n\t};\n\n\t/**\n\t * Given a token, find the value within the groupName\n\t * @param {Object} token\n\t * @param {String} groupName\n\t * @param {Number} precedence\n\t * @private\n\t */\n\tTone.TimeBase.prototype._matchGroup = function(token, group, prec) {\n\t\tvar ret = false;\n\t\tif (!this.isUndef(token)){\n\t\t\tfor (var opName in group){\n\t\t\t\tvar op = group[opName];\n\t\t\t\tif (op.regexp.test(token.value)){\n\t\t\t\t\tif (!this.isUndef(prec)){\n\t\t\t\t\t\tif(op.precedence === prec){\t\n\t\t\t\t\t\t\treturn op;\n\t\t\t\t\t\t}\n\t\t\t\t\t} else {\n\t\t\t\t\t\treturn op;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\treturn ret;\n\t};\n\n\t/**\n\t * Match a binary expression given the token and the precedence\n\t * @param {Lexer} lexer\n\t * @param {Number} precedence\n\t * @private\n\t */\n\tTone.TimeBase.prototype._parseBinary = function(lexer, precedence){\n\t\tif (this.isUndef(precedence)){\n\t\t\tprecedence = 2;\n\t\t}\n\t\tvar expr;\n\t\tif (precedence < 0){\n\t\t\texpr = this._parseUnary(lexer);\n\t\t} else {\n\t\t\texpr = this._parseBinary(lexer, precedence - 1);\n\t\t}\n\t\tvar token = lexer.peek();\n\t\twhile (token && this._matchGroup(token, this._binaryExpressions, precedence)){\n\t\t\ttoken = lexer.next();\n\t\t\texpr = token.method.bind(this, expr, this._parseBinary(lexer, precedence - 1));\n\t\t\ttoken = lexer.peek();\n\t\t}\n\t\treturn expr;\n\t};\n\n\t/**\n\t * Match a unary expression.\n\t * @param {Lexer} lexer\n\t * @private\n\t */\n\tTone.TimeBase.prototype._parseUnary = function(lexer){\n\t\tvar token, expr;\n\t\ttoken = lexer.peek();\n\t\tvar op = this._matchGroup(token, this._unaryExpressions);\n\t\tif (op) {\n\t\t\ttoken = lexer.next();\n\t\t\texpr = this._parseUnary(lexer);\n\t\t\treturn op.method.bind(this, expr);\n\t\t}\n\t\treturn this._parsePrimary(lexer);\n\t};\n\n\t/**\n\t * Match a primary expression (a value).\n\t * @param {Lexer} lexer\n\t * @private\n\t */\n\tTone.TimeBase.prototype._parsePrimary = function(lexer){\n\t\tvar token, expr;\n\t\ttoken = lexer.peek();\n\t\tif (this.isUndef(token)) {\n\t\t\tthrow new SyntaxError(\"Tone.TimeBase: Unexpected end of expression\");\n\t\t}\n\t\tif (this._matchGroup(token, this._primaryExpressions)) {\n\t\t\ttoken = lexer.next();\n\t\t\tvar matching = token.value.match(token.regexp);\n\t\t\treturn token.method.bind(this, matching[1], matching[2], matching[3]);\n\t\t}\n\t\tif (token && token.value === \"(\"){\n\t\t\tlexer.next();\n\t\t\texpr = this._parseBinary(lexer);\n\t\t\ttoken = lexer.next();\n\t\t\tif (!(token && token.value === \")\")) {\n\t\t\t\tthrow new SyntaxError(\"Expected )\");\n\t\t\t}\n\t\t\treturn expr;\n\t\t}\n\t\tthrow new SyntaxError(\"Tone.TimeBase: Cannot process token \" + token.value);\n\t};\n\n\t/**\n\t * Recursively parse the string expression into a syntax tree.\n\t * @param {string} expr \n\t * @return {Function} the bound method to be evaluated later\n\t * @private\n\t */\n\tTone.TimeBase.prototype._parseExprString = function(exprString){\n\t\tif (!this.isString(exprString)){\n\t\t\texprString = exprString.toString();\n\t\t}\n\t\tvar lexer = this._tokenize(exprString);\n\t\tvar tree = this._parseBinary(lexer);\n\t\treturn tree;\n\t};\n\n\t///////////////////////////////////////////////////////////////////////////\n\t//\tDEFAULTS\n\t///////////////////////////////////////////////////////////////////////////\n\n\t/**\n\t * The initial expression value\n\t * @return {Number} The initial value 0\n\t * @private\n\t */\n\tTone.TimeBase.prototype._noOp = function(){\n\t\treturn 0;\n\t};\n\n\t/**\n\t * The default expression value if no arguments are given\n\t * @private\n\t */\n\tTone.TimeBase.prototype._defaultExpr = function(){\n\t\treturn this._noOp;\n\t};\n\n\t/**\n\t * The default units if none are given.\n\t * @private\n\t */\n\tTone.TimeBase.prototype._defaultUnits = \"s\";\n\n\t///////////////////////////////////////////////////////////////////////////\n\t//\tUNIT CONVERSIONS\n\t///////////////////////////////////////////////////////////////////////////\n\n\t/**\n\t * Returns the value of a frequency in the current units\n\t * @param {Frequency} freq\n\t * @return {Number}\n\t * @private\n\t */\n\tTone.TimeBase.prototype._frequencyToUnits = function(freq){\n\t\treturn 1/freq;\n\t};\n\n\t/**\n\t * Return the value of the beats in the current units\n\t * @param {Number} beats\n\t * @return {Number}\n\t * @private\n\t */\n\tTone.TimeBase.prototype._beatsToUnits = function(beats){\n\t\treturn (60 / Tone.Transport.bpm.value) * beats;\n\t};\n\n\t/**\n\t * Returns the value of a second in the current units\n\t * @param {Seconds} seconds\n\t * @return {Number}\n\t * @private\n\t */\n\tTone.TimeBase.prototype._secondsToUnits = function(seconds){\n\t\treturn seconds;\n\t};\n\n\t/**\n\t * Returns the value of a tick in the current time units\n\t * @param {Ticks} ticks\n\t * @return {Number}\n\t * @private\n\t */\n\tTone.TimeBase.prototype._ticksToUnits = function(ticks){\n\t\treturn ticks * (this._beatsToUnits(1) / Tone.Transport.PPQ);\n\t};\n\n\t/**\n\t * Return the time signature.\n\t * @return {Number}\n\t * @private\n\t */\n\tTone.TimeBase.prototype._timeSignature = function(){\n\t\treturn Tone.Transport.timeSignature;\n\t};\n\n\t///////////////////////////////////////////////////////////////////////////\n\t//\tEXPRESSIONS\n\t///////////////////////////////////////////////////////////////////////////\n\n\t/**\n\t * Push an expression onto the expression list\n\t * @param {Time} val\n\t * @param {String} type\n\t * @param {String} units\n\t * @return {Tone.TimeBase} \n\t * @private\n\t */\n\tTone.TimeBase.prototype._pushExpr = function(val, name, units){\n\t\t//create the expression\n\t\tif (!(val instanceof Tone.TimeBase)){\n\t\t\tval = new this.constructor(val, units);\n\t\t}\n\t\tthis._expr = this._binaryExpressions[name].method.bind(this, this._expr, val._expr);\n\t\treturn this;\n\t};\n\n\t/**\n\t * Add to the current value.\n\t * @param {Time} val The value to add\n\t * @param {String=} units Optional units to use with the value.\n\t * @return {Tone.TimeBase} this\n\t * @example\n\t * Tone.TimeBase(\"2m\").add(\"1m\"); //\"3m\"\n\t */\n\tTone.TimeBase.prototype.add = function(val, units){\n\t\treturn this._pushExpr(val, \"+\", units);\n\t};\n\n\t/**\n\t * Subtract the value from the current time.\n\t * @param {Time} val The value to subtract\n\t * @param {String=} units Optional units to use with the value.\n\t * @return {Tone.TimeBase} this\n\t * @example\n\t * Tone.TimeBase(\"2m\").sub(\"1m\"); //\"1m\"\n\t */\n\tTone.TimeBase.prototype.sub = function(val, units){\n\t\treturn this._pushExpr(val, \"-\", units);\n\t};\n\n\t/**\n\t * Multiply the current value by the given time.\n\t * @param {Time} val The value to multiply\n\t * @param {String=} units Optional units to use with the value.\n\t * @return {Tone.TimeBase} this\n\t * @example\n\t * Tone.TimeBase(\"2m\").mult(\"2\"); //\"4m\"\n\t */\n\tTone.TimeBase.prototype.mult = function(val, units){\n\t\treturn this._pushExpr(val, \"*\", units);\n\t};\n\n\t/**\n\t * Divide the current value by the given time.\n\t * @param {Time} val The value to divide by\n\t * @param {String=} units Optional units to use with the value.\n\t * @return {Tone.TimeBase} this\n\t * @example\n\t * Tone.TimeBase(\"2m\").div(2); //\"1m\"\n\t */\n\tTone.TimeBase.prototype.div = function(val, units){\n\t\treturn this._pushExpr(val, \"/\", units);\n\t};\n\n\t/**\n\t * Evaluate the time value. Returns the time\n\t * in seconds.\n\t * @return {Seconds} \n\t */\n\tTone.TimeBase.prototype.valueOf = function(){\n\t\treturn this._expr();\n\t};\n\n\t/**\n\t * Clean up\n\t * @return {Tone.TimeBase} this\n\t */\n\tTone.TimeBase.prototype.dispose = function(){\n\t\tthis._expr = null;\n\t};\n\n\treturn Tone.TimeBase;\n});","define([\"Tone/core/Tone\", \"Tone/type/Type\"], function(Tone){\n\n\t\"use strict\";\n\n\t/**\n\t * @class Tone.Param wraps the native Web Audio's AudioParam to provide\n\t * additional unit conversion functionality. It also\n\t * serves as a base-class for classes which have a single,\n\t * automatable parameter. \n\t * @extends {Tone}\n\t * @param {AudioParam} param The parameter to wrap.\n\t * @param {Tone.Type} units The units of the audio param.\n\t * @param {Boolean} convert If the param should be converted.\n\t */\n\tTone.Param = function(){\n\n\t\tvar options = this.optionsObject(arguments, [\"param\", \"units\", \"convert\"], Tone.Param.defaults);\n\n\t\t/**\n\t\t * The native parameter to control\n\t\t * @type {AudioParam}\n\t\t * @private\n\t\t */\n\t\tthis._param = this.input = options.param;\n\n\t\t/**\n\t\t * The units of the parameter\n\t\t * @type {Tone.Type}\n\t\t */\n\t\tthis.units = options.units;\n\n\t\t/**\n\t\t * If the value should be converted or not\n\t\t * @type {Boolean}\n\t\t */\n\t\tthis.convert = options.convert;\n\n\t\t/**\n\t\t * True if the signal value is being overridden by \n\t\t * a connected signal.\n\t\t * @readOnly\n\t\t * @type {boolean}\n\t\t * @private\n\t\t */\n\t\tthis.overridden = false;\n\n\t\t/**\n\t\t * If there is an LFO, this is where it is held.\n\t\t * @type {Tone.LFO}\n\t\t * @private\n\t\t */\n\t\tthis._lfo = null;\n\n\t\tif (this.isObject(options.lfo)){\n\t\t\tthis.value = options.lfo;\n\t\t} else if (!this.isUndef(options.value)){\n\t\t\tthis.value = options.value;\n\t\t}\n\t};\n\n\tTone.extend(Tone.Param);\n\t\n\t/**\n\t * Defaults\n\t * @type {Object}\n\t * @const\n\t */\n\tTone.Param.defaults = {\n\t\t\"units\" : Tone.Type.Default,\n\t\t\"convert\" : true,\n\t\t\"param\" : undefined\n\t};\n\n\t/**\n\t * The current value of the parameter. \n\t * @memberOf Tone.Param#\n\t * @type {Number}\n\t * @name value\n\t */\n\tObject.defineProperty(Tone.Param.prototype, \"value\", {\n\t\tget : function(){\n\t\t\treturn this._toUnits(this._param.value);\n\t\t},\n\t\tset : function(value){\n\t\t\tif (this.isObject(value)){\n\t\t\t\t//throw an error if the LFO needs to be included\n\t\t\t\tif (this.isUndef(Tone.LFO)){\n\t\t\t\t\tthrow new Error(\"Include 'Tone.LFO' to use an LFO as a Param value.\");\n\t\t\t\t}\n\t\t\t\t//remove the old one\n\t\t\t\tif (this._lfo){\n\t\t\t\t\tthis._lfo.dispose();\n\t\t\t\t}\n\t\t\t\tthis._lfo = new Tone.LFO(value).start();\n\t\t\t\tthis._lfo.connect(this.input);\n\t\t\t} else {\n\t\t\t\tvar convertedVal = this._fromUnits(value);\n\t\t\t\tthis._param.cancelScheduledValues(0);\n\t\t\t\tthis._param.value = convertedVal;\n\t\t\t}\n\t\t}\n\t});\n\n\t/**\n\t * Convert the given value from the type specified by Tone.Param.units\n\t * into the destination value (such as Gain or Frequency).\n\t * @private\n\t * @param {*} val the value to convert\n\t * @return {number} the number which the value should be set to\n\t */\n\tTone.Param.prototype._fromUnits = function(val){\n\t\tif (this.convert || this.isUndef(this.convert)){\n\t\t\tswitch(this.units){\n\t\t\t\tcase Tone.Type.Time: \n\t\t\t\t\treturn this.toSeconds(val);\n\t\t\t\tcase Tone.Type.Frequency: \n\t\t\t\t\treturn this.toFrequency(val);\n\t\t\t\tcase Tone.Type.Decibels: \n\t\t\t\t\treturn this.dbToGain(val);\n\t\t\t\tcase Tone.Type.NormalRange: \n\t\t\t\t\treturn Math.min(Math.max(val, 0), 1);\n\t\t\t\tcase Tone.Type.AudioRange: \n\t\t\t\t\treturn Math.min(Math.max(val, -1), 1);\n\t\t\t\tcase Tone.Type.Positive: \n\t\t\t\t\treturn Math.max(val, 0);\n\t\t\t\tdefault:\n\t\t\t\t\treturn val;\n\t\t\t}\n\t\t} else {\n\t\t\treturn val;\n\t\t}\n\t};\n\n\t/**\n\t * Convert the parameters value into the units specified by Tone.Param.units.\n\t * @private\n\t * @param {number} val the value to convert\n\t * @return {number}\n\t */\n\tTone.Param.prototype._toUnits = function(val){\n\t\tif (this.convert || this.isUndef(this.convert)){\n\t\t\tswitch(this.units){\n\t\t\t\tcase Tone.Type.Decibels: \n\t\t\t\t\treturn this.gainToDb(val);\n\t\t\t\tdefault:\n\t\t\t\t\treturn val;\n\t\t\t}\n\t\t} else {\n\t\t\treturn val;\n\t\t}\n\t};\n\n\t/**\n\t * the minimum output value\n\t * @type {Number}\n\t * @private\n\t */\n\tTone.Param.prototype._minOutput = 0.00001;\n\n\t/**\n\t * Schedules a parameter value change at the given time.\n\t * @param {*}\tvalue The value to set the signal.\n\t * @param {Time} time The time when the change should occur.\n\t * @returns {Tone.Param} this\n\t * @example\n\t * //set the frequency to \"G4\" in exactly 1 second from now. \n\t * freq.setValueAtTime(\"G4\", \"+1\");\n\t */\n\tTone.Param.prototype.setValueAtTime = function(value, time){\n\t\tvalue = this._fromUnits(value);\n\t\ttime = this.toSeconds(time);\n\t\tif (time <= this.now() + this.blockTime){\n\t\t\tthis._param.value = value;\n\t\t} else {\n\t\t\tthis._param.setValueAtTime(value, time);\n\t\t}\n\t\treturn this;\n\t};\n\n\t/**\n\t * Creates a schedule point with the current value at the current time.\n\t * This is useful for creating an automation anchor point in order to \n\t * schedule changes from the current value. \n\t *\n\t * @param {number=} now (Optionally) pass the now value in. \n\t * @returns {Tone.Param} this\n\t */\n\tTone.Param.prototype.setRampPoint = function(now){\n\t\tnow = this.defaultArg(now, this.now());\n\t\tvar currentVal = this._param.value;\n\t\t// exponentialRampToValueAt cannot ever ramp from or to 0\n\t\t// More info: https://bugzilla.mozilla.org/show_bug.cgi?id=1125600#c2\n\t\tif (currentVal === 0){\n\t\t\tcurrentVal = this._minOutput;\n\t\t}\n\t\tthis._param.setValueAtTime(currentVal, now);\n\t\treturn this;\n\t};\n\n\t/**\n\t * Schedules a linear continuous change in parameter value from the \n\t * previous scheduled parameter value to the given value.\n\t * \n\t * @param {number} value \n\t * @param {Time} endTime \n\t * @returns {Tone.Param} this\n\t */\n\tTone.Param.prototype.linearRampToValueAtTime = function(value, endTime){\n\t\tvalue = this._fromUnits(value);\n\t\tthis._param.linearRampToValueAtTime(value, this.toSeconds(endTime));\n\t\treturn this;\n\t};\n\n\t/**\n\t * Schedules an exponential continuous change in parameter value from \n\t * the previous scheduled parameter value to the given value.\n\t * \n\t * @param {number} value \n\t * @param {Time} endTime \n\t * @returns {Tone.Param} this\n\t */\n\tTone.Param.prototype.exponentialRampToValueAtTime = function(value, endTime){\n\t\tvalue = this._fromUnits(value);\n\t\tvalue = Math.max(this._minOutput, value);\n\t\tthis._param.exponentialRampToValueAtTime(value, this.toSeconds(endTime));\n\t\treturn this;\n\t};\n\n\t/**\n\t * Schedules an exponential continuous change in parameter value from \n\t * the current time and current value to the given value over the \n\t * duration of the rampTime.\n\t * \n\t * @param {number} value The value to ramp to.\n\t * @param {Time} rampTime the time that it takes the \n\t * value to ramp from it's current value\n\t * @param {Time}\t[startTime=now] \tWhen the ramp should start. \n\t * @returns {Tone.Param} this\n\t * @example\n\t * //exponentially ramp to the value 2 over 4 seconds. \n\t * signal.exponentialRampToValue(2, 4);\n\t */\n\tTone.Param.prototype.exponentialRampToValue = function(value, rampTime, startTime){\n\t\tstartTime = this.toSeconds(startTime);\n\t\tthis.setRampPoint(startTime);\n\t\tthis.exponentialRampToValueAtTime(value, startTime + this.toSeconds(rampTime));\n\t\treturn this;\n\t};\n\n\t/**\n\t * Schedules an linear continuous change in parameter value from \n\t * the current time and current value to the given value over the \n\t * duration of the rampTime.\n\t * \n\t * @param {number} value The value to ramp to.\n\t * @param {Time} rampTime the time that it takes the \n\t * value to ramp from it's current value\n\t * @param {Time}\t[startTime=now] \tWhen the ramp should start. \n\t * @returns {Tone.Param} this\n\t * @example\n\t * //linearly ramp to the value 4 over 3 seconds. \n\t * signal.linearRampToValue(4, 3);\n\t */\n\tTone.Param.prototype.linearRampToValue = function(value, rampTime, startTime){\n\t\tstartTime = this.toSeconds(startTime);\n\t\tthis.setRampPoint(startTime);\n\t\tthis.linearRampToValueAtTime(value, startTime + this.toSeconds(rampTime));\n\t\treturn this;\n\t};\n\n\t/**\n\t * Start exponentially approaching the target value at the given time with\n\t * a rate having the given time constant.\n\t * @param {number} value \n\t * @param {Time} startTime \n\t * @param {number} timeConstant \n\t * @returns {Tone.Param} this \n\t */\n\tTone.Param.prototype.setTargetAtTime = function(value, startTime, timeConstant){\n\t\tvalue = this._fromUnits(value);\n\t\t// The value will never be able to approach without timeConstant > 0.\n\t\t// http://www.w3.org/TR/webaudio/#dfn-setTargetAtTime, where the equation\n\t\t// is described. 0 results in a division by 0.\n\t\tvalue = Math.max(this._minOutput, value);\n\t\ttimeConstant = Math.max(this._minOutput, timeConstant);\n\t\tthis._param.setTargetAtTime(value, this.toSeconds(startTime), timeConstant);\n\t\treturn this;\n\t};\n\n\t/**\n\t * Sets an array of arbitrary parameter values starting at the given time\n\t * for the given duration.\n\t * \t\n\t * @param {Array} values \n\t * @param {Time} startTime \n\t * @param {Time} duration \n\t * @returns {Tone.Param} this\n\t */\n\tTone.Param.prototype.setValueCurveAtTime = function(values, startTime, duration){\n\t\tfor (var i = 0; i < values.length; i++){\n\t\t\tvalues[i] = this._fromUnits(values[i]);\n\t\t}\n\t\tthis._param.setValueCurveAtTime(values, this.toSeconds(startTime), this.toSeconds(duration));\n\t\treturn this;\n\t};\n\n\t/**\n\t * Cancels all scheduled parameter changes with times greater than or \n\t * equal to startTime.\n\t * \n\t * @param {Time} startTime\n\t * @returns {Tone.Param} this\n\t */\n\tTone.Param.prototype.cancelScheduledValues = function(startTime){\n\t\tthis._param.cancelScheduledValues(this.toSeconds(startTime));\n\t\treturn this;\n\t};\n\n\t/**\n\t * Ramps to the given value over the duration of the rampTime. \n\t * Automatically selects the best ramp type (exponential or linear)\n\t * depending on the `units` of the signal\n\t * \n\t * @param {number} value \n\t * @param {Time} rampTime \tThe time that it takes the \n\t * value to ramp from it's current value\n\t * @param {Time}\t[startTime=now] \tWhen the ramp should start. \n\t * @returns {Tone.Param} this\n\t * @example\n\t * //ramp to the value either linearly or exponentially \n\t * //depending on the \"units\" value of the signal\n\t * signal.rampTo(0, 10);\n\t * @example\n\t * //schedule it to ramp starting at a specific time\n\t * signal.rampTo(0, 10, 5)\n\t */\n\tTone.Param.prototype.rampTo = function(value, rampTime, startTime){\n\t\trampTime = this.defaultArg(rampTime, 0);\n\t\tif (this.units === Tone.Type.Frequency || this.units === Tone.Type.BPM || this.units === Tone.Type.Decibels){\n\t\t\tthis.exponentialRampToValue(value, rampTime, startTime);\n\t\t} else {\n\t\t\tthis.linearRampToValue(value, rampTime, startTime);\n\t\t}\n\t\treturn this;\n\t};\n\n\t/**\n\t * The LFO created by the signal instance. If none\n\t * was created, this is null.\n\t * @type {Tone.LFO}\n\t * @readOnly\n\t * @memberOf Tone.Param#\n\t * @name lfo\n\t */\n\tObject.defineProperty(Tone.Param.prototype, \"lfo\", {\n\t\tget : function(){\n\t\t\treturn this._lfo;\n\t\t}\n\t});\n\n\t/**\n\t * Clean up\n\t * @returns {Tone.Param} this\n\t */\n\tTone.Param.prototype.dispose = function(){\n\t\tTone.prototype.dispose.call(this);\n\t\tthis._param = null;\n\t\tif (this._lfo){\n\t\t\tthis._lfo.dispose();\n\t\t\tthis._lfo = null;\n\t\t}\n\t\treturn this;\n\t};\n\n\treturn Tone.Param;\n});","'use strict';\r\n\r\ndefine(function (require) {\r\n var p5sound = require('master');\r\n\r\n var Add = require('Tone/signal/Add');\r\n var Mult = require('Tone/signal/Multiply');\r\n var Scale = require('Tone/signal/Scale');\r\n\r\n /**\r\n *
Creates a signal that oscillates between -1.0 and 1.0.\r\n * By default, the oscillation takes the form of a sinusoidal\r\n * shape ('sine'). Additional types include 'triangle',\r\n * 'sawtooth' and 'square'. The frequency defaults to\r\n * 440 oscillations per second (440Hz, equal to the pitch of an\r\n * 'A' note).
\r\n *\r\n *
Set the type of oscillation with setType(), or by instantiating a\r\n * specific oscillator: p5.SinOsc, p5.TriOsc, p5.SqrOsc, or p5.SawOsc.\r\n *
\r\n *\r\n * @class p5.Oscillator\r\n * @constructor\r\n * @param {Number} [freq] frequency defaults to 440Hz\r\n * @param {String} [type] type of oscillator. Options:\r\n * 'sine' (default), 'triangle',\r\n * 'sawtooth', 'square'\r\n * @example\r\n *
\r\n * var osc;\r\n * var playing = false;\r\n *\r\n * function setup() {\r\n * backgroundColor = color(255,0,255);\r\n * textAlign(CENTER);\r\n *\r\n * osc = new p5.Oscillator();\r\n * osc.setType('sine');\r\n * osc.freq(240);\r\n * osc.amp(0);\r\n * osc.start();\r\n * }\r\n *\r\n * function draw() {\r\n * background(backgroundColor)\r\n * text('click to play', width/2, height/2);\r\n * }\r\n *\r\n * function mouseClicked() {\r\n * if (mouseX > 0 && mouseX < width && mouseY < height && mouseY > 0) {\r\n * if (!playing) {\r\n * // ramp amplitude to 0.5 over 0.05 seconds\r\n * osc.amp(0.5, 0.05);\r\n * playing = true;\r\n * backgroundColor = color(0,255,255);\r\n * } else {\r\n * // ramp amplitude to 0 over 0.5 seconds\r\n * osc.amp(0, 0.5);\r\n * playing = false;\r\n * backgroundColor = color(255,0,255);\r\n * }\r\n * }\r\n * }\r\n *
\r\n */\r\n p5.Oscillator = function(freq, type) {\r\n if (typeof freq === 'string') {\r\n var f = type;\r\n type = freq;\r\n freq = f;\r\n } if (typeof type === 'number') {\r\n var f = type;\r\n type = freq;\r\n freq = f;\r\n }\r\n this.started = false;\r\n\r\n // components\r\n this.phaseAmount = undefined;\r\n this.oscillator = p5sound.audiocontext.createOscillator();\r\n this.f = freq || 440.0; // frequency\r\n this.oscillator.type = type || 'sine';\r\n this.oscillator.frequency.setValueAtTime(this.f, p5sound.audiocontext.currentTime);\r\n\r\n // connections\r\n this.output = p5sound.audiocontext.createGain();\r\n\r\n this._freqMods = []; // modulators connected to this oscillator's frequency\r\n\r\n // set default output gain to 0.5\r\n this.output.gain.value = 0.5;\r\n this.output.gain.setValueAtTime(0.5, p5sound.audiocontext.currentTime);\r\n\r\n this.oscillator.connect(this.output);\r\n // stereo panning\r\n this.panPosition = 0.0;\r\n this.connection = p5sound.input; // connect to p5sound by default\r\n this.panner = new p5.Panner(this.output, this.connection, 1);\r\n\r\n //array of math operation signal chaining\r\n this.mathOps = [this.output];\r\n\r\n // add to the soundArray so we can dispose of the osc later\r\n p5sound.soundArray.push(this);\r\n };\r\n\r\n /**\r\n * Start an oscillator. Accepts an optional parameter to\r\n * determine how long (in seconds from now) until the\r\n * oscillator starts.\r\n *\r\n * @method start\r\n * @for p5.Oscillator\r\n * @param {Number} [time] startTime in seconds from now.\r\n * @param {Number} [frequency] frequency in Hz.\r\n */\r\n p5.Oscillator.prototype.start = function(time, f) {\r\n if (this.started) {\r\n var now = p5sound.audiocontext.currentTime;\r\n this.stop(now);\r\n }\r\n if (!this.started) {\r\n var freq = f || this.f;\r\n var type = this.oscillator.type;\r\n\r\n // set old osc free to be garbage collected (memory)\r\n if (this.oscillator) {\r\n this.oscillator.disconnect();\r\n delete this.oscillator;\r\n }\r\n\r\n // var detune = this.oscillator.frequency.value;\r\n this.oscillator = p5sound.audiocontext.createOscillator();\r\n this.oscillator.frequency.value = Math.abs(freq);\r\n this.oscillator.type = type;\r\n // this.oscillator.detune.value = detune;\r\n this.oscillator.connect(this.output);\r\n time = time || 0;\r\n this.oscillator.start(time + p5sound.audiocontext.currentTime);\r\n this.freqNode = this.oscillator.frequency;\r\n\r\n // if other oscillators are already connected to this osc's freq\r\n for (var i in this._freqMods) {\r\n if (typeof this._freqMods[i].connect !== 'undefined') {\r\n this._freqMods[i].connect(this.oscillator.frequency);\r\n }\r\n }\r\n\r\n this.started = true;\r\n }\r\n };\r\n\r\n /**\r\n * Stop an oscillator. Accepts an optional parameter\r\n * to determine how long (in seconds from now) until the\r\n * oscillator stops.\r\n *\r\n * @method stop\r\n * @for p5.Oscillator\r\n * @param {Number} secondsFromNow Time, in seconds from now.\r\n */\r\n p5.Oscillator.prototype.stop = function(time) {\r\n if (this.started) {\r\n var t = time || 0;\r\n var now = p5sound.audiocontext.currentTime;\r\n this.oscillator.stop(t + now);\r\n this.started = false;\r\n }\r\n };\r\n\r\n /**\r\n * Set the amplitude between 0 and 1.0. Or, pass in an object\r\n * such as an oscillator to modulate amplitude with an audio signal.\r\n *\r\n * @method amp\r\n * @for p5.Oscillator\r\n * @param {Number|Object} vol between 0 and 1.0\r\n * or a modulating signal/oscillator\r\n * @param {Number} [rampTime] create a fade that lasts rampTime\r\n * @param {Number} [timeFromNow] schedule this event to happen\r\n * seconds from now\r\n * @return {AudioParam} gain If no value is provided,\r\n * returns the Web Audio API\r\n * AudioParam that controls\r\n * this oscillator's\r\n * gain/amplitude/volume)\r\n */\r\n p5.Oscillator.prototype.amp = function(vol, rampTime, tFromNow) {\r\n var self = this;\r\n if (typeof vol === 'number') {\r\n var rampTime = rampTime || 0;\r\n var tFromNow = tFromNow || 0;\r\n var now = p5sound.audiocontext.currentTime;\r\n this.output.gain.linearRampToValueAtTime(vol, now + tFromNow + rampTime);\r\n }\r\n\r\n else if (vol) {\r\n vol.connect(self.output.gain);\r\n } else {\r\n // return the Gain Node\r\n return this.output.gain;\r\n }\r\n };\r\n\r\n // these are now the same thing\r\n p5.Oscillator.prototype.fade = p5.Oscillator.prototype.amp;\r\n\r\n p5.Oscillator.prototype.getAmp = function() {\r\n return this.output.gain.value;\r\n };\r\n\r\n /**\r\n * Set frequency of an oscillator to a value. Or, pass in an object\r\n * such as an oscillator to modulate the frequency with an audio signal.\r\n *\r\n * @method freq\r\n * @for p5.Oscillator\r\n * @param {Number|Object} Frequency Frequency in Hz\r\n * or modulating signal/oscillator\r\n * @param {Number} [rampTime] Ramp time (in seconds)\r\n * @param {Number} [timeFromNow] Schedule this event to happen\r\n * at x seconds from now\r\n * @return {AudioParam} Frequency If no value is provided,\r\n * returns the Web Audio API\r\n * AudioParam that controls\r\n * this oscillator's frequency\r\n * @example\r\n *
\r\n * var osc = new p5.Oscillator(300);\r\n * osc.start();\r\n * osc.freq(40, 10);\r\n *
\r\n */\r\n p5.Oscillator.prototype.freq = function(val, rampTime, tFromNow) {\r\n if (typeof val === 'number' && !isNaN(val)) {\r\n this.f = val;\r\n var now = p5sound.audiocontext.currentTime;\r\n var rampTime = rampTime || 0;\r\n var tFromNow = tFromNow || 0;\r\n var t = now + tFromNow + rampTime;\r\n // var currentFreq = this.oscillator.frequency.value;\r\n // this.oscillator.frequency.cancelScheduledValues(now);\r\n\r\n if (rampTime === 0) {\r\n this.oscillator.frequency.setValueAtTime(val, tFromNow + now);\r\n } else {\r\n if (val > 0 ) {\r\n this.oscillator.frequency.exponentialRampToValueAtTime(val, tFromNow + rampTime + now);\r\n } else {\r\n this.oscillator.frequency.linearRampToValueAtTime(val, tFromNow + rampTime + now);\r\n }\r\n }\r\n\r\n // reset phase if oscillator has a phase\r\n if (this.phaseAmount) {\r\n this.phase(this.phaseAmount);\r\n }\r\n\r\n } else if (val) {\r\n if (val.output) {\r\n val = val.output;\r\n }\r\n val.connect(this.oscillator.frequency);\r\n\r\n // keep track of what is modulating this param\r\n // so it can be re-connected if\r\n this._freqMods.push( val );\r\n } else {\r\n // return the Frequency Node\r\n return this.oscillator.frequency;\r\n }\r\n };\r\n\r\n p5.Oscillator.prototype.getFreq = function() {\r\n return this.oscillator.frequency.value;\r\n };\r\n\r\n /**\r\n * Set type to 'sine', 'triangle', 'sawtooth' or 'square'.\r\n *\r\n * @method setType\r\n * @for p5.Oscillator\r\n * @param {String} type 'sine', 'triangle', 'sawtooth' or 'square'.\r\n */\r\n p5.Oscillator.prototype.setType = function(type) {\r\n this.oscillator.type = type;\r\n };\r\n\r\n p5.Oscillator.prototype.getType = function() {\r\n return this.oscillator.type;\r\n };\r\n\r\n /**\r\n * Connect to a p5.sound / Web Audio object.\r\n *\r\n * @method connect\r\n * @for p5.Oscillator\r\n * @param {Object} unit A p5.sound or Web Audio object\r\n */\r\n p5.Oscillator.prototype.connect = function(unit) {\r\n if (!unit) {\r\n this.panner.connect(p5sound.input);\r\n }\r\n else if (unit.hasOwnProperty('input')) {\r\n this.panner.connect(unit.input);\r\n this.connection = unit.input;\r\n }\r\n else {\r\n this.panner.connect(unit);\r\n this.connection = unit;\r\n }\r\n };\r\n\r\n /**\r\n * Disconnect all outputs\r\n *\r\n * @method disconnect\r\n * @for p5.Oscillator\r\n */\r\n p5.Oscillator.prototype.disconnect = function() {\r\n if (this.output) {\r\n this.output.disconnect();\r\n }\r\n if (this.panner) {\r\n this.panner.disconnect();\r\n if (this.output) {\r\n this.output.connect(this.panner);\r\n }\r\n }\r\n this.oscMods = [];\r\n };\r\n\r\n /**\r\n * Pan between Left (-1) and Right (1)\r\n *\r\n * @method pan\r\n * @for p5.Oscillator\r\n * @param {Number} panning Number between -1 and 1\r\n * @param {Number} timeFromNow schedule this event to happen\r\n * seconds from now\r\n */\r\n p5.Oscillator.prototype.pan = function(pval, tFromNow) {\r\n this.panPosition = pval;\r\n this.panner.pan(pval, tFromNow);\r\n };\r\n\r\n p5.Oscillator.prototype.getPan = function() {\r\n return this.panPosition;\r\n };\r\n\r\n // get rid of the oscillator\r\n p5.Oscillator.prototype.dispose = function() {\r\n // remove reference from soundArray\r\n var index = p5sound.soundArray.indexOf(this);\r\n p5sound.soundArray.splice(index, 1);\r\n\r\n if (this.oscillator) {\r\n var now = p5sound.audiocontext.currentTime;\r\n this.stop(now);\r\n this.disconnect();\r\n this.panner = null;\r\n this.oscillator = null;\r\n }\r\n // if it is a Pulse\r\n if (this.osc2) {\r\n this.osc2.dispose();\r\n }\r\n };\r\n\r\n /**\r\n * Set the phase of an oscillator between 0.0 and 1.0.\r\n * In this implementation, phase is a delay time\r\n * based on the oscillator's current frequency.\r\n *\r\n * @method phase\r\n * @for p5.Oscillator\r\n * @param {Number} phase float between 0.0 and 1.0\r\n */\r\n p5.Oscillator.prototype.phase = function(p) {\r\n var delayAmt = p5.prototype.map(p, 0, 1.0, 0, 1/this.f);\r\n var now = p5sound.audiocontext.currentTime;\r\n\r\n this.phaseAmount = p;\r\n\r\n if (!this.dNode) {\r\n // create a delay node\r\n this.dNode = p5sound.audiocontext.createDelay();\r\n // put the delay node in between output and panner\r\n this.oscillator.disconnect();\r\n this.oscillator.connect(this.dNode);\r\n this.dNode.connect(this.output);\r\n }\r\n\r\n // set delay time to match phase:\r\n this.dNode.delayTime.setValueAtTime(delayAmt, now);\r\n };\r\n\r\n // ========================== //\r\n // SIGNAL MATH FOR MODULATION //\r\n // ========================== //\r\n\r\n // return sigChain(this, scale, thisChain, nextChain, Scale);\r\n var sigChain = function(o, mathObj, thisChain, nextChain, type) {\r\n var chainSource = o.oscillator;\r\n // if this type of math already exists in the chain, replace it\r\n for (var i in o.mathOps) {\r\n if (o.mathOps[i] instanceof type) {\r\n chainSource.disconnect();\r\n o.mathOps[i].dispose();\r\n thisChain = i;\r\n // assume nextChain is output gain node unless...\r\n if (thisChain < o.mathOps.length - 2) {\r\n nextChain = o.mathOps[i+1];\r\n }\r\n }\r\n }\r\n if (thisChain === o.mathOps.length - 1) {\r\n o.mathOps.push(nextChain);\r\n }\r\n // assume source is the oscillator unless i > 0\r\n if (i > 0) {\r\n chainSource = o.mathOps[i-1];\r\n }\r\n chainSource.disconnect();\r\n chainSource.connect(mathObj);\r\n mathObj.connect(nextChain);\r\n o.mathOps[thisChain] = mathObj;\r\n return o;\r\n };\r\n\r\n /**\r\n * Add a value to the p5.Oscillator's output amplitude,\r\n * and return the oscillator. Calling this method again\r\n * will override the initial add() with a new value.\r\n *\r\n * @method add\r\n * @for p5.Oscillator\r\n * @param {Number} number Constant number to add\r\n * @return {p5.Oscillator} Oscillator Returns this oscillator\r\n * with scaled output\r\n *\r\n */\r\n p5.Oscillator.prototype.add = function(num) {\r\n var add = new Add(num);\r\n var thisChain = this.mathOps.length-1;\r\n var nextChain = this.output;\r\n return sigChain(this, add, thisChain, nextChain, Add);\r\n };\r\n\r\n /**\r\n * Multiply the p5.Oscillator's output amplitude\r\n * by a fixed value (i.e. turn it up!). Calling this method\r\n * again will override the initial mult() with a new value.\r\n *\r\n * @method mult\r\n * @for p5.Oscillator\r\n * @param {Number} number Constant number to multiply\r\n * @return {p5.Oscillator} Oscillator Returns this oscillator\r\n * with multiplied output\r\n */\r\n p5.Oscillator.prototype.mult = function(num) {\r\n var mult = new Mult(num);\r\n var thisChain = this.mathOps.length-1;\r\n var nextChain = this.output;\r\n return sigChain(this, mult, thisChain, nextChain, Mult);\r\n };\r\n\r\n /**\r\n * Scale this oscillator's amplitude values to a given\r\n * range, and return the oscillator. Calling this method\r\n * again will override the initial scale() with new values.\r\n *\r\n * @method scale\r\n * @for p5.Oscillator\r\n * @param {Number} inMin input range minumum\r\n * @param {Number} inMax input range maximum\r\n * @param {Number} outMin input range minumum\r\n * @param {Number} outMax input range maximum\r\n * @return {p5.Oscillator} Oscillator Returns this oscillator\r\n * with scaled output\r\n */\r\n p5.Oscillator.prototype.scale = function(inMin, inMax, outMin, outMax) {\r\n var mapOutMin, mapOutMax;\r\n if (arguments.length === 4) {\r\n mapOutMin = p5.prototype.map(outMin, inMin, inMax, 0, 1) - 0.5;\r\n mapOutMax = p5.prototype.map(outMax, inMin, inMax, 0, 1) - 0.5;\r\n }\r\n else {\r\n mapOutMin = arguments[0];\r\n mapOutMax = arguments[1];\r\n }\r\n var scale = new Scale(mapOutMin, mapOutMax);\r\n var thisChain = this.mathOps.length-1;\r\n var nextChain = this.output;\r\n return sigChain(this, scale, thisChain, nextChain, Scale);\r\n\r\n // this.output.disconnect();\r\n // this.output.connect(scale)\r\n };\r\n\r\n // ============================== //\r\n // SinOsc, TriOsc, SqrOsc, SawOsc //\r\n // ============================== //\r\n\r\n /**\r\n * Constructor: new p5.SinOsc().\r\n * This creates a Sine Wave Oscillator and is\r\n * equivalent to new p5.Oscillator('sine')\r\n * or creating a p5.Oscillator and then calling\r\n * its method setType('sine').\r\n * See p5.Oscillator for methods.\r\n *\r\n * @class p5.SinOsc\r\n * @constructor\r\n * @extends p5.Oscillator\r\n * @param {Number} [freq] Set the frequency\r\n */\r\n p5.SinOsc = function(freq) {\r\n p5.Oscillator.call(this, freq, 'sine');\r\n };\r\n\r\n p5.SinOsc.prototype = Object.create(p5.Oscillator.prototype);\r\n\r\n /**\r\n * Constructor: new p5.TriOsc().\r\n * This creates a Triangle Wave Oscillator and is\r\n * equivalent to new p5.Oscillator('triangle')\r\n * or creating a p5.Oscillator and then calling\r\n * its method setType('triangle').\r\n * See p5.Oscillator for methods.\r\n *\r\n * @class p5.TriOsc\r\n * @constructor\r\n * @extends p5.Oscillator\r\n * @param {Number} [freq] Set the frequency\r\n */\r\n p5.TriOsc = function(freq) {\r\n p5.Oscillator.call(this, freq, 'triangle');\r\n };\r\n\r\n p5.TriOsc.prototype = Object.create(p5.Oscillator.prototype);\r\n\r\n /**\r\n * Constructor: new p5.SawOsc().\r\n * This creates a SawTooth Wave Oscillator and is\r\n * equivalent to new p5.Oscillator('sawtooth')\r\n * or creating a p5.Oscillator and then calling\r\n * its method setType('sawtooth').\r\n * See p5.Oscillator for methods.\r\n *\r\n * @class p5.SawOsc\r\n * @constructor\r\n * @extends p5.Oscillator\r\n * @param {Number} [freq] Set the frequency\r\n */\r\n p5.SawOsc = function(freq) {\r\n p5.Oscillator.call(this, freq, 'sawtooth');\r\n };\r\n\r\n p5.SawOsc.prototype = Object.create(p5.Oscillator.prototype);\r\n\r\n /**\r\n * Constructor: new p5.SqrOsc().\r\n * This creates a Square Wave Oscillator and is\r\n * equivalent to new p5.Oscillator('square')\r\n * or creating a p5.Oscillator and then calling\r\n * its method setType('square').\r\n * See p5.Oscillator for methods.\r\n *\r\n * @class p5.SqrOsc\r\n * @constructor\r\n * @extends p5.Oscillator\r\n * @param {Number} [freq] Set the frequency\r\n */\r\n p5.SqrOsc = function(freq) {\r\n p5.Oscillator.call(this, freq, 'square');\r\n };\r\n\r\n p5.SqrOsc.prototype = Object.create(p5.Oscillator.prototype);\r\n\r\n});\r\n","define([\"Tone/core/Tone\", \"Tone/type/Type\"], function (Tone) {\n\n\t\"use strict\";\n\n\t/**\n\t * @class A Timeline class for scheduling and maintaining state\n\t * along a timeline. All events must have a \"time\" property. \n\t * Internally, events are stored in time order for fast \n\t * retrieval.\n\t * @extends {Tone}\n\t * @param {Positive} [memory=Infinity] The number of previous events that are retained.\n\t */\n\tTone.Timeline = function(){\n\n\t\tvar options = this.optionsObject(arguments, [\"memory\"], Tone.Timeline.defaults);\n\n\t\t/**\n\t\t * The array of scheduled timeline events\n\t\t * @type {Array}\n\t\t * @private\n\t\t */\n\t\tthis._timeline = [];\n\n\t\t/**\n\t\t * An array of items to remove from the list. \n\t\t * @type {Array}\n\t\t * @private\n\t\t */\n\t\tthis._toRemove = [];\n\n\t\t/**\n\t\t * Flag if the tieline is mid iteration\n\t\t * @private\n\t\t * @type {Boolean}\n\t\t */\n\t\tthis._iterating = false;\n\n\t\t/**\n\t\t * The memory of the timeline, i.e.\n\t\t * how many events in the past it will retain\n\t\t * @type {Positive}\n\t\t */\n\t\tthis.memory = options.memory;\n\t};\n\n\tTone.extend(Tone.Timeline);\n\n\t/**\n\t * the default parameters\n\t * @static\n\t * @const\n\t */\n\tTone.Timeline.defaults = {\n\t\t\"memory\" : Infinity\n\t};\n\n\t/**\n\t * The number of items in the timeline.\n\t * @type {Number}\n\t * @memberOf Tone.Timeline#\n\t * @name length\n\t * @readOnly\n\t */\n\tObject.defineProperty(Tone.Timeline.prototype, \"length\", {\n\t\tget : function(){\n\t\t\treturn this._timeline.length;\n\t\t}\n\t});\n\n\t/**\n\t * Insert an event object onto the timeline. Events must have a \"time\" attribute.\n\t * @param {Object} event The event object to insert into the \n\t * timeline. \n\t * @returns {Tone.Timeline} this\n\t */\n\tTone.Timeline.prototype.add = function(event){\n\t\t//the event needs to have a time attribute\n\t\tif (this.isUndef(event.time)){\n\t\t\tthrow new Error(\"Tone.Timeline: events must have a time attribute\");\n\t\t}\n\t\tif (this._timeline.length){\n\t\t\tvar index = this._search(event.time);\n\t\t\tthis._timeline.splice(index + 1, 0, event);\n\t\t} else {\n\t\t\tthis._timeline.push(event);\t\t\t\n\t\t}\n\t\t//if the length is more than the memory, remove the previous ones\n\t\tif (this.length > this.memory){\n\t\t\tvar diff = this.length - this.memory;\n\t\t\tthis._timeline.splice(0, diff);\n\t\t}\n\t\treturn this;\n\t};\n\n\t/**\n\t * Remove an event from the timeline.\n\t * @param {Object} event The event object to remove from the list.\n\t * @returns {Tone.Timeline} this\n\t */\n\tTone.Timeline.prototype.remove = function(event){\n\t\tif (this._iterating){\n\t\t\tthis._toRemove.push(event);\n\t\t} else {\n\t\t\tvar index = this._timeline.indexOf(event);\n\t\t\tif (index !== -1){\n\t\t\t\tthis._timeline.splice(index, 1);\n\t\t\t}\n\t\t}\n\t\treturn this;\n\t};\n\n\t/**\n\t * Get the nearest event whose time is less than or equal to the given time.\n\t * @param {Number} time The time to query.\n\t * @returns {Object} The event object set after that time.\n\t */\n\tTone.Timeline.prototype.get = function(time){\n\t\tvar index = this._search(time);\n\t\tif (index !== -1){\n\t\t\treturn this._timeline[index];\n\t\t} else {\n\t\t\treturn null;\n\t\t}\n\t};\n\n\t/**\n\t * Return the first event in the timeline without removing it\n\t * @returns {Object} The first event object\n\t */\n\tTone.Timeline.prototype.peek = function(){\n\t\treturn this._timeline[0];\n\t};\n\n\t/**\n\t * Return the first event in the timeline and remove it\n\t * @returns {Object} The first event object\n\t */\n\tTone.Timeline.prototype.shift = function(){\n\t\treturn this._timeline.shift();\n\t};\n\n\t/**\n\t * Get the event which is scheduled after the given time.\n\t * @param {Number} time The time to query.\n\t * @returns {Object} The event object after the given time\n\t */\n\tTone.Timeline.prototype.getAfter = function(time){\n\t\tvar index = this._search(time);\n\t\tif (index + 1 < this._timeline.length){\n\t\t\treturn this._timeline[index + 1];\n\t\t} else {\n\t\t\treturn null;\n\t\t}\n\t};\n\n\t/**\n\t * Get the event before the event at the given time.\n\t * @param {Number} time The time to query.\n\t * @returns {Object} The event object before the given time\n\t */\n\tTone.Timeline.prototype.getBefore = function(time){\n\t\tvar len = this._timeline.length;\n\t\t//if it's after the last item, return the last item\n\t\tif (len > 0 && this._timeline[len - 1].time < time){\n\t\t\treturn this._timeline[len - 1];\n\t\t}\n\t\tvar index = this._search(time);\n\t\tif (index - 1 >= 0){\n\t\t\treturn this._timeline[index - 1];\n\t\t} else {\n\t\t\treturn null;\n\t\t}\n\t};\n\n\t/**\n\t * Cancel events after the given time\n\t * @param {Number} time The time to query.\n\t * @returns {Tone.Timeline} this\n\t */\n\tTone.Timeline.prototype.cancel = function(after){\n\t\tif (this._timeline.length > 1){\n\t\t\tvar index = this._search(after);\n\t\t\tif (index >= 0){\n\t\t\t\tif (this._timeline[index].time === after){\n\t\t\t\t\t//get the first item with that time\n\t\t\t\t\tfor (var i = index; i >= 0; i--){\n\t\t\t\t\t\tif (this._timeline[i].time === after){\n\t\t\t\t\t\t\tindex = i;\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tthis._timeline = this._timeline.slice(0, index);\n\t\t\t\t} else {\n\t\t\t\t\tthis._timeline = this._timeline.slice(0, index + 1);\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tthis._timeline = [];\n\t\t\t}\n\t\t} else if (this._timeline.length === 1){\n\t\t\t//the first item's time\n\t\t\tif (this._timeline[0].time >= after){\n\t\t\t\tthis._timeline = [];\n\t\t\t}\n\t\t}\n\t\treturn this;\n\t};\n\n\t/**\n\t * Cancel events before or equal to the given time.\n\t * @param {Number} time The time to cancel before.\n\t * @returns {Tone.Timeline} this\n\t */\n\tTone.Timeline.prototype.cancelBefore = function(time){\n\t\tif (this._timeline.length){\n\t\t\tvar index = this._search(time);\n\t\t\tif (index >= 0){\n\t\t\t\tthis._timeline = this._timeline.slice(index + 1);\n\t\t\t}\n\t\t}\n\t\treturn this;\n\t};\n\n\t/**\n\t * Does a binary serach on the timeline array and returns the \n\t * nearest event index whose time is after or equal to the given time.\n\t * If a time is searched before the first index in the timeline, -1 is returned.\n\t * If the time is after the end, the index of the last item is returned.\n\t * @param {Number} time \n\t * @return {Number} the index in the timeline array \n\t * @private\n\t */\n\tTone.Timeline.prototype._search = function(time){\n\t\tvar beginning = 0;\n\t\tvar len = this._timeline.length;\n\t\tvar end = len;\n\t\tif (len > 0 && this._timeline[len - 1].time <= time){\n\t\t\treturn len - 1;\n\t\t}\n\t\twhile (beginning < end){\n\t\t\t// calculate the midpoint for roughly equal partition\n\t\t\tvar midPoint = Math.floor(beginning + (end - beginning) / 2);\n\t\t\tvar event = this._timeline[midPoint];\n\t\t\tvar nextEvent = this._timeline[midPoint + 1];\n\t\t\tif (event.time === time){\n\t\t\t\t//choose the last one that has the same time\n\t\t\t\tfor (var i = midPoint; i < this._timeline.length; i++){\n\t\t\t\t\tvar testEvent = this._timeline[i];\n\t\t\t\t\tif (testEvent.time === time){\n\t\t\t\t\t\tmidPoint = i;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\treturn midPoint;\n\t\t\t} else if (event.time < time && nextEvent.time > time){\n\t\t\t\treturn midPoint;\n\t\t\t} else if (event.time > time){\n\t\t\t\t//search lower\n\t\t\t\tend = midPoint;\n\t\t\t} else if (event.time < time){\n\t\t\t\t//search upper\n\t\t\t\tbeginning = midPoint + 1;\n\t\t\t} \n\t\t}\n\t\treturn -1;\n\t};\n\n\t/**\n\t * Internal iterator. Applies extra safety checks for \n\t * removing items from the array. \n\t * @param {Function} callback \n\t * @param {Number=} lowerBound \n\t * @param {Number=} upperBound \n\t * @private\n\t */\n\tTone.Timeline.prototype._iterate = function(callback, lowerBound, upperBound){\n\t\tthis._iterating = true;\n\t\tlowerBound = this.defaultArg(lowerBound, 0);\n\t\tupperBound = this.defaultArg(upperBound, this._timeline.length - 1);\n\t\tfor (var i = lowerBound; i <= upperBound; i++){\n\t\t\tcallback(this._timeline[i]);\n\t\t}\n\t\tthis._iterating = false;\n\t\tif (this._toRemove.length > 0){\n\t\t\tfor (var j = 0; j < this._toRemove.length; j++){\n\t\t\t\tvar index = this._timeline.indexOf(this._toRemove[j]);\n\t\t\t\tif (index !== -1){\n\t\t\t\t\tthis._timeline.splice(index, 1);\n\t\t\t\t}\n\t\t\t}\n\t\t\tthis._toRemove = [];\n\t\t}\n\t};\n\n\t/**\n\t * Iterate over everything in the array\n\t * @param {Function} callback The callback to invoke with every item\n\t * @returns {Tone.Timeline} this\n\t */\n\tTone.Timeline.prototype.forEach = function(callback){\n\t\tthis._iterate(callback);\n\t\treturn this;\n\t};\n\n\t/**\n\t * Iterate over everything in the array at or before the given time.\n\t * @param {Number} time The time to check if items are before\n\t * @param {Function} callback The callback to invoke with every item\n\t * @returns {Tone.Timeline} this\n\t */\n\tTone.Timeline.prototype.forEachBefore = function(time, callback){\n\t\t//iterate over the items in reverse so that removing an item doesn't break things\n\t\tvar upperBound = this._search(time);\n\t\tif (upperBound !== -1){\n\t\t\tthis._iterate(callback, 0, upperBound);\n\t\t}\n\t\treturn this;\n\t};\n\n\t/**\n\t * Iterate over everything in the array after the given time.\n\t * @param {Number} time The time to check if items are before\n\t * @param {Function} callback The callback to invoke with every item\n\t * @returns {Tone.Timeline} this\n\t */\n\tTone.Timeline.prototype.forEachAfter = function(time, callback){\n\t\t//iterate over the items in reverse so that removing an item doesn't break things\n\t\tvar lowerBound = this._search(time);\n\t\tthis._iterate(callback, lowerBound + 1);\n\t\treturn this;\n\t};\n\n\t/**\n\t * Iterate over everything in the array at or after the given time. Similar to \n\t * forEachAfter, but includes the item(s) at the given time.\n\t * @param {Number} time The time to check if items are before\n\t * @param {Function} callback The callback to invoke with every item\n\t * @returns {Tone.Timeline} this\n\t */\n\tTone.Timeline.prototype.forEachFrom = function(time, callback){\n\t\t//iterate over the items in reverse so that removing an item doesn't break things\n\t\tvar lowerBound = this._search(time);\n\t\t//work backwards until the event time is less than time\n\t\twhile (lowerBound >= 0 && this._timeline[lowerBound].time >= time){\n\t\t\tlowerBound--;\n\t\t}\n\t\tthis._iterate(callback, lowerBound + 1);\n\t\treturn this;\n\t};\n\n\t/**\n\t * Iterate over everything in the array at the given time\n\t * @param {Number} time The time to check if items are before\n\t * @param {Function} callback The callback to invoke with every item\n\t * @returns {Tone.Timeline} this\n\t */\n\tTone.Timeline.prototype.forEachAtTime = function(time, callback){\n\t\t//iterate over the items in reverse so that removing an item doesn't break things\n\t\tvar upperBound = this._search(time);\n\t\tif (upperBound !== -1){\n\t\t\tthis._iterate(function(event){\n\t\t\t\tif (event.time === time){\n\t\t\t\t\tcallback(event);\n\t\t\t\t} \n\t\t\t}, 0, upperBound);\n\t\t}\n\t\treturn this;\n\t};\n\n\t/**\n\t * Clean up.\n\t * @return {Tone.Timeline} this\n\t */\n\tTone.Timeline.prototype.dispose = function(){\n\t\tTone.prototype.dispose.call(this);\n\t\tthis._timeline = null;\n\t\tthis._toRemove = null;\n\t};\n\n\treturn Tone.Timeline;\n});","define([\"Tone/core/Tone\", \"Tone/signal/Multiply\", \"Tone/signal/Signal\"], function(Tone){\n\n\t\"use strict\";\n\n\t/**\n\t * @class Negate the incoming signal. i.e. an input signal of 10 will output -10\n\t *\n\t * @constructor\n\t * @extends {Tone.SignalBase}\n\t * @example\n\t * var neg = new Tone.Negate();\n\t * var sig = new Tone.Signal(-2).connect(neg);\n\t * //output of neg is positive 2. \n\t */\n\tTone.Negate = function(){\n\t\t/**\n\t\t * negation is done by multiplying by -1\n\t\t * @type {Tone.Multiply}\n\t\t * @private\n\t\t */\n\t\tthis._multiply = this.input = this.output = new Tone.Multiply(-1);\n\t};\n\n\tTone.extend(Tone.Negate, Tone.SignalBase);\n\n\t/**\n\t * clean up\n\t * @returns {Tone.Negate} this\n\t */\n\tTone.Negate.prototype.dispose = function(){\n\t\tTone.prototype.dispose.call(this);\n\t\tthis._multiply.dispose();\n\t\tthis._multiply = null;\n\t\treturn this;\n\t}; \n\n\treturn Tone.Negate;\n});","define([\"Tone/core/Tone\", \"Tone/signal/Signal\", \"Tone/signal/Multiply\", \"Tone/signal/WaveShaper\"], \nfunction(Tone){\n\n\t\"use strict\";\n\n\t/**\n\t * @class GreaterThanZero outputs 1 when the input is strictly greater than zero\n\t * \n\t * @constructor\n\t * @extends {Tone.SignalBase}\n\t * @example\n\t * var gt0 = new Tone.GreaterThanZero();\n\t * var sig = new Tone.Signal(0.01).connect(gt0);\n\t * //the output of gt0 is 1. \n\t * sig.value = 0;\n\t * //the output of gt0 is 0. \n\t */\n\tTone.GreaterThanZero = function(){\n\t\t\n\t\t/**\n\t\t * @type {Tone.WaveShaper}\n\t\t * @private\n\t\t */\n\t\tthis._thresh = this.output = new Tone.WaveShaper(function(val){\n\t\t\tif (val <= 0){\n\t\t\t\treturn 0;\n\t\t\t} else {\n\t\t\t\treturn 1;\n\t\t\t}\n\t\t}, 127);\n\n\t\t/**\n\t\t * scale the first thresholded signal by a large value.\n\t\t * this will help with values which are very close to 0\n\t\t * @type {Tone.Multiply}\n\t\t * @private\n\t\t */\n\t\tthis._scale = this.input = new Tone.Multiply(10000);\n\n\t\t//connections\n\t\tthis._scale.connect(this._thresh);\n\t};\n\n\tTone.extend(Tone.GreaterThanZero, Tone.SignalBase);\n\n\t/**\n\t * dispose method\n\t * @returns {Tone.GreaterThanZero} this\n\t */\n\tTone.GreaterThanZero.prototype.dispose = function(){\n\t\tTone.prototype.dispose.call(this);\n\t\tthis._scale.dispose();\n\t\tthis._scale = null;\n\t\tthis._thresh.dispose();\n\t\tthis._thresh = null;\n\t\treturn this;\n\t};\n\n\treturn Tone.GreaterThanZero;\n});","define([\"Tone/core/Tone\", \"Tone/signal/TimelineSignal\", \"Tone/core/TimelineState\", \n\t\"Tone/core/Emitter\", \"Tone/core/Context\"], function (Tone) {\n\n\t\"use strict\";\n\n\t/**\n\t * @class A sample accurate clock which provides a callback at the given rate. \n\t * While the callback is not sample-accurate (it is still susceptible to\n\t * loose JS timing), the time passed in as the argument to the callback\n\t * is precise. For most applications, it is better to use Tone.Transport\n\t * instead of the Clock by itself since you can synchronize multiple callbacks.\n\t *\n\t * \t@constructor\n\t * @extends {Tone.Emitter}\n\t * \t@param {function} callback The callback to be invoked with the time of the audio event\n\t * \t@param {Frequency} frequency The rate of the callback\n\t * \t@example\n\t * //the callback will be invoked approximately once a second\n\t * //and will print the time exactly once a second apart.\n\t * var clock = new Tone.Clock(function(time){\n\t * \tconsole.log(time);\n\t * }, 1);\n\t */\n\tTone.Clock = function(){\n\n\t\tTone.Emitter.call(this);\n\n\t\tvar options = this.optionsObject(arguments, [\"callback\", \"frequency\"], Tone.Clock.defaults);\n\n\t\t/**\n\t\t * The callback function to invoke at the scheduled tick.\n\t\t * @type {Function}\n\t\t */\n\t\tthis.callback = options.callback;\n\n\t\t/**\n\t\t * The next time the callback is scheduled.\n\t\t * @type {Number}\n\t\t * @private\n\t\t */\n\t\tthis._nextTick = 0;\n\n\t\t/**\n\t\t * The last state of the clock.\n\t\t * @type {State}\n\t\t * @private\n\t\t */\n\t\tthis._lastState = Tone.State.Stopped;\n\n\t\t/**\n\t\t * The rate the callback function should be invoked. \n\t\t * @type {BPM}\n\t\t * @signal\n\t\t */\n\t\tthis.frequency = new Tone.TimelineSignal(options.frequency, Tone.Type.Frequency);\n\t\tthis._readOnly(\"frequency\");\n\n\t\t/**\n\t\t * The number of times the callback was invoked. Starts counting at 0\n\t\t * and increments after the callback was invoked. \n\t\t * @type {Ticks}\n\t\t * @readOnly\n\t\t */\n\t\tthis.ticks = 0;\n\n\t\t/**\n\t\t * The state timeline\n\t\t * @type {Tone.TimelineState}\n\t\t * @private\n\t\t */\n\t\tthis._state = new Tone.TimelineState(Tone.State.Stopped);\n\n\t\t/**\n\t\t * The loop function bound to its context. \n\t\t * This is necessary to remove the event in the end.\n\t\t * @type {Function}\n\t\t * @private\n\t\t */\n\t\tthis._boundLoop = this._loop.bind(this);\n\n\t\t//bind a callback to the worker thread\n \tthis.context.on(\"tick\", this._boundLoop);\n\t};\n\n\tTone.extend(Tone.Clock, Tone.Emitter);\n\n\t/**\n\t * The defaults\n\t * @const\n\t * @type {Object}\n\t */\n\tTone.Clock.defaults = {\n\t\t\"callback\" : Tone.noOp,\n\t\t\"frequency\" : 1,\n\t\t\"lookAhead\" : \"auto\",\n\t};\n\n\t/**\n\t * Returns the playback state of the source, either \"started\", \"stopped\" or \"paused\".\n\t * @type {Tone.State}\n\t * @readOnly\n\t * @memberOf Tone.Clock#\n\t * @name state\n\t */\n\tObject.defineProperty(Tone.Clock.prototype, \"state\", {\n\t\tget : function(){\n\t\t\treturn this._state.getValueAtTime(this.now());\n\t\t}\n\t});\n\n\t/**\n\t * Start the clock at the given time. Optionally pass in an offset\n\t * of where to start the tick counter from.\n\t * @param {Time} time The time the clock should start\n\t * @param {Ticks=} offset Where the tick counter starts counting from.\n\t * @return {Tone.Clock} this\n\t */\n\tTone.Clock.prototype.start = function(time, offset){\n\t\ttime = this.toSeconds(time);\n\t\tif (this._state.getValueAtTime(time) !== Tone.State.Started){\n\t\t\tthis._state.add({\n\t\t\t\t\"state\" : Tone.State.Started, \n\t\t\t\t\"time\" : time,\n\t\t\t\t\"offset\" : offset\n\t\t\t});\n\t\t}\n\t\treturn this;\t\n\t};\n\n\t/**\n\t * Stop the clock. Stopping the clock resets the tick counter to 0.\n\t * @param {Time} [time=now] The time when the clock should stop.\n\t * @returns {Tone.Clock} this\n\t * @example\n\t * clock.stop();\n\t */\n\tTone.Clock.prototype.stop = function(time){\n\t\ttime = this.toSeconds(time);\n\t\tthis._state.cancel(time);\n\t\tthis._state.setStateAtTime(Tone.State.Stopped, time);\n\t\treturn this;\t\n\t};\n\n\n\t/**\n\t * Pause the clock. Pausing does not reset the tick counter.\n\t * @param {Time} [time=now] The time when the clock should stop.\n\t * @returns {Tone.Clock} this\n\t */\n\tTone.Clock.prototype.pause = function(time){\n\t\ttime = this.toSeconds(time);\n\t\tif (this._state.getValueAtTime(time) === Tone.State.Started){\n\t\t\tthis._state.setStateAtTime(Tone.State.Paused, time);\n\t\t}\n\t\treturn this;\t\n\t};\n\n\t/**\n\t * The scheduling loop.\n\t * @param {Number} time The current page time starting from 0\n\t * when the page was loaded.\n\t * @private\n\t */\n\tTone.Clock.prototype._loop = function(){\n\t\t//get the frequency value to compute the value of the next loop\n\t\tvar now = this.now();\n\t\t//if it's started\n\t\tvar lookAhead = this.context.lookAhead;\n\t\tvar updateInterval = this.context.updateInterval;\n\t\tvar lagCompensation = this.context.lag * 2;\n\t\tvar loopInterval = now + lookAhead + updateInterval + lagCompensation;\n\t\twhile (loopInterval > this._nextTick && this._state){\n\t\t\tvar currentState = this._state.getValueAtTime(this._nextTick);\n\t\t\tif (currentState !== this._lastState){\n\t\t\t\tthis._lastState = currentState;\n\t\t\t\tvar event = this._state.get(this._nextTick);\n\t\t\t\t// emit an event\n\t\t\t\tif (currentState === Tone.State.Started){\n\t\t\t\t\t//correct the time\n\t\t\t\t\tthis._nextTick = event.time;\n\t\t\t\t\tif (!this.isUndef(event.offset)){\n\t\t\t\t\t\tthis.ticks = event.offset;\n\t\t\t\t\t}\n\t\t\t\t\tthis.emit(\"start\", event.time, this.ticks);\n\t\t\t\t} else if (currentState === Tone.State.Stopped){\n\t\t\t\t\tthis.ticks = 0;\n\n\t\t\t\t\tthis.emit(\"stop\", event.time);\n\t\t\t\t} else if (currentState === Tone.State.Paused){\n\t\t\t\t\tthis.emit(\"pause\", event.time);\n\t\t\t\t}\n\t\t\t}\n\t\t\tvar tickTime = this._nextTick;\n\t\t\tif (this.frequency){\n\t\t\t\tthis._nextTick += 1 / this.frequency.getValueAtTime(this._nextTick);\n\t\t\t\tif (currentState === Tone.State.Started){\n\t\t\t\t\tthis.callback(tickTime);\n\t\t\t\t\tthis.ticks++;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t};\n\n\t/**\n\t * Returns the scheduled state at the given time.\n\t * @param {Time} time The time to query.\n\t * @return {String} The name of the state input in setStateAtTime.\n\t * @example\n\t * clock.start(\"+0.1\");\n\t * clock.getStateAtTime(\"+0.1\"); //returns \"started\"\n\t */\n\tTone.Clock.prototype.getStateAtTime = function(time){\n\t\ttime = this.toSeconds(time);\n\t\treturn this._state.getValueAtTime(time);\n\t};\n\n\t/**\n\t * Clean up\n\t * @returns {Tone.Clock} this\n\t */\n\tTone.Clock.prototype.dispose = function(){\n\t\tTone.Emitter.prototype.dispose.call(this);\n\t\tthis.context.off(\"tick\", this._boundLoop);\n\t\tthis._writable(\"frequency\");\n\t\tthis.frequency.dispose();\n\t\tthis.frequency = null;\n\t\tthis._boundLoop = null;\n\t\tthis._nextTick = Infinity;\n\t\tthis.callback = null;\n\t\tthis._state.dispose();\n\t\tthis._state = null;\n\t};\n\n\treturn Tone.Clock;\n});","'use strict';\r\ndefine(function (require) {\r\n\r\n var p5sound = require('master');\r\n var AudioVoice = require('audioVoice');\r\n var noteToFreq = require('helpers').noteToFreq;\r\n\r\n var DEFAULT_SUSTAIN = 0.15;\r\n\r\n /**\r\n * A MonoSynth is used as a single voice for sound synthesis.\r\n * This is a class to be used in conjunction with the PolySynth\r\n * class. Custom synthetisers should be built inheriting from\r\n * this class.\r\n *\r\n * @class p5.MonoSynth\r\n * @constructor\r\n * @example\r\n *
\r\n * var monoSynth;\r\n *\r\n * function setup() {\r\n * var cnv = createCanvas(100, 100);\r\n * cnv.mousePressed(playSynth);\r\n *\r\n * monoSynth = new p5.MonoSynth();\r\n *\r\n * textAlign(CENTER);\r\n * text('click to play', width/2, height/2);\r\n * }\r\n *\r\n * function playSynth() {\r\n * // time from now (in seconds)\r\n * var time = 0;\r\n * // note duration (in seconds)\r\n * var dur = 0.25;\r\n * // velocity (volume, from 0 to 1)\r\n * var v = 0.2;\r\n *\r\n * monoSynth.play(\"G3\", v, time, dur);\r\n * monoSynth.play(\"C4\", v, time += dur, dur);\r\n *\r\n * background(random(255), random(255), 255);\r\n * text('click to play', width/2, height/2);\r\n * }\r\n *
\r\n **/\r\n\r\n p5.MonoSynth = function () {\r\n AudioVoice.call(this);\r\n\r\n this.oscillator = new p5.Oscillator();\r\n\r\n this.env = new p5.Envelope();\r\n this.env.setRange(1, 0);\r\n this.env.setExp(true);\r\n\r\n //set params\r\n this.setADSR(0.02, 0.25, 0.05, 0.35);\r\n\r\n // oscillator --> env --> this.output (gain) --> p5.soundOut\r\n this.oscillator.disconnect();\r\n this.oscillator.connect(this.output);\r\n\r\n this.env.disconnect();\r\n this.env.setInput(this.output.gain);\r\n\r\n // reset oscillator gain to 1.0\r\n this.oscillator.output.gain.value = 1.0;\r\n\r\n this.oscillator.start();\r\n this.connect();\r\n\r\n p5sound.soundArray.push(this);\r\n };\r\n\r\n p5.MonoSynth.prototype = Object.create(p5.AudioVoice.prototype);\r\n\r\n /**\r\n * Play tells the MonoSynth to start playing a note. This method schedules\r\n * the calling of .triggerAttack and .triggerRelease.\r\n *\r\n * @method play\r\n * @for p5.MonoSynth\r\n * @param {String | Number} note the note you want to play, specified as a\r\n * frequency in Hertz (Number) or as a midi\r\n * value in Note/Octave format (\"C4\", \"Eb3\"...etc\")\r\n * See \r\n * Tone. Defaults to 440 hz.\r\n * @param {Number} [velocity] velocity of the note to play (ranging from 0 to 1)\r\n * @param {Number} [secondsFromNow] time from now (in seconds) at which to play\r\n * @param {Number} [sustainTime] time to sustain before releasing the envelope\r\n * @example\r\n *
\r\n * var monoSynth;\r\n *\r\n * function setup() {\r\n * var cnv = createCanvas(100, 100);\r\n * cnv.mousePressed(playSynth);\r\n *\r\n * monoSynth = new p5.MonoSynth();\r\n *\r\n * textAlign(CENTER);\r\n * text('click to play', width/2, height/2);\r\n * }\r\n *\r\n * function playSynth() {\r\n * // time from now (in seconds)\r\n * var time = 0;\r\n * // note duration (in seconds)\r\n * var dur = 1/6;\r\n * // note velocity (volume, from 0 to 1)\r\n * var v = random();\r\n *\r\n * monoSynth.play(\"Fb3\", v, 0, dur);\r\n * monoSynth.play(\"Gb3\", v, time += dur, dur);\r\n *\r\n * background(random(255), random(255), 255);\r\n * text('click to play', width/2, height/2);\r\n * }\r\n *
\r\n *\r\n */\r\n p5.MonoSynth.prototype.play = function (note, velocity, secondsFromNow, susTime) {\r\n this.triggerAttack(note, velocity, ~~secondsFromNow);\r\n this.triggerRelease(~~secondsFromNow + (susTime || DEFAULT_SUSTAIN));\r\n };\r\n\r\n /**\r\n * Trigger the Attack, and Decay portion of the Envelope.\r\n * Similar to holding down a key on a piano, but it will\r\n * hold the sustain level until you let go.\r\n *\r\n * @param {String | Number} note the note you want to play, specified as a\r\n * frequency in Hertz (Number) or as a midi\r\n * value in Note/Octave format (\"C4\", \"Eb3\"...etc\")\r\n * See \r\n * Tone. Defaults to 440 hz\r\n * @param {Number} [velocity] velocity of the note to play (ranging from 0 to 1)\r\n * @param {Number} [secondsFromNow] time from now (in seconds) at which to play\r\n * @method triggerAttack\r\n * @for p5.MonoSynth\r\n * @example\r\n *
\r\n * var monoSynth = new p5.MonoSynth();\r\n *\r\n * function mousePressed() {\r\n * monoSynth.triggerAttack(\"E3\");\r\n * }\r\n *\r\n * function mouseReleased() {\r\n * monoSynth.triggerRelease();\r\n * }\r\n *
\r\n */\r\n p5.MonoSynth.prototype.triggerAttack = function (note, velocity, secondsFromNow) {\r\n var secondsFromNow = ~~secondsFromNow;\r\n var freq = noteToFreq(note);\r\n var vel = velocity || 0.1;\r\n this.oscillator.freq(freq, 0, secondsFromNow);\r\n this.env.ramp(this.output.gain, secondsFromNow, vel);\r\n };\r\n\r\n /**\r\n * Trigger the release of the Envelope. This is similar to releasing\r\n * the key on a piano and letting the sound fade according to the\r\n * release level and release time.\r\n *\r\n * @param {Number} secondsFromNow time to trigger the release\r\n * @method triggerRelease\r\n * @for p5.MonoSynth\r\n * @example\r\n *
\r\n * var monoSynth = new p5.MonoSynth();\r\n *\r\n * function mousePressed() {\r\n * monoSynth.triggerAttack(\"E3\");\r\n * }\r\n *\r\n * function mouseReleased() {\r\n * monoSynth.triggerRelease();\r\n * }\r\n *
\r\n */\r\n p5.MonoSynth.prototype.triggerRelease = function (secondsFromNow) {\r\n var secondsFromNow = secondsFromNow || 0;\r\n this.env.ramp(this.output.gain, secondsFromNow, 0);\r\n };\r\n\r\n /**\r\n * Set values like a traditional\r\n * \r\n * ADSR envelope\r\n * .\r\n *\r\n * @method setADSR\r\n * @for p5.MonoSynth\r\n * @param {Number} attackTime Time (in seconds before envelope\r\n * reaches Attack Level\r\n * @param {Number} [decayTime] Time (in seconds) before envelope\r\n * reaches Decay/Sustain Level\r\n * @param {Number} [susRatio] Ratio between attackLevel and releaseLevel, on a scale from 0 to 1,\r\n * where 1.0 = attackLevel, 0.0 = releaseLevel.\r\n * The susRatio determines the decayLevel and the level at which the\r\n * sustain portion of the envelope will sustain.\r\n * For example, if attackLevel is 0.4, releaseLevel is 0,\r\n * and susAmt is 0.5, the decayLevel would be 0.2. If attackLevel is\r\n * increased to 1.0 (using setRange),\r\n * then decayLevel would increase proportionally, to become 0.5.\r\n * @param {Number} [releaseTime] Time in seconds from now (defaults to 0)\r\n */\r\n p5.MonoSynth.prototype.setADSR = function (attack,decay,sustain,release) {\r\n this.env.setADSR(attack, decay, sustain, release);\r\n };\r\n\r\n\r\n /**\r\n * Getters and Setters\r\n * @property {Number} attack\r\n * @for p5.MonoSynth\r\n */\r\n /**\r\n * @property {Number} decay\r\n * @for p5.MonoSynth\r\n */\r\n /**\r\n * @property {Number} sustain\r\n * @for p5.MonoSynth\r\n */\r\n /**\r\n * @property {Number} release\r\n * @for p5.MonoSynth\r\n */\r\n Object.defineProperties(p5.MonoSynth.prototype, {\r\n 'attack': {\r\n get : function() {\r\n return this.env.aTime;\r\n },\r\n set : function(attack) {\r\n this.env.setADSR(attack, this.env.dTime,\r\n this.env.sPercent, this.env.rTime);\r\n }\r\n },\r\n 'decay': {\r\n get : function() {\r\n return this.env.dTime;\r\n },\r\n set : function(decay) {\r\n this.env.setADSR(this.env.aTime, decay,\r\n this.env.sPercent, this.env.rTime);\r\n }\r\n },\r\n 'sustain': {\r\n get : function() {\r\n return this.env.sPercent;\r\n },\r\n set : function(sustain) {\r\n this.env.setADSR(this.env.aTime, this.env.dTime,\r\n sustain, this.env.rTime);\r\n }\r\n },\r\n 'release': {\r\n get : function() {\r\n return this.env.rTime;\r\n },\r\n set : function(release) {\r\n this.env.setADSR(this.env.aTime, this.env.dTime,\r\n this.env.sPercent, release);\r\n }\r\n },\r\n });\r\n\r\n\r\n /**\r\n * MonoSynth amp\r\n * @method amp\r\n * @for p5.MonoSynth\r\n * @param {Number} vol desired volume\r\n * @param {Number} [rampTime] Time to reach new volume\r\n * @return {Number} new volume value\r\n */\r\n p5.MonoSynth.prototype.amp = function(vol, rampTime) {\r\n var t = rampTime || 0;\r\n if (typeof vol !== 'undefined') {\r\n this.oscillator.amp(vol, t);\r\n }\r\n return this.oscillator.amp().value;\r\n };\r\n\r\n /**\r\n * Connect to a p5.sound / Web Audio object.\r\n *\r\n * @method connect\r\n * @for p5.MonoSynth\r\n * @param {Object} unit A p5.sound or Web Audio object\r\n */\r\n\r\n p5.MonoSynth.prototype.connect = function(unit) {\r\n var u = unit || p5sound.input;\r\n this.output.connect(u.input ? u.input : u);\r\n };\r\n\r\n /**\r\n * Disconnect all outputs\r\n *\r\n * @method disconnect\r\n * @for p5.MonoSynth\r\n */\r\n p5.MonoSynth.prototype.disconnect = function() {\r\n if (this.output) {\r\n this.output.disconnect();\r\n }\r\n };\r\n\r\n\r\n /**\r\n * Get rid of the MonoSynth and free up its resources / memory.\r\n *\r\n * @method dispose\r\n * @for p5.MonoSynth\r\n */\r\n p5.MonoSynth.prototype.dispose = function() {\r\n AudioVoice.prototype.dispose.apply(this);\r\n\r\n if (this.env) {\r\n this.env.dispose();\r\n }\r\n if (this.oscillator) {\r\n this.oscillator.dispose();\r\n }\r\n };\r\n\r\n});\r\n","'use strict';\r\ndefine(function() {\r\n var p5sound = require('master');\r\n\r\n /**\r\n * Base class for monophonic synthesizers. Any extensions of this class\r\n * should follow the API and implement the methods below in order to\r\n * remain compatible with p5.PolySynth();\r\n *\r\n * @class p5.AudioVoice\r\n * @constructor\r\n */\r\n p5.AudioVoice = function () {\r\n\t this.ac = p5sound.audiocontext;\r\n\t this.output = this.ac.createGain();\r\n\t this.connect();\r\n\t p5sound.soundArray.push(this);\r\n };\r\n\r\n p5.AudioVoice.prototype.play = function (note, velocity, secondsFromNow, sustime) {\r\n };\r\n\r\n p5.AudioVoice.prototype.triggerAttack = function (note, velocity, secondsFromNow) {\r\n };\r\n\r\n p5.AudioVoice.prototype.triggerRelease = function (secondsFromNow) {\r\n };\r\n\r\n p5.AudioVoice.prototype.amp = function(vol, rampTime) {\r\n };\r\n\r\n /**\r\n * Connect to p5 objects or Web Audio Nodes\r\n * @method connect\r\n * @for p5.AudioVoice\r\n * @param {Object} unit\r\n */\r\n p5.AudioVoice.prototype.connect = function(unit) {\r\n var u = unit || p5sound.input;\r\n this.output.connect(u.input ? u.input : u);\r\n };\r\n\r\n /**\r\n * Disconnect from soundOut\r\n * @method disconnect\r\n * @for p5.AudioVoice\r\n */\r\n p5.AudioVoice.prototype.disconnect = function() {\r\n this.output.disconnect();\r\n };\r\n\r\n p5.AudioVoice.prototype.dispose = function() {\r\n if (this.output) {\r\n this.output.disconnect();\r\n delete this.output;\r\n }\r\n };\r\n\r\n return p5.AudioVoice;\r\n});\r\n","'use strict';\r\ndefine(function (require) {\r\n\r\n var p5sound = require('master');\r\n var TimelineSignal = require('Tone/signal/TimelineSignal');\r\n var noteToFreq = require('helpers').noteToFreq;\r\n\r\n /**\r\n * An AudioVoice is used as a single voice for sound synthesis.\r\n * The PolySynth class holds an array of AudioVoice, and deals\r\n * with voices allocations, with setting notes to be played, and\r\n * parameters to be set.\r\n *\r\n * @class p5.PolySynth\r\n * @constructor\r\n *\r\n * @param {Number} [synthVoice] A monophonic synth voice inheriting\r\n * the AudioVoice class. Defaults to p5.MonoSynth\r\n * @param {Number} [maxVoices] Number of voices, defaults to 8;\r\n * @example\r\n *
\r\n * var polySynth;\r\n *\r\n * function setup() {\r\n * var cnv = createCanvas(100, 100);\r\n * cnv.mousePressed(playSynth);\r\n *\r\n * polySynth = new p5.PolySynth();\r\n *\r\n * textAlign(CENTER);\r\n * text('click to play', width/2, height/2);\r\n * }\r\n *\r\n * function playSynth() {\r\n * // note duration (in seconds)\r\n * var dur = 1.5;\r\n *\r\n * // time from now (in seconds)\r\n * var time = 0;\r\n *\r\n * // velocity (volume, from 0 to 1)\r\n * var vel = 0.1;\r\n *\r\n * // notes can overlap with each other\r\n * polySynth.play(\"G2\", vel, 0, dur);\r\n * polySynth.play(\"C3\", vel, time += 1/3, dur);\r\n * polySynth.play(\"G3\", vel, time += 1/3, dur);\r\n *\r\n * background(random(255), random(255), 255);\r\n * text('click to play', width/2, height/2);\r\n * }\r\n *
\r\n **/\r\n p5.PolySynth = function(audioVoice, maxVoices) {\r\n //audiovoices will contain maxVoices many monophonic synths\r\n this.audiovoices = [];\r\n\r\n /**\r\n * An object that holds information about which notes have been played and\r\n * which notes are currently being played. New notes are added as keys\r\n * on the fly. While a note has been attacked, but not released, the value of the\r\n * key is the audiovoice which is generating that note. When notes are released,\r\n * the value of the key becomes undefined.\r\n * @property notes\r\n */\r\n this.notes = {};\r\n\r\n //indices of the most recently used, and least recently used audiovoice\r\n this._newest = 0;\r\n this._oldest = 0;\r\n\r\n /**\r\n * A PolySynth must have at least 1 voice, defaults to 8\r\n * @property polyvalue\r\n */\r\n this.maxVoices = maxVoices || 8;\r\n\r\n /**\r\n * Monosynth that generates the sound for each note that is triggered. The\r\n * p5.PolySynth defaults to using the p5.MonoSynth as its voice.\r\n * @property AudioVoice\r\n */\r\n this.AudioVoice = audioVoice === undefined ? p5.MonoSynth : audioVoice;\r\n\r\n /**\r\n * This value must only change as a note is attacked or released. Due to delay\r\n * and sustain times, Tone.TimelineSignal is required to schedule the change in value.\r\n\t * @private\r\n * @property {Tone.TimelineSignal} _voicesInUse\r\n */\r\n this._voicesInUse = new TimelineSignal(0);\r\n\r\n this.output = p5sound.audiocontext.createGain();\r\n this.connect();\r\n\r\n //Construct the appropriate number of audiovoices\r\n this._allocateVoices();\r\n p5sound.soundArray.push(this);\r\n };\r\n\r\n /**\r\n * Construct the appropriate number of audiovoices\r\n * @private\r\n * @for p5.PolySynth\r\n * @method _allocateVoices\r\n */\r\n p5.PolySynth.prototype._allocateVoices = function() {\r\n for(var i = 0; i< this.maxVoices; i++) {\r\n this.audiovoices.push(new this.AudioVoice());\r\n this.audiovoices[i].disconnect();\r\n this.audiovoices[i].connect(this.output);\r\n }\r\n };\r\n\r\n /**\r\n * Play a note by triggering noteAttack and noteRelease with sustain time\r\n *\r\n * @method play\r\n * @for p5.PolySynth\r\n * @param {Number} [note] midi note to play (ranging from 0 to 127 - 60 being a middle C)\r\n * @param {Number} [velocity] velocity of the note to play (ranging from 0 to 1)\r\n * @param {Number} [secondsFromNow] time from now (in seconds) at which to play\r\n * @param {Number} [sustainTime] time to sustain before releasing the envelope\r\n * @example\r\n *
\r\n * var polySynth;\r\n *\r\n * function setup() {\r\n * var cnv = createCanvas(100, 100);\r\n * cnv.mousePressed(playSynth);\r\n *\r\n * polySynth = new p5.PolySynth();\r\n *\r\n * textAlign(CENTER);\r\n * text('click to play', width/2, height/2);\r\n * }\r\n *\r\n * function playSynth() {\r\n * // note duration (in seconds)\r\n * var dur = 0.1;\r\n *\r\n * // time from now (in seconds)\r\n * var time = 0;\r\n *\r\n * // velocity (volume, from 0 to 1)\r\n * var vel = 0.1;\r\n *\r\n * polySynth.play(\"G2\", vel, 0, dur);\r\n * polySynth.play(\"C3\", vel, 0, dur);\r\n * polySynth.play(\"G3\", vel, 0, dur);\r\n *\r\n * background(random(255), random(255), 255);\r\n * text('click to play', width/2, height/2);\r\n * }\r\n *
\r\n */\r\n p5.PolySynth.prototype.play = function (note,velocity, secondsFromNow, susTime) {\r\n var susTime = susTime || 1;\r\n this.noteAttack(note, velocity, secondsFromNow);\r\n this.noteRelease(note, secondsFromNow + susTime);\r\n };\r\n\r\n\r\n /**\r\n * noteADSR sets the envelope for a specific note that has just been triggered.\r\n * Using this method modifies the envelope of whichever audiovoice is being used\r\n * to play the desired note. The envelope should be reset before noteRelease is called\r\n * in order to prevent the modified envelope from being used on other notes.\r\n *\r\n * @method noteADSR\r\n * @for p5.PolySynth\r\n * @param {Number} [note] Midi note on which ADSR should be set.\r\n * @param {Number} [attackTime] Time (in seconds before envelope\r\n * reaches Attack Level\r\n * @param {Number} [decayTime] Time (in seconds) before envelope\r\n * reaches Decay/Sustain Level\r\n * @param {Number} [susRatio] Ratio between attackLevel and releaseLevel, on a scale from 0 to 1,\r\n * where 1.0 = attackLevel, 0.0 = releaseLevel.\r\n * The susRatio determines the decayLevel and the level at which the\r\n * sustain portion of the envelope will sustain.\r\n * For example, if attackLevel is 0.4, releaseLevel is 0,\r\n * and susAmt is 0.5, the decayLevel would be 0.2. If attackLevel is\r\n * increased to 1.0 (using setRange),\r\n * then decayLevel would increase proportionally, to become 0.5.\r\n * @param {Number} [releaseTime] Time in seconds from now (defaults to 0)\r\n **/\r\n\r\n p5.PolySynth.prototype.noteADSR = function (note,a,d,s,r,timeFromNow) {\r\n var now = p5sound.audiocontext.currentTime;\r\n var timeFromNow = timeFromNow || 0;\r\n var t = now + timeFromNow\r\n this.audiovoices[ this.notes[note].getValueAtTime(t) ].setADSR(a,d,s,r);\r\n };\r\n\r\n\r\n /**\r\n * Set the PolySynths global envelope. This method modifies the envelopes of each\r\n * monosynth so that all notes are played with this envelope.\r\n *\r\n * @method setADSR\r\n * @for p5.PolySynth\r\n * @param {Number} [attackTime] Time (in seconds before envelope\r\n * reaches Attack Level\r\n * @param {Number} [decayTime] Time (in seconds) before envelope\r\n * reaches Decay/Sustain Level\r\n * @param {Number} [susRatio] Ratio between attackLevel and releaseLevel, on a scale from 0 to 1,\r\n * where 1.0 = attackLevel, 0.0 = releaseLevel.\r\n * The susRatio determines the decayLevel and the level at which the\r\n * sustain portion of the envelope will sustain.\r\n * For example, if attackLevel is 0.4, releaseLevel is 0,\r\n * and susAmt is 0.5, the decayLevel would be 0.2. If attackLevel is\r\n * increased to 1.0 (using setRange),\r\n * then decayLevel would increase proportionally, to become 0.5.\r\n * @param {Number} [releaseTime] Time in seconds from now (defaults to 0)\r\n **/\r\n p5.PolySynth.prototype.setADSR = function(a,d,s,r) {\r\n this.audiovoices.forEach(function(voice) {\r\n voice.setADSR(a,d,s,r);\r\n });\r\n };\r\n\r\n /**\r\n * Trigger the Attack, and Decay portion of a MonoSynth.\r\n * Similar to holding down a key on a piano, but it will\r\n * hold the sustain level until you let go.\r\n *\r\n * @method noteAttack\r\n * @for p5.PolySynth\r\n * @param {Number} [note] midi note on which attack should be triggered.\r\n * @param {Number} [velocity] velocity of the note to play (ranging from 0 to 1)/\r\n * @param {Number} [secondsFromNow] time from now (in seconds)\r\n * @example\r\n *
\r\n * var polySynth = new p5.PolySynth();\r\n * var pitches = [\"G\", \"D\", \"G\", \"C\"];\r\n * var octaves = [2, 3, 4];\r\n *\r\n * function mousePressed() {\r\n * // play a chord: multiple notes at the same time\r\n * for (var i = 0; i < 4; i++) {\r\n * var note = random(pitches) + random(octaves);\r\n * polySynth.noteAttack(note, 0.1);\r\n * }\r\n * }\r\n *\r\n * function mouseReleased() {\r\n * // release all voices\r\n * polySynth.noteRelease();\r\n * }\r\n *
\r\n */\r\n p5.PolySynth.prototype.noteAttack = function (_note, _velocity, secondsFromNow) {\r\n //this value goes to the audiovoices which handle their own scheduling\r\n var secondsFromNow = ~~secondsFromNow;\r\n\r\n //this value is used by this._voicesInUse\r\n var acTime = p5sound.audiocontext.currentTime + secondsFromNow;\r\n\r\n //Convert note to frequency if necessary. This is because entries into this.notes\r\n //should be based on frequency for the sake of consistency.\r\n var note = noteToFreq(_note);\r\n var velocity = _velocity || 0.1;\r\n\r\n var currentVoice;\r\n\r\n //Release the note if it is already playing\r\n if (this.notes[note] && this.notes[note].getValueAtTime(acTime) !== null) {\r\n this.noteRelease(note, 0);\r\n }\r\n\r\n //Check to see how many voices are in use at the time the note will start\r\n if (this._voicesInUse.getValueAtTime(acTime) < this.maxVoices) {\r\n currentVoice = Math.max(~~this._voicesInUse.getValueAtTime(acTime), 0);\r\n }\r\n //If we are exceeding the polyvalue, bump off the oldest notes and replace\r\n //with a new note\r\n else {\r\n currentVoice = this._oldest;\r\n\r\n var oldestNote = p5.prototype.freqToMidi(this.audiovoices[this._oldest].oscillator.freq().value);\r\n this.noteRelease(oldestNote);\r\n this._oldest = ( this._oldest + 1 ) % (this.maxVoices - 1);\r\n }\r\n\r\n //Overrite the entry in the notes object. A note (frequency value)\r\n //corresponds to the index of the audiovoice that is playing it\r\n this.notes[note] = new TimelineSignal();\r\n this.notes[note].setValueAtTime(currentVoice, acTime);\r\n\r\n //Find the scheduled change in this._voicesInUse that will be previous to this new note\r\n //Add 1 and schedule this value at time 't', when this note will start playing\r\n var previousVal = this._voicesInUse._searchBefore(acTime) === null ? 0 : this._voicesInUse._searchBefore(acTime).value;\r\n this._voicesInUse.setValueAtTime(previousVal + 1, acTime);\r\n\r\n //Then update all scheduled values that follow to increase by 1\r\n this._updateAfter(acTime, 1);\r\n\r\n this._newest = currentVoice;\r\n //The audiovoice handles the actual scheduling of the note\r\n if (typeof velocity === 'number') {\r\n var maxRange = 1 / this._voicesInUse.getValueAtTime(acTime) * 2;\r\n velocity = velocity > maxRange ? maxRange : velocity;\r\n }\r\n this.audiovoices[currentVoice].triggerAttack(note, velocity, secondsFromNow);\r\n };\r\n\r\n /**\r\n * Private method to ensure accurate values of this._voicesInUse\r\n * Any time a new value is scheduled, it is necessary to increment all subsequent\r\n * scheduledValues after attack, and decrement all subsequent\r\n * scheduledValues after release\r\n *\r\n * @private\r\n * @for p5.PolySynth\r\n * @param {[type]} time [description]\r\n * @param {[type]} value [description]\r\n * @return {[type]} [description]\r\n */\r\n p5.PolySynth.prototype._updateAfter = function(time, value) {\r\n if(this._voicesInUse._searchAfter(time) === null) {\r\n return;\r\n } else{\r\n this._voicesInUse._searchAfter(time).value += value;\r\n var nextTime = this._voicesInUse._searchAfter(time).time;\r\n this._updateAfter(nextTime, value);\r\n }\r\n };\r\n\r\n\r\n /**\r\n * Trigger the Release of an AudioVoice note. This is similar to releasing\r\n * the key on a piano and letting the sound fade according to the\r\n * release level and release time.\r\n *\r\n * @method noteRelease\r\n * @for p5.PolySynth\r\n * @param {Number} [note] midi note on which attack should be triggered.\r\n * If no value is provided, all notes will be released.\r\n * @param {Number} [secondsFromNow] time to trigger the release\r\n * @example\r\n *
\r\n * var pitches = [\"G\", \"D\", \"G\", \"C\"];\r\n * var octaves = [2, 3, 4];\r\n * var polySynth = new p5.PolySynth();\r\n *\r\n * function mousePressed() {\r\n * // play a chord: multiple notes at the same time\r\n * for (var i = 0; i < 4; i++) {\r\n * var note = random(pitches) + random(octaves);\r\n * polySynth.noteAttack(note, 0.1);\r\n * }\r\n * }\r\n *\r\n * function mouseReleased() {\r\n * // release all voices\r\n * polySynth.noteRelease();\r\n * }\r\n *
\r\n *\r\n */\r\n p5.PolySynth.prototype.noteRelease = function (_note,secondsFromNow) {\r\n var now = p5sound.audiocontext.currentTime;\r\n var tFromNow = secondsFromNow || 0;\r\n var t = now + tFromNow;\r\n\r\n // if a note value is not provided, release all voices\r\n if (!_note) {\r\n this.audiovoices.forEach(function(voice) {\r\n voice.triggerRelease(tFromNow)\r\n });\r\n this._voicesInUse.setValueAtTime(0, t);\r\n for (var n in this.notes) {\r\n this.notes[n].dispose();\r\n delete this.notes[n];\r\n }\r\n return;\r\n }\r\n\r\n //Make sure note is in frequency inorder to query the this.notes object\r\n var note = noteToFreq(_note);\r\n\r\n if (!this.notes[note] || this.notes[note].getValueAtTime(t) === null) {\r\n console.warn('Cannot release a note that is not already playing');\r\n } else {\r\n //Find the scheduled change in this._voicesInUse that will be previous to this new note\r\n //subtract 1 and schedule this value at time 't', when this note will stop playing\r\n var previousVal = Math.max(~~this._voicesInUse.getValueAtTime(t).value, 1);\r\n this._voicesInUse.setValueAtTime(previousVal - 1, t);\r\n //Then update all scheduled values that follow to decrease by 1 but never go below 0\r\n if (previousVal > 0) {\r\n this._updateAfter(t, -1);\r\n }\r\n\r\n this.audiovoices[ this.notes[note].getValueAtTime(t) ].triggerRelease(tFromNow);\r\n this.notes[note].dispose();\r\n delete this.notes[note];\r\n\r\n this._newest = this._newest === 0 ? 0 : (this._newest - 1) % (this.maxVoices - 1);\r\n }\r\n\r\n };\r\n\r\n /**\r\n * Connect to a p5.sound / Web Audio object.\r\n *\r\n * @method connect\r\n * @for p5.PolySynth\r\n * @param {Object} unit A p5.sound or Web Audio object\r\n */\r\n p5.PolySynth.prototype.connect = function (unit) {\r\n var u = unit || p5sound.input;\r\n this.output.connect(u.input ? u.input : u);\r\n };\r\n\r\n /**\r\n * Disconnect all outputs\r\n *\r\n * @method disconnect\r\n * @for p5.PolySynth\r\n */\r\n p5.PolySynth.prototype.disconnect = function() {\r\n if (this.output) {\r\n this.output.disconnect();\r\n }\r\n };\r\n\r\n /**\r\n * Get rid of the MonoSynth and free up its resources / memory.\r\n *\r\n * @method dispose\r\n * @for p5.PolySynth\r\n */\r\n p5.PolySynth.prototype.dispose = function() {\r\n this.audiovoices.forEach(function(voice) {\r\n voice.dispose();\r\n });\r\n\r\n if (this.output) {\r\n this.output.disconnect();\r\n delete this.output;\r\n }\r\n };\r\n\r\n});\r\n","'use strict';\r\n\r\ndefine(function (require) {\r\n\r\n require('audioworklet-polyfill');\r\n require('shims');\r\n require('audiocontext');\r\n var p5SOUND = require('master');\r\n require('helpers');\r\n require('errorHandler');\r\n require('audioWorklet');\r\n require('panner');\r\n require('soundfile');\r\n require('amplitude');\r\n require('fft');\r\n require('signal');\r\n require('oscillator');\r\n require('envelope');\r\n require('pulse');\r\n require('noise');\r\n require('audioin');\r\n require('filter');\r\n require('eq');\r\n require('panner3d');\r\n require('listener3d');\r\n require('delay');\r\n require('reverb');\r\n require('metro');\r\n require('looper');\r\n require('soundLoop');\r\n require('compressor');\r\n require('soundRecorder');\r\n require('peakDetect');\r\n require('gain');\r\n require('monosynth');\r\n require('polysynth');\r\n require('distortion');\r\n require('audioVoice');\r\n require('monosynth');\r\n require('polysynth');\r\n\r\n return p5SOUND;\r\n\r\n});\r\n","!function(){var e,t=[];function r(e){var r=this,n={},i=-1;this.parameters.forEach(function(e,o){var s=t[++i]||(t[i]=new Float32Array(r.bufferSize));s.fill(e.value),n[o]=s}),this.processor.realm.exec(\"self.sampleRate=sampleRate=\"+this.context.sampleRate+\";self.currentTime=currentTime=\"+this.context.currentTime);var s=o(e.inputBuffer),a=o(e.outputBuffer);this.instance.process([s],[a],n)}function o(e){for(var t=[],r=0;r= this.sampleLimit) {\\n this.stop();\\n return true;\\n }\\n\\n var input = inputs[0];\\n var output = outputs[0];\\n\\n for (var channel = 0; channel < output.length; ++channel) {\\n var inputChannel = input[channel];\\n\\n if (channel === 0) {\\n this.leftBuffers.push(inputChannel);\\n\\n if (this.numInputChannels === 1) {\\n this.rightBuffers.push(inputChannel);\\n }\\n } else if (channel === 1 && this.numInputChannels > 1) {\\n this.rightBuffers.push(inputChannel);\\n }\\n }\\n\\n this.recordedSamples += output[0].length;\\n return true;\\n }\\n }, {\\n key: \\\"record\\\",\\n value: function record(duration) {\\n if (duration) {\\n this.sampleLimit = Math.round(duration * sampleRate);\\n }\\n\\n this.recording = true;\\n }\\n }, {\\n key: \\\"stop\\\",\\n value: function stop() {\\n this.recording = false;\\n var buffers = this.getBuffers();\\n var leftBuffer = buffers[0].buffer;\\n var rightBuffer = buffers[1].buffer;\\n this.port.postMessage({\\n name: 'buffers',\\n leftBuffer: leftBuffer,\\n rightBuffer: rightBuffer\\n }, [leftBuffer, rightBuffer]);\\n this.clear();\\n }\\n }, {\\n key: \\\"getBuffers\\\",\\n value: function getBuffers() {\\n var buffers = [];\\n buffers.push(this.mergeBuffers(this.leftBuffers));\\n buffers.push(this.mergeBuffers(this.rightBuffers));\\n return buffers;\\n }\\n }, {\\n key: \\\"mergeBuffers\\\",\\n value: function mergeBuffers(channelBuffer) {\\n var result = new Float32Array(this.recordedSamples);\\n var offset = 0;\\n var lng = channelBuffer.length;\\n\\n for (var i = 0; i < lng; i++) {\\n var buffer = channelBuffer[i];\\n result.set(buffer, offset);\\n offset += buffer.length;\\n }\\n\\n return result;\\n }\\n }, {\\n key: \\\"clear\\\",\\n value: function clear() {\\n this.leftBuffers = [];\\n this.rightBuffers = [];\\n this.recordedSamples = 0;\\n this.sampleLimit = null;\\n }\\n }]);\\n\\n return RecorderProcessor;\\n}(_wrapNativeSuper(AudioWorkletProcessor));\\n\\nregisterProcessor(processorNames.recorderProcessor, RecorderProcessor);\"","export default \"function _typeof(obj) { if (typeof Symbol === \\\"function\\\" && typeof Symbol.iterator === \\\"symbol\\\") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === \\\"function\\\" && obj.constructor === Symbol && obj !== Symbol.prototype ? \\\"symbol\\\" : typeof obj; }; } return _typeof(obj); }\\n\\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\\\"Cannot call a class as a function\\\"); } }\\n\\nfunction _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if (\\\"value\\\" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }\\n\\nfunction _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }\\n\\nfunction _possibleConstructorReturn(self, call) { if (call && (_typeof(call) === \\\"object\\\" || typeof call === \\\"function\\\")) { return call; } return _assertThisInitialized(self); }\\n\\nfunction _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError(\\\"this hasn't been initialised - super() hasn't been called\\\"); } return self; }\\n\\nfunction _inherits(subClass, superClass) { if (typeof superClass !== \\\"function\\\" && superClass !== null) { throw new TypeError(\\\"Super expression must either be null or a function\\\"); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, writable: true, configurable: true } }); if (superClass) _setPrototypeOf(subClass, superClass); }\\n\\nfunction _wrapNativeSuper(Class) { var _cache = typeof Map === \\\"function\\\" ? new Map() : undefined; _wrapNativeSuper = function _wrapNativeSuper(Class) { if (Class === null || !_isNativeFunction(Class)) return Class; if (typeof Class !== \\\"function\\\") { throw new TypeError(\\\"Super expression must either be null or a function\\\"); } if (typeof _cache !== \\\"undefined\\\") { if (_cache.has(Class)) return _cache.get(Class); _cache.set(Class, Wrapper); } function Wrapper() { return _construct(Class, arguments, _getPrototypeOf(this).constructor); } Wrapper.prototype = Object.create(Class.prototype, { constructor: { value: Wrapper, enumerable: false, writable: true, configurable: true } }); return _setPrototypeOf(Wrapper, Class); }; return _wrapNativeSuper(Class); }\\n\\nfunction isNativeReflectConstruct() { if (typeof Reflect === \\\"undefined\\\" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === \\\"function\\\") return true; try { Date.prototype.toString.call(Reflect.construct(Date, [], function () {})); return true; } catch (e) { return false; } }\\n\\nfunction _construct(Parent, args, Class) { if (isNativeReflectConstruct()) { _construct = Reflect.construct; } else { _construct = function _construct(Parent, args, Class) { var a = [null]; a.push.apply(a, args); var Constructor = Function.bind.apply(Parent, a); var instance = new Constructor(); if (Class) _setPrototypeOf(instance, Class.prototype); return instance; }; } return _construct.apply(null, arguments); }\\n\\nfunction _isNativeFunction(fn) { return Function.toString.call(fn).indexOf(\\\"[native code]\\\") !== -1; }\\n\\nfunction _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); }\\n\\nfunction _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); }; return _getPrototypeOf(o); }\\n\\n// import processor name via preval.require so that it's available as a value at compile time\\nvar processorNames = {\\n \\\"recorderProcessor\\\": \\\"recorder-processor\\\",\\n \\\"soundFileProcessor\\\": \\\"sound-file-processor\\\",\\n \\\"amplitudeProcessor\\\": \\\"amplitude-processor\\\"\\n};\\n\\nvar SoundFileProcessor =\\n/*#__PURE__*/\\nfunction (_AudioWorkletProcesso) {\\n _inherits(SoundFileProcessor, _AudioWorkletProcesso);\\n\\n function SoundFileProcessor() {\\n _classCallCheck(this, SoundFileProcessor);\\n\\n return _possibleConstructorReturn(this, _getPrototypeOf(SoundFileProcessor).apply(this, arguments));\\n }\\n\\n _createClass(SoundFileProcessor, [{\\n key: \\\"process\\\",\\n value: function process(inputs) {\\n var input = inputs[0];\\n var inputChannel = input[0];\\n var position = inputChannel[inputChannel.length - 1] || 0;\\n this.port.postMessage({\\n name: 'position',\\n position: position\\n });\\n return true;\\n }\\n }]);\\n\\n return SoundFileProcessor;\\n}(_wrapNativeSuper(AudioWorkletProcessor));\\n\\nregisterProcessor(processorNames.soundFileProcessor, SoundFileProcessor);\"","'use strict';\r\n\r\ndefine(function (require) {\r\n\r\n var p5sound = require('master');\r\n var ac = p5sound.audiocontext;\r\n\r\n // Stereo panner\r\n // if there is a stereo panner node use it\r\n if(typeof ac.createStereoPanner !== 'undefined') {\r\n p5.Panner = function (input, output) {\r\n this.stereoPanner = this.input = ac.createStereoPanner();\r\n input.connect(this.stereoPanner);\r\n this.stereoPanner.connect(output);\r\n };\r\n\r\n p5.Panner.prototype.pan = function(val, tFromNow) {\r\n var time = tFromNow || 0;\r\n var t = ac.currentTime + time;\r\n\r\n this.stereoPanner.pan.linearRampToValueAtTime(val, t);\r\n };\r\n\r\n //not implemented because stereopanner\r\n //node does not require this and will automatically\r\n //convert single channel or multichannel to stereo.\r\n //tested with single and stereo, not with (>2) multichannel\r\n p5.Panner.prototype.inputChannels = function() {};\r\n\r\n p5.Panner.prototype.connect = function(obj) {\r\n this.stereoPanner.connect(obj);\r\n };\r\n\r\n p5.Panner.prototype.disconnect = function() {\r\n if (this.stereoPanner) {\r\n this.stereoPanner.disconnect();\r\n }\r\n };\r\n\r\n } else {\r\n // if there is no createStereoPanner object\r\n // such as in safari 7.1.7 at the time of writing this\r\n // use this method to create the effect\r\n p5.Panner = function(input, output, numInputChannels) {\r\n this.input = ac.createGain();\r\n input.connect(this.input);\r\n\r\n this.left = ac.createGain();\r\n this.right = ac.createGain();\r\n this.left.channelInterpretation = 'discrete';\r\n this.right.channelInterpretation = 'discrete';\r\n\r\n // if input is stereo\r\n if (numInputChannels > 1) {\r\n this.splitter = ac.createChannelSplitter(2);\r\n this.input.connect(this.splitter);\r\n\r\n this.splitter.connect(this.left, 1);\r\n this.splitter.connect(this.right, 0);\r\n }\r\n else {\r\n this.input.connect(this.left);\r\n this.input.connect(this.right);\r\n }\r\n\r\n this.output = ac.createChannelMerger(2);\r\n this.left.connect(this.output, 0, 1);\r\n this.right.connect(this.output, 0, 0);\r\n this.output.connect(output);\r\n };\r\n\r\n // -1 is left, +1 is right\r\n p5.Panner.prototype.pan = function(val, tFromNow) {\r\n var time = tFromNow || 0;\r\n var t = ac.currentTime + time;\r\n var v = (val + 1) / 2;\r\n var rightVal = Math.cos(v*Math.PI/2);\r\n var leftVal = Math.sin(v * Math.PI/2);\r\n this.left.gain.linearRampToValueAtTime(leftVal, t);\r\n this.right.gain.linearRampToValueAtTime(rightVal, t);\r\n };\r\n\r\n p5.Panner.prototype.inputChannels = function(numChannels) {\r\n if (numChannels === 1) {\r\n this.input.disconnect();\r\n this.input.connect(this.left);\r\n this.input.connect(this.right);\r\n } else if (numChannels === 2) {\r\n if (typeof(this.splitter === 'undefined')) {\r\n this.splitter = ac.createChannelSplitter(2);\r\n }\r\n this.input.disconnect();\r\n this.input.connect(this.splitter);\r\n this.splitter.connect(this.left, 1);\r\n this.splitter.connect(this.right, 0);\r\n }\r\n };\r\n\r\n p5.Panner.prototype.connect = function(obj) {\r\n this.output.connect(obj);\r\n };\r\n\r\n p5.Panner.prototype.disconnect = function() {\r\n if (this.output) {\r\n this.output.disconnect();\r\n }\r\n };\r\n }\r\n});\r\n","'use strict';\r\n\r\ndefine(function (require) {\r\n\r\n var CustomError = require('errorHandler');\r\n var p5sound = require('master');\r\n var ac = p5sound.audiocontext;\r\n var midiToFreq = require('helpers').midiToFreq;\r\n var convertToWav = require('helpers').convertToWav;\r\n var processorNames = require('./audioWorklet/processorNames');\r\n\r\n /**\r\n *
SoundFile object with a path to a file.
\r\n *\r\n *
The p5.SoundFile may not be available immediately because\r\n * it loads the file information asynchronously.
\r\n *\r\n *
To do something with the sound as soon as it loads\r\n * pass the name of a function as the second parameter.
\r\n *\r\n *
Only one file path is required. However, audio file formats\r\n * (i.e. mp3, ogg, wav and m4a/aac) are not supported by all\r\n * web browsers. If you want to ensure compatability, instead of a single\r\n * file path, you may include an Array of filepaths, and the browser will\r\n * choose a format that works.
\r\n *\r\n * @class p5.SoundFile\r\n * @constructor\r\n * @param {String|Array} path path to a sound file (String). Optionally,\r\n * you may include multiple file formats in\r\n * an array. Alternately, accepts an object\r\n * from the HTML5 File API, or a p5.File.\r\n * @param {Function} [successCallback] Name of a function to call once file loads\r\n * @param {Function} [errorCallback] Name of a function to call if file fails to\r\n * load. This function will receive an error or\r\n * XMLHttpRequest object with information\r\n * about what went wrong.\r\n * @param {Function} [whileLoadingCallback] Name of a function to call while file\r\n * is loading. That function will\r\n * receive progress of the request to\r\n * load the sound file\r\n * (between 0 and 1) as its first\r\n * parameter. This progress\r\n * does not account for the additional\r\n * time needed to decode the audio data.\r\n *\r\n * @example\r\n *
\r\n */\r\n p5.SoundFile = function(paths, onload, onerror, whileLoading) {\r\n if (typeof paths !== 'undefined') {\r\n if (typeof paths === 'string' || typeof paths[0] === 'string') {\r\n var path = p5.prototype._checkFileFormats(paths);\r\n this.url = path;\r\n }\r\n else if(typeof paths === 'object') {\r\n if (!(window.File && window.FileReader && window.FileList && window.Blob)) {\r\n // The File API isn't supported in this browser\r\n throw 'Unable to load file because the File API is not supported';\r\n }\r\n }\r\n\r\n // if type is a p5.File...get the actual file\r\n if (paths.file) {\r\n paths = paths.file;\r\n }\r\n\r\n this.file = paths;\r\n }\r\n\r\n // private _onended callback, set by the method: onended(callback)\r\n this._onended = function() {};\r\n\r\n this._looping = false;\r\n this._playing = false;\r\n this._paused = false;\r\n this._pauseTime = 0;\r\n\r\n // cues for scheduling events with addCue() removeCue()\r\n this._cues = [];\r\n this._cueIDCounter = 0;\r\n\r\n // position of the most recently played sample\r\n this._lastPos = 0;\r\n this._counterNode = null;\r\n this._workletNode = null;\r\n\r\n // array of sources so that they can all be stopped!\r\n this.bufferSourceNodes = [];\r\n\r\n // current source\r\n this.bufferSourceNode = null;\r\n\r\n this.buffer = null;\r\n this.playbackRate = 1;\r\n\r\n this.input = p5sound.audiocontext.createGain();\r\n this.output = p5sound.audiocontext.createGain();\r\n\r\n this.reversed = false;\r\n\r\n // start and end of playback / loop\r\n this.startTime = 0;\r\n this.endTime = null;\r\n this.pauseTime = 0;\r\n\r\n // \"restart\" would stop playback before retriggering\r\n this.mode = 'sustain';\r\n\r\n // time that playback was started, in millis\r\n this.startMillis = null;\r\n\r\n // stereo panning\r\n this.panPosition = 0.0;\r\n this.panner = new p5.Panner(this.output, p5sound.input, 2);\r\n\r\n // it is possible to instantiate a soundfile with no path\r\n if (this.url || this.file) {\r\n this.load(onload, onerror);\r\n }\r\n\r\n // add this p5.SoundFile to the soundArray\r\n p5sound.soundArray.push(this);\r\n\r\n if (typeof whileLoading === 'function') {\r\n this._whileLoading = whileLoading;\r\n } else {\r\n this._whileLoading = function() {};\r\n }\r\n\r\n this._onAudioProcess = _onAudioProcess.bind(this);\r\n this._clearOnEnd = _clearOnEnd.bind(this);\r\n };\r\n\r\n // register preload handling of loadSound\r\n p5.prototype.registerPreloadMethod('loadSound', p5.prototype);\r\n\r\n /**\r\n * loadSound() returns a new p5.SoundFile from a specified\r\n * path. If called during preload(), the p5.SoundFile will be ready\r\n * to play in time for setup() and draw(). If called outside of\r\n * preload, the p5.SoundFile will not be ready immediately, so\r\n * loadSound accepts a callback as the second parameter. Using a\r\n * \r\n * local server is recommended when loading external files.\r\n *\r\n * @method loadSound\r\n * @for p5\r\n * @param {String|Array} path Path to the sound file, or an array with\r\n * paths to soundfiles in multiple formats\r\n * i.e. ['sound.ogg', 'sound.mp3'].\r\n * Alternately, accepts an object: either\r\n * from the HTML5 File API, or a p5.File.\r\n * @param {Function} [successCallback] Name of a function to call once file loads\r\n * @param {Function} [errorCallback] Name of a function to call if there is\r\n * an error loading the file.\r\n * @param {Function} [whileLoading] Name of a function to call while file is loading.\r\n * This function will receive the percentage loaded\r\n * so far, from 0.0 to 1.0.\r\n * @return {SoundFile} Returns a p5.SoundFile\r\n * @example\r\n *
\r\n */\r\n p5.prototype.loadSound = function(path, callback, onerror, whileLoading) {\r\n // if loading locally without a server\r\n if (window.location.origin.indexOf('file://') > -1 && window.cordova === 'undefined' ) {\r\n window.alert('This sketch may require a server to load external files. Please see http://bit.ly/1qcInwS');\r\n }\r\n\r\n var self = this;\r\n var s = new p5.SoundFile(path, function() {\r\n if(typeof callback === 'function') {\r\n callback.apply(self, arguments);\r\n }\r\n\r\n if (typeof self._decrementPreload === 'function') {\r\n self._decrementPreload();\r\n }\r\n }, onerror, whileLoading);\r\n\r\n return s;\r\n };\r\n\r\n /**\r\n * This is a helper function that the p5.SoundFile calls to load\r\n * itself. Accepts a callback (the name of another function)\r\n * as an optional parameter.\r\n *\r\n * @private\r\n * @for p5.SoundFile\r\n * @param {Function} [successCallback] Name of a function to call once file loads\r\n * @param {Function} [errorCallback] Name of a function to call if there is an error\r\n */\r\n p5.SoundFile.prototype.load = function(callback, errorCallback) {\r\n var self = this;\r\n var errorTrace = new Error().stack;\r\n\r\n if (this.url !== undefined && this.url !== '') {\r\n var request = new XMLHttpRequest();\r\n request.addEventListener('progress', function(evt) {\r\n self._updateProgress(evt);\r\n }, false);\r\n request.open('GET', this.url, true);\r\n request.responseType = 'arraybuffer';\r\n\r\n request.onload = function() {\r\n if (request.status === 200) {\r\n // on sucess loading file:\r\n if (!self.panner) return;\r\n ac.decodeAudioData(request.response,\r\n // success decoding buffer:\r\n function(buff) {\r\n if (!self.panner) return;\r\n self.buffer = buff;\r\n self.panner.inputChannels(buff.numberOfChannels);\r\n if (callback) {\r\n callback(self);\r\n }\r\n },\r\n // error decoding buffer. \"e\" is undefined in Chrome 11/22/2015\r\n function() {\r\n if (!self.panner) return;\r\n var err = new CustomError('decodeAudioData', errorTrace, self.url);\r\n var msg = 'AudioContext error at decodeAudioData for ' + self.url;\r\n if (errorCallback) {\r\n err.msg = msg;\r\n errorCallback(err);\r\n } else {\r\n console.error(msg +'\\n The error stack trace includes: \\n' + err.stack);\r\n }\r\n }\r\n );\r\n }\r\n // if request status != 200, it failed\r\n else {\r\n if (!self.panner) return;\r\n var err = new CustomError('loadSound', errorTrace, self.url);\r\n var msg = 'Unable to load ' + self.url + '. The request status was: ' +\r\n request.status + ' (' + request.statusText + ')';\r\n\r\n if (errorCallback) {\r\n err.message = msg;\r\n errorCallback(err);\r\n } else {\r\n console.error(msg +'\\n The error stack trace includes: \\n' + err.stack);\r\n }\r\n }\r\n };\r\n\r\n // if there is another error, aside from 404...\r\n request.onerror = function() {\r\n var err = new CustomError('loadSound', errorTrace, self.url);\r\n var msg = 'There was no response from the server at ' + self.url + '. Check the url and internet connectivity.';\r\n\r\n if (errorCallback) {\r\n err.message = msg;\r\n errorCallback(err);\r\n } else {\r\n console.error(msg +'\\n The error stack trace includes: \\n' + err.stack);\r\n }\r\n };\r\n\r\n request.send();\r\n }\r\n else if (this.file !== undefined) {\r\n var reader = new FileReader();\r\n reader.onload = function() {\r\n if (!self.panner) return;\r\n ac.decodeAudioData(reader.result, function(buff) {\r\n if (!self.panner) return;\r\n self.buffer = buff;\r\n self.panner.inputChannels(buff.numberOfChannels);\r\n if (callback) {\r\n callback(self);\r\n }\r\n });\r\n };\r\n reader.onerror = function(e) {\r\n if (!self.panner) return;\r\n if (onerror) {\r\n onerror(e);\r\n }\r\n };\r\n reader.readAsArrayBuffer(this.file);\r\n }\r\n };\r\n\r\n // TO DO: use this method to create a loading bar that shows progress during file upload/decode.\r\n p5.SoundFile.prototype._updateProgress = function(evt) {\r\n if (evt.lengthComputable) {\r\n var percentComplete = evt.loaded / evt.total * 0.99;\r\n this._whileLoading(percentComplete, evt);\r\n // ...\r\n } else {\r\n // Unable to compute progress information since the total size is unknown\r\n this._whileLoading('size unknown');\r\n }\r\n };\r\n\r\n /**\r\n * Returns true if the sound file finished loading successfully.\r\n *\r\n * @method isLoaded\r\n * @for p5.SoundFile\r\n * @return {Boolean}\r\n */\r\n p5.SoundFile.prototype.isLoaded = function() {\r\n if (this.buffer) {\r\n return true;\r\n } else {\r\n return false;\r\n }\r\n };\r\n\r\n /**\r\n * Play the p5.SoundFile\r\n *\r\n * @method play\r\n * @for p5.SoundFile\r\n * @param {Number} [startTime] (optional) schedule playback to start (in seconds from now).\r\n * @param {Number} [rate] (optional) playback rate\r\n * @param {Number} [amp] (optional) amplitude (volume)\r\n * of playback\r\n * @param {Number} [cueStart] (optional) cue start time in seconds\r\n * @param {Number} [duration] (optional) duration of playback in seconds\r\n */\r\n p5.SoundFile.prototype.play = function(startTime, rate, amp, _cueStart, duration) {\r\n if (!this.output) {\r\n console.warn('SoundFile.play() called after dispose');\r\n return;\r\n }\r\n\r\n var self = this;\r\n var now = p5sound.audiocontext.currentTime;\r\n var cueStart, cueEnd;\r\n var time = startTime || 0;\r\n if (time < 0) {\r\n time = 0;\r\n }\r\n\r\n time = time + now;\r\n\r\n if (typeof rate !== 'undefined') {\r\n this.rate(rate);\r\n }\r\n\r\n if (typeof amp !== 'undefined') {\r\n this.setVolume(amp);\r\n }\r\n\r\n // TO DO: if already playing, create array of buffers for easy stop()\r\n if (this.buffer) {\r\n\r\n // reset the pause time (if it was paused)\r\n this._pauseTime = 0;\r\n\r\n // handle restart playmode\r\n if (this.mode === 'restart' && this.buffer && this.bufferSourceNode) {\r\n this.bufferSourceNode.stop(time);\r\n this._counterNode.stop(time);\r\n }\r\n\r\n //dont create another instance if already playing\r\n if (this.mode === 'untildone' && this.isPlaying()) {\r\n return;\r\n }\r\n // make a new source and counter. They are automatically assigned playbackRate and buffer\r\n this.bufferSourceNode = this._initSourceNode();\r\n\r\n // garbage collect counterNode and create a new one\r\n delete this._counterNode;\r\n this._counterNode = this._initCounterNode();\r\n\r\n if (_cueStart) {\r\n if (_cueStart >=0 && _cueStart < this.buffer.duration) {\r\n // this.startTime = cueStart;\r\n cueStart = _cueStart;\r\n } else { throw 'start time out of range'; }\r\n } else {\r\n cueStart = 0;\r\n }\r\n\r\n if (duration) {\r\n // if duration is greater than buffer.duration, just play entire file anyway rather than throw an error\r\n duration = duration <= this.buffer.duration - cueStart ? duration : this.buffer.duration;\r\n }\r\n\r\n // if it was paused, play at the pause position\r\n if (this._paused) {\r\n this.bufferSourceNode.start(time, this.pauseTime, duration);\r\n this._counterNode.start(time, this.pauseTime, duration);\r\n } else {\r\n this.bufferSourceNode.start(time, cueStart, duration);\r\n this._counterNode.start(time, cueStart, duration);\r\n }\r\n\r\n this._playing = true;\r\n this._paused = false;\r\n\r\n // add source to sources array, which is used in stopAll()\r\n this.bufferSourceNodes.push(this.bufferSourceNode);\r\n this.bufferSourceNode._arrayIndex = this.bufferSourceNodes.length - 1;\r\n\r\n this.bufferSourceNode.addEventListener('ended', this._clearOnEnd);\r\n }\r\n // If soundFile hasn't loaded the buffer yet, throw an error\r\n else {\r\n throw 'not ready to play file, buffer has yet to load. Try preload()';\r\n }\r\n\r\n // if looping, will restart at original time\r\n this.bufferSourceNode.loop = this._looping;\r\n this._counterNode.loop = this._looping;\r\n\r\n if (this._looping === true) {\r\n cueEnd = duration ? duration : cueStart - 0.000000000000001;\r\n this.bufferSourceNode.loopStart = cueStart;\r\n this.bufferSourceNode.loopEnd = cueEnd;\r\n this._counterNode.loopStart = cueStart;\r\n this._counterNode.loopEnd = cueEnd;\r\n }\r\n };\r\n\r\n\r\n /**\r\n * p5.SoundFile has two play modes: restart and\r\n * sustain. Play Mode determines what happens to a\r\n * p5.SoundFile if it is triggered while in the middle of playback.\r\n * In sustain mode, playback will continue simultaneous to the\r\n * new playback. In restart mode, play() will stop playback\r\n * and start over. With untilDone, a sound will play only if it's\r\n * not already playing. Sustain is the default mode.\r\n *\r\n * @method playMode\r\n * @for p5.SoundFile\r\n * @param {String} str 'restart' or 'sustain' or 'untilDone'\r\n * @example\r\n *
\r\n * var mySound;\r\n * function preload(){\r\n * mySound = loadSound('assets/Damscray_DancingTiger.mp3');\r\n * }\r\n * function mouseClicked() {\r\n * mySound.playMode('sustain');\r\n * mySound.play();\r\n * }\r\n * function keyPressed() {\r\n * mySound.playMode('restart');\r\n * mySound.play();\r\n * }\r\n *\r\n *
\r\n */\r\n p5.SoundFile.prototype.playMode = function(str) {\r\n var s = str.toLowerCase();\r\n\r\n // if restart, stop all other sounds from playing\r\n if (s === 'restart' && this.buffer && this.bufferSourceNode) {\r\n for (var i = 0; i < this.bufferSourceNodes.length - 1; i++) {\r\n var now = p5sound.audiocontext.currentTime;\r\n this.bufferSourceNodes[i].stop(now);\r\n }\r\n }\r\n\r\n // set play mode to effect future playback\r\n if (s === 'restart' || s === 'sustain' || s === 'untildone') {\r\n this.mode = s;\r\n } else {\r\n throw 'Invalid play mode. Must be either \"restart\" or \"sustain\"';\r\n }\r\n };\r\n\r\n /**\r\n * Pauses a file that is currently playing. If the file is not\r\n * playing, then nothing will happen.\r\n *\r\n * After pausing, .play() will resume from the paused\r\n * position.\r\n * If p5.SoundFile had been set to loop before it was paused,\r\n * it will continue to loop after it is unpaused with .play().\r\n *\r\n * @method pause\r\n * @for p5.SoundFile\r\n * @param {Number} [startTime] (optional) schedule event to occur\r\n * seconds from now\r\n * @example\r\n *
\r\n */\r\n p5.SoundFile.prototype.pause = function(startTime) {\r\n var now = p5sound.audiocontext.currentTime;\r\n var time = startTime || 0;\r\n var pTime = time + now;\r\n\r\n if (this.isPlaying() && this.buffer && this.bufferSourceNode) {\r\n this.pauseTime = this.currentTime();\r\n this.bufferSourceNode.stop(pTime);\r\n this._counterNode.stop(pTime);\r\n this._paused = true;\r\n this._playing = false;\r\n\r\n this._pauseTime = this.currentTime();\r\n // TO DO: make sure play() still starts from orig start position\r\n } else {\r\n this._pauseTime = 0;\r\n }\r\n };\r\n\r\n /**\r\n * Loop the p5.SoundFile. Accepts optional parameters to set the\r\n * playback rate, playback volume, loopStart, loopEnd.\r\n *\r\n * @method loop\r\n * @for p5.SoundFile\r\n * @param {Number} [startTime] (optional) schedule event to occur\r\n * seconds from now\r\n * @param {Number} [rate] (optional) playback rate\r\n * @param {Number} [amp] (optional) playback volume\r\n * @param {Number} [cueLoopStart] (optional) startTime in seconds\r\n * @param {Number} [duration] (optional) loop duration in seconds\r\n */\r\n p5.SoundFile.prototype.loop = function(startTime, rate, amp, loopStart, duration) {\r\n this._looping = true;\r\n this.play(startTime, rate, amp, loopStart, duration);\r\n };\r\n\r\n /**\r\n * Set a p5.SoundFile's looping flag to true or false. If the sound\r\n * is currently playing, this change will take effect when it\r\n * reaches the end of the current playback.\r\n *\r\n * @method setLoop\r\n * @for p5.SoundFile\r\n * @param {Boolean} Boolean set looping to true or false\r\n */\r\n p5.SoundFile.prototype.setLoop = function(bool) {\r\n if (bool === true) {\r\n this._looping = true;\r\n }\r\n else if (bool === false) {\r\n this._looping = false;\r\n }\r\n else {\r\n throw 'Error: setLoop accepts either true or false';\r\n }\r\n if (this.bufferSourceNode) {\r\n this.bufferSourceNode.loop = this._looping;\r\n this._counterNode.loop = this._looping;\r\n }\r\n };\r\n\r\n /**\r\n * Returns 'true' if a p5.SoundFile is currently looping and playing, 'false' if not.\r\n *\r\n * @method isLooping\r\n * @for p5.SoundFile\r\n * @return {Boolean}\r\n */\r\n p5.SoundFile.prototype.isLooping = function() {\r\n if (!this.bufferSourceNode) {\r\n return false;\r\n }\r\n if (this._looping === true && this.isPlaying() === true) {\r\n return true;\r\n }\r\n return false;\r\n };\r\n\r\n /**\r\n * Returns true if a p5.SoundFile is playing, false if not (i.e.\r\n * paused or stopped).\r\n *\r\n * @method isPlaying\r\n * @for p5.SoundFile\r\n * @return {Boolean}\r\n */\r\n p5.SoundFile.prototype.isPlaying = function() {\r\n return this._playing;\r\n };\r\n\r\n /**\r\n * Returns true if a p5.SoundFile is paused, false if not (i.e.\r\n * playing or stopped).\r\n *\r\n * @method isPaused\r\n * @for p5.SoundFile\r\n * @return {Boolean}\r\n */\r\n p5.SoundFile.prototype.isPaused = function() {\r\n return this._paused;\r\n };\r\n\r\n /**\r\n * Stop soundfile playback.\r\n *\r\n * @method stop\r\n * @for p5.SoundFile\r\n * @param {Number} [startTime] (optional) schedule event to occur\r\n * in seconds from now\r\n */\r\n p5.SoundFile.prototype.stop = function(timeFromNow) {\r\n var time = timeFromNow || 0;\r\n\r\n if (this.mode === 'sustain' || this.mode === 'untildone') {\r\n this.stopAll(time);\r\n this._playing = false;\r\n this.pauseTime = 0;\r\n this._paused = false;\r\n }\r\n else if (this.buffer && this.bufferSourceNode) {\r\n var now = p5sound.audiocontext.currentTime;\r\n var t = time || 0;\r\n this.pauseTime = 0;\r\n this.bufferSourceNode.stop(now + t);\r\n this._counterNode.stop(now + t);\r\n this._playing = false;\r\n this._paused = false;\r\n }\r\n };\r\n\r\n /**\r\n * Stop playback on all of this soundfile's sources.\r\n * @private\r\n */\r\n p5.SoundFile.prototype.stopAll = function(_time) {\r\n var now = p5sound.audiocontext.currentTime;\r\n var time = _time || 0;\r\n if (this.buffer && this.bufferSourceNode) {\r\n for (var i in this.bufferSourceNodes) {\r\n const bufferSourceNode = this.bufferSourceNodes[i];\r\n if (!!bufferSourceNode) {\r\n try {\r\n bufferSourceNode.stop(now + time);\r\n } catch(e) {\r\n // this was throwing errors only on Safari\r\n }\r\n }\r\n }\r\n this._counterNode.stop(now + time);\r\n this._onended(this);\r\n }\r\n };\r\n\r\n /**\r\n * Multiply the output volume (amplitude) of a sound file\r\n * between 0.0 (silence) and 1.0 (full volume).\r\n * 1.0 is the maximum amplitude of a digital sound, so multiplying\r\n * by greater than 1.0 may cause digital distortion. To\r\n * fade, provide a rampTime parameter. For more\r\n * complex fades, see the Envelope class.\r\n *\r\n * Alternately, you can pass in a signal source such as an\r\n * oscillator to modulate the amplitude with an audio signal.\r\n *\r\n * @method setVolume\r\n * @for p5.SoundFile\r\n * @param {Number|Object} volume Volume (amplitude) between 0.0\r\n * and 1.0 or modulating signal/oscillator\r\n * @param {Number} [rampTime] Fade for t seconds\r\n * @param {Number} [timeFromNow] Schedule this event to happen at\r\n * t seconds in the future\r\n */\r\n p5.SoundFile.prototype.setVolume = function(vol, _rampTime, _tFromNow) {\r\n if (typeof vol === 'number') {\r\n var rampTime = _rampTime || 0;\r\n var tFromNow = _tFromNow || 0;\r\n var now = p5sound.audiocontext.currentTime;\r\n var currentVol = this.output.gain.value;\r\n this.output.gain.cancelScheduledValues(now + tFromNow);\r\n this.output.gain.linearRampToValueAtTime(currentVol, now + tFromNow);\r\n this.output.gain.linearRampToValueAtTime(vol, now + tFromNow + rampTime);\r\n }\r\n else if (vol) {\r\n vol.connect(this.output.gain);\r\n } else {\r\n // return the Gain Node\r\n return this.output.gain;\r\n }\r\n };\r\n\r\n // same as setVolume, to match Processing Sound\r\n p5.SoundFile.prototype.amp = p5.SoundFile.prototype.setVolume;\r\n\r\n // these are the same thing\r\n p5.SoundFile.prototype.fade = p5.SoundFile.prototype.setVolume;\r\n\r\n p5.SoundFile.prototype.getVolume = function() {\r\n return this.output.gain.value;\r\n };\r\n\r\n /**\r\n * Set the stereo panning of a p5.sound object to\r\n * a floating point number between -1.0 (left) and 1.0 (right).\r\n * Default is 0.0 (center).\r\n *\r\n * @method pan\r\n * @for p5.SoundFile\r\n * @param {Number} [panValue] Set the stereo panner\r\n * @param {Number} [timeFromNow] schedule this event to happen\r\n * seconds from now\r\n * @example\r\n *
\r\n *\r\n * var ball = {};\r\n * var soundFile;\r\n *\r\n * function preload() {\r\n * soundFormats('ogg', 'mp3');\r\n * soundFile = loadSound('assets/beatbox.mp3');\r\n * }\r\n *\r\n * function draw() {\r\n * background(0);\r\n * ball.x = constrain(mouseX, 0, width);\r\n * ellipse(ball.x, height/2, 20, 20)\r\n * }\r\n *\r\n * function mousePressed(){\r\n * // map the ball's x location to a panning degree\r\n * // between -1.0 (left) and 1.0 (right)\r\n * var panning = map(ball.x, 0., width,-1.0, 1.0);\r\n * soundFile.pan(panning);\r\n * soundFile.play();\r\n * }\r\n *
\r\n */\r\n p5.SoundFile.prototype.pan = function(pval, tFromNow) {\r\n this.panPosition = pval;\r\n this.panner.pan(pval, tFromNow);\r\n };\r\n\r\n /**\r\n * Returns the current stereo pan position (-1.0 to 1.0)\r\n *\r\n * @method getPan\r\n * @for p5.SoundFile\r\n * @return {Number} Returns the stereo pan setting of the Oscillator\r\n * as a number between -1.0 (left) and 1.0 (right).\r\n * 0.0 is center and default.\r\n */\r\n p5.SoundFile.prototype.getPan = function() {\r\n return this.panPosition;\r\n };\r\n\r\n /**\r\n * Set the playback rate of a sound file. Will change the speed and the pitch.\r\n * Values less than zero will reverse the audio buffer.\r\n *\r\n * @method rate\r\n * @for p5.SoundFile\r\n * @param {Number} [playbackRate] Set the playback rate. 1.0 is normal,\r\n * .5 is half-speed, 2.0 is twice as fast.\r\n * Values less than zero play backwards.\r\n * @example\r\n *
\r\n * var song;\r\n *\r\n * function preload() {\r\n * song = loadSound('assets/Damscray_DancingTiger.mp3');\r\n * }\r\n *\r\n * function setup() {\r\n * song.loop();\r\n * }\r\n *\r\n * function draw() {\r\n * background(200);\r\n *\r\n * // Set the rate to a range between 0.1 and 4\r\n * // Changing the rate also alters the pitch\r\n * var speed = map(mouseY, 0.1, height, 0, 2);\r\n * speed = constrain(speed, 0.01, 4);\r\n * song.rate(speed);\r\n *\r\n * // Draw a circle to show what is going on\r\n * stroke(0);\r\n * fill(51, 100);\r\n * ellipse(mouseX, 100, 48, 48);\r\n * }\r\n *\r\n * \r\n *
\r\n *\r\n */\r\n p5.SoundFile.prototype.rate = function(playbackRate) {\r\n var reverse = false;\r\n if (typeof playbackRate === 'undefined') {\r\n return this.playbackRate;\r\n }\r\n\r\n this.playbackRate = playbackRate;\r\n\r\n if (playbackRate === 0) {\r\n playbackRate = 0.0000000000001;\r\n }\r\n\r\n else if (playbackRate < 0 && !this.reversed) {\r\n playbackRate = Math.abs(playbackRate);\r\n reverse = true;\r\n }\r\n\r\n else if (playbackRate > 0 && this.reversed) {\r\n reverse = true;\r\n }\r\n\r\n if (this.bufferSourceNode) {\r\n var now = p5sound.audiocontext.currentTime;\r\n this.bufferSourceNode.playbackRate.cancelScheduledValues(now);\r\n this.bufferSourceNode.playbackRate.linearRampToValueAtTime(Math.abs(playbackRate), now);\r\n this._counterNode.playbackRate.cancelScheduledValues(now);\r\n this._counterNode.playbackRate.linearRampToValueAtTime(Math.abs(playbackRate), now);\r\n }\r\n\r\n if (reverse) {\r\n this.reverseBuffer();\r\n }\r\n return this.playbackRate;\r\n };\r\n\r\n // TO DO: document this\r\n p5.SoundFile.prototype.setPitch = function(num) {\r\n var newPlaybackRate = midiToFreq(num) / midiToFreq(60);\r\n this.rate(newPlaybackRate);\r\n };\r\n\r\n p5.SoundFile.prototype.getPlaybackRate = function() {\r\n return this.playbackRate;\r\n };\r\n\r\n /**\r\n * Returns the duration of a sound file in seconds.\r\n *\r\n * @method duration\r\n * @for p5.SoundFile\r\n * @return {Number} The duration of the soundFile in seconds.\r\n */\r\n p5.SoundFile.prototype.duration = function() {\r\n // Return Duration\r\n if (this.buffer) {\r\n return this.buffer.duration;\r\n } else {\r\n return 0;\r\n }\r\n };\r\n\r\n /**\r\n * Return the current position of the p5.SoundFile playhead, in seconds.\r\n * Time is relative to the normal buffer direction, so if `reverseBuffer`\r\n * has been called, currentTime will count backwards.\r\n *\r\n * @method currentTime\r\n * @for p5.SoundFile\r\n * @return {Number} currentTime of the soundFile in seconds.\r\n */\r\n p5.SoundFile.prototype.currentTime = function() {\r\n return this.reversed\r\n ? Math.abs(this._lastPos - this.buffer.length) / ac.sampleRate\r\n : this._lastPos / ac.sampleRate;\r\n };\r\n\r\n /**\r\n * Move the playhead of the song to a position, in seconds. Start timing\r\n * and playback duration. If none are given, will reset the file to play\r\n * entire duration from start to finish.\r\n *\r\n * @method jump\r\n * @for p5.SoundFile\r\n * @param {Number} cueTime cueTime of the soundFile in seconds.\r\n * @param {Number} duration duration in seconds.\r\n */\r\n p5.SoundFile.prototype.jump = function(cueTime, duration) {\r\n if (cueTime < 0 || cueTime > this.buffer.duration) {\r\n throw 'jump time out of range';\r\n }\r\n if (duration > this.buffer.duration - cueTime) {\r\n throw 'end time out of range';\r\n }\r\n\r\n var cTime = cueTime || 0;\r\n var dur = duration || undefined;\r\n if (this.isPlaying()) {\r\n this.stop(0);\r\n }\r\n this.play(0, this.playbackRate, this.output.gain.value, cTime, dur);\r\n };\r\n\r\n /**\r\n * Return the number of channels in a sound file.\r\n * For example, Mono = 1, Stereo = 2.\r\n *\r\n * @method channels\r\n * @for p5.SoundFile\r\n * @return {Number} [channels]\r\n */\r\n p5.SoundFile.prototype.channels = function() {\r\n return this.buffer.numberOfChannels;\r\n };\r\n\r\n /**\r\n * Return the sample rate of the sound file.\r\n *\r\n * @method sampleRate\r\n * @for p5.SoundFile\r\n * @return {Number} [sampleRate]\r\n */\r\n p5.SoundFile.prototype.sampleRate = function() {\r\n return this.buffer.sampleRate;\r\n };\r\n\r\n /**\r\n * Return the number of samples in a sound file.\r\n * Equal to sampleRate * duration.\r\n *\r\n * @method frames\r\n * @for p5.SoundFile\r\n * @return {Number} [sampleCount]\r\n */\r\n p5.SoundFile.prototype.frames = function() {\r\n return this.buffer.length;\r\n };\r\n\r\n /**\r\n * Returns an array of amplitude peaks in a p5.SoundFile that can be\r\n * used to draw a static waveform. Scans through the p5.SoundFile's\r\n * audio buffer to find the greatest amplitudes. Accepts one\r\n * parameter, 'length', which determines size of the array.\r\n * Larger arrays result in more precise waveform visualizations.\r\n *\r\n * Inspired by Wavesurfer.js.\r\n *\r\n * @method getPeaks\r\n * @for p5.SoundFile\r\n * @params {Number} [length] length is the size of the returned array.\r\n * Larger length results in more precision.\r\n * Defaults to 5*width of the browser window.\r\n * @returns {Float32Array} Array of peaks.\r\n */\r\n p5.SoundFile.prototype.getPeaks = function(length) {\r\n\r\n if (this.buffer) {\r\n // set length to window's width if no length is provided\r\n if (!length) {\r\n length = window.width*5;\r\n }\r\n if (this.buffer) {\r\n var buffer = this.buffer;\r\n var sampleSize = buffer.length / length;\r\n var sampleStep = ~~(sampleSize / 10) || 1;\r\n var channels = buffer.numberOfChannels;\r\n var peaks = new Float32Array(Math.round(length));\r\n\r\n for (var c = 0; c < channels; c++) {\r\n var chan = buffer.getChannelData(c);\r\n for (var i = 0; i < length; i++) {\r\n var start = ~~(i*sampleSize);\r\n var end = ~~(start + sampleSize);\r\n var max = 0;\r\n for (var j = start; j < end; j+= sampleStep) {\r\n var value = chan[j];\r\n if (value > max) {\r\n max = value;\r\n // faster than Math.abs\r\n } else if (-value > max) {\r\n max = value;\r\n }\r\n }\r\n if (c === 0 || Math.abs(max) > peaks[i]) {\r\n peaks[i] = max;\r\n }\r\n }\r\n }\r\n\r\n return peaks;\r\n }\r\n }\r\n\r\n else {\r\n throw 'Cannot load peaks yet, buffer is not loaded';\r\n }\r\n };\r\n\r\n /**\r\n * Reverses the p5.SoundFile's buffer source.\r\n * Playback must be handled separately (see example).\r\n *\r\n * @method reverseBuffer\r\n * @for p5.SoundFile\r\n * @example\r\n *
\r\n * var drum;\r\n *\r\n * function preload() {\r\n * drum = loadSound('assets/drum.mp3');\r\n * }\r\n *\r\n * function setup() {\r\n * drum.reverseBuffer();\r\n * drum.play();\r\n * }\r\n *\r\n * \r\n *
\r\n */\r\n p5.SoundFile.prototype.reverseBuffer = function() {\r\n if (this.buffer) {\r\n var currentPos = this._lastPos / ac.sampleRate;\r\n var curVol = this.getVolume();\r\n this.setVolume(0, 0.001);\r\n\r\n const numChannels = this.buffer.numberOfChannels;\r\n for (var i = 0; i < numChannels; i++) {\r\n this.buffer.getChannelData(i).reverse();\r\n }\r\n // set reversed flag\r\n this.reversed = !this.reversed;\r\n\r\n if (currentPos) {\r\n this.jump(this.duration() - currentPos);\r\n }\r\n this.setVolume(curVol, 0.001);\r\n } else {\r\n throw 'SoundFile is not done loading';\r\n }\r\n };\r\n\r\n /**\r\n * Schedule an event to be called when the soundfile\r\n * reaches the end of a buffer. If the soundfile is\r\n * playing through once, this will be called when it\r\n * ends. If it is looping, it will be called when\r\n * stop is called.\r\n *\r\n * @method onended\r\n * @for p5.SoundFile\r\n * @param {Function} callback function to call when the\r\n * soundfile has ended.\r\n */\r\n p5.SoundFile.prototype.onended = function(callback) {\r\n this._onended = callback;\r\n return this;\r\n };\r\n\r\n p5.SoundFile.prototype.add = function() {\r\n // TO DO\r\n };\r\n\r\n p5.SoundFile.prototype.dispose = function() {\r\n var now = p5sound.audiocontext.currentTime;\r\n\r\n // remove reference to soundfile\r\n var index = p5sound.soundArray.indexOf(this);\r\n p5sound.soundArray.splice(index, 1);\r\n\r\n this.stop(now);\r\n if (this.buffer && this.bufferSourceNode) {\r\n for (var i = 0; i < this.bufferSourceNodes.length - 1; i++) {\r\n if (this.bufferSourceNodes[i] !== null) {\r\n this.bufferSourceNodes[i].disconnect();\r\n try {\r\n this.bufferSourceNodes[i].stop(now);\r\n } catch(e) {\r\n console.warning('no buffer source node to dispose');\r\n }\r\n this.bufferSourceNodes[i] = null;\r\n }\r\n }\r\n if ( this.isPlaying() ) {\r\n try {\r\n this._counterNode.stop(now);\r\n } catch(e) {\r\n console.log(e);\r\n }\r\n this._counterNode = null;\r\n }\r\n }\r\n if (this.output) {\r\n this.output.disconnect();\r\n this.output = null;\r\n }\r\n if (this.panner) {\r\n this.panner.disconnect();\r\n this.panner = null;\r\n }\r\n };\r\n\r\n /**\r\n * Connects the output of a p5sound object to input of another\r\n * p5.sound object. For example, you may connect a p5.SoundFile to an\r\n * FFT or an Effect. If no parameter is given, it will connect to\r\n * the master output. Most p5sound objects connect to the master\r\n * output when they are created.\r\n *\r\n * @method connect\r\n * @for p5.SoundFile\r\n * @param {Object} [object] Audio object that accepts an input\r\n */\r\n p5.SoundFile.prototype.connect = function(unit) {\r\n if (!unit) {\r\n this.panner.connect(p5sound.input);\r\n }\r\n else {\r\n if (unit.hasOwnProperty('input')) {\r\n this.panner.connect(unit.input);\r\n } else {\r\n this.panner.connect(unit);\r\n }\r\n }\r\n };\r\n\r\n /**\r\n * Disconnects the output of this p5sound object.\r\n *\r\n * @method disconnect\r\n * @for p5.SoundFile\r\n */\r\n p5.SoundFile.prototype.disconnect = function() {\r\n if (this.panner) {\r\n this.panner.disconnect();\r\n }\r\n };\r\n\r\n /**\r\n */\r\n p5.SoundFile.prototype.getLevel = function() {\r\n console.warn('p5.SoundFile.getLevel has been removed from the library. Use p5.Amplitude instead');\r\n };\r\n\r\n /**\r\n * Reset the source for this SoundFile to a\r\n * new path (URL).\r\n *\r\n * @method setPath\r\n * @for p5.SoundFile\r\n * @param {String} path path to audio file\r\n * @param {Function} callback Callback\r\n */\r\n p5.SoundFile.prototype.setPath = function(p, callback) {\r\n var path = p5.prototype._checkFileFormats(p);\r\n this.url = path;\r\n this.load(callback);\r\n };\r\n\r\n /**\r\n * Replace the current Audio Buffer with a new Buffer.\r\n *\r\n * @method setBuffer\r\n * @for p5.SoundFile\r\n * @param {Array} buf Array of Float32 Array(s). 2 Float32 Arrays\r\n * will create a stereo source. 1 will create\r\n * a mono source.\r\n */\r\n p5.SoundFile.prototype.setBuffer = function(buf) {\r\n var numChannels = buf.length;\r\n var size = buf[0].length;\r\n var newBuffer = ac.createBuffer(numChannels, size, ac.sampleRate);\r\n\r\n if (!(buf[0] instanceof Float32Array)) {\r\n buf[0] = new Float32Array(buf[0]);\r\n }\r\n\r\n for (var channelNum = 0; channelNum < numChannels; channelNum++) {\r\n var channel = newBuffer.getChannelData( channelNum );\r\n channel.set(buf[channelNum]);\r\n }\r\n\r\n this.buffer = newBuffer;\r\n\r\n // set numbers of channels on input to the panner\r\n this.panner.inputChannels(numChannels);\r\n };\r\n\r\n //////////////////////////////////////////////////\r\n // script processor node with an empty buffer to help\r\n // keep a sample-accurate position in playback buffer.\r\n // Inspired by Chinmay Pendharkar's technique for Sonoport --> http://bit.ly/1HwdCsV\r\n // Copyright [2015] [Sonoport (Asia) Pte. Ltd.],\r\n // Licensed under the Apache License http://apache.org/licenses/LICENSE-2.0\r\n ////////////////////////////////////////////////////////////////////////////////////\r\n\r\n var _createCounterBuffer = function(buffer) {\r\n const len = buffer.length;\r\n const audioBuf = ac.createBuffer( 1, buffer.length, ac.sampleRate );\r\n const arrayBuffer = audioBuf.getChannelData(0);\r\n for (var index = 0; index < len; index++) {\r\n arrayBuffer[index] = index;\r\n }\r\n return audioBuf;\r\n };\r\n\r\n // initialize counterNode, set its initial buffer and playbackRate\r\n p5.SoundFile.prototype._initCounterNode = function() {\r\n var self = this;\r\n var now = ac.currentTime;\r\n var cNode = ac.createBufferSource();\r\n\r\n // dispose of worklet node if it already exists\r\n if (self._workletNode) {\r\n self._workletNode.disconnect();\r\n delete self._workletNode;\r\n }\r\n self._workletNode = new AudioWorkletNode(ac, processorNames.soundFileProcessor);\r\n self._workletNode.port.onmessage = function(event) {\r\n if (event.data.name === 'position') {\r\n this._lastPos = event.data.position;\r\n\r\n // do any callbacks that have been scheduled\r\n this._onTimeUpdate(self._lastPos);\r\n }\r\n }.bind(self);\r\n\r\n // create counter buffer of the same length as self.buffer\r\n cNode.buffer = _createCounterBuffer( self.buffer );\r\n\r\n cNode.playbackRate.setValueAtTime(self.playbackRate, now);\r\n\r\n cNode.connect(self._workletNode);\r\n self._workletNode.connect(p5.soundOut._silentNode);\r\n\r\n return cNode;\r\n };\r\n\r\n // initialize sourceNode, set its initial buffer and playbackRate\r\n p5.SoundFile.prototype._initSourceNode = function() {\r\n var bufferSourceNode = ac.createBufferSource();\r\n bufferSourceNode.buffer = this.buffer;\r\n bufferSourceNode.playbackRate.value = this.playbackRate;\r\n bufferSourceNode.connect(this.output);\r\n return bufferSourceNode;\r\n };\r\n\r\n /**\r\n * processPeaks returns an array of timestamps where it thinks there is a beat.\r\n *\r\n * This is an asynchronous function that processes the soundfile in an offline audio context,\r\n * and sends the results to your callback function.\r\n *\r\n * The process involves running the soundfile through a lowpass filter, and finding all of the\r\n * peaks above the initial threshold. If the total number of peaks are below the minimum number of peaks,\r\n * it decreases the threshold and re-runs the analysis until either minPeaks or minThreshold are reached.\r\n *\r\n * @method processPeaks\r\n * @for p5.SoundFile\r\n * @param {Function} callback a function to call once this data is returned\r\n * @param {Number} [initThreshold] initial threshold defaults to 0.9\r\n * @param {Number} [minThreshold] minimum threshold defaults to 0.22\r\n * @param {Number} [minPeaks] minimum number of peaks defaults to 200\r\n * @return {Array} Array of timestamped peaks\r\n */\r\n p5.SoundFile.prototype.processPeaks = function(callback, _initThreshold, _minThreshold, _minPeaks) {\r\n var bufLen = this.buffer.length;\r\n var sampleRate = this.buffer.sampleRate;\r\n var buffer = this.buffer;\r\n var allPeaks = [];\r\n\r\n var initialThreshold = _initThreshold || 0.9,\r\n threshold = initialThreshold,\r\n minThreshold = _minThreshold || 0.22,\r\n minPeaks = _minPeaks || 200;\r\n\r\n // Create offline context\r\n var offlineContext = new window.OfflineAudioContext(1, bufLen, sampleRate);\r\n\r\n // create buffer source\r\n var source = offlineContext.createBufferSource();\r\n source.buffer = buffer;\r\n\r\n // Create filter. TO DO: allow custom setting of filter\r\n var filter = offlineContext.createBiquadFilter();\r\n filter.type = 'lowpass';\r\n source.connect(filter);\r\n filter.connect(offlineContext.destination);\r\n\r\n // start playing at time:0\r\n source.start(0);\r\n offlineContext.startRendering(); // Render the song\r\n\r\n // act on the result\r\n offlineContext.oncomplete = function(e) {\r\n if (!self.panner) return;\r\n var filteredBuffer = e.renderedBuffer;\r\n var bufferData = filteredBuffer.getChannelData(0);\r\n\r\n\r\n // step 1:\r\n // create Peak instances, add them to array, with strength and sampleIndex\r\n do {\r\n allPeaks = getPeaksAtThreshold(bufferData, threshold);\r\n threshold -= 0.005;\r\n } while (Object.keys(allPeaks).length < minPeaks && threshold >= minThreshold);\r\n\r\n\r\n // step 2:\r\n // find intervals for each peak in the sampleIndex, add tempos array\r\n var intervalCounts = countIntervalsBetweenNearbyPeaks(allPeaks);\r\n\r\n // step 3: find top tempos\r\n var groups = groupNeighborsByTempo(intervalCounts, filteredBuffer.sampleRate);\r\n\r\n // sort top intervals\r\n var topTempos = groups.sort(function(intA, intB) {\r\n return intB.count - intA.count;\r\n\r\n }).splice(0,5);\r\n\r\n // set this SoundFile's tempo to the top tempo ??\r\n this.tempo = topTempos[0].tempo;\r\n\r\n // step 4:\r\n // new array of peaks at top tempo within a bpmVariance\r\n var bpmVariance = 5;\r\n var tempoPeaks = getPeaksAtTopTempo(allPeaks, topTempos[0].tempo, filteredBuffer.sampleRate, bpmVariance);\r\n\r\n callback(tempoPeaks);\r\n };\r\n };\r\n\r\n // process peaks\r\n var Peak = function(amp, i) {\r\n this.sampleIndex = i;\r\n this.amplitude = amp;\r\n this.tempos = [];\r\n this.intervals = [];\r\n };\r\n\r\n // 1. for processPeaks() Function to identify peaks above a threshold\r\n // returns an array of peak indexes as frames (samples) of the original soundfile\r\n function getPeaksAtThreshold(data, threshold) {\r\n var peaksObj = {};\r\n var length = data.length;\r\n\r\n for (var i = 0; i < length; i++) {\r\n if (data[i] > threshold) {\r\n var amp = data[i];\r\n var peak = new Peak(amp, i);\r\n peaksObj[i] = peak;\r\n // Skip forward ~ 1/8s to get past this peak.\r\n i += 6000;\r\n }\r\n i++;\r\n }\r\n return peaksObj;\r\n }\r\n\r\n // 2. for processPeaks()\r\n function countIntervalsBetweenNearbyPeaks(peaksObj) {\r\n var intervalCounts = [];\r\n var peaksArray = Object.keys(peaksObj).sort();\r\n\r\n for (var index = 0; index < peaksArray.length; index++) {\r\n\r\n // find intervals in comparison to nearby peaks\r\n for (var i = 0; i < 10; i++) {\r\n var startPeak = peaksObj[peaksArray[index]];\r\n var endPeak = peaksObj[peaksArray[index + i]];\r\n\r\n if (startPeak && endPeak) {\r\n var startPos = startPeak.sampleIndex;\r\n var endPos = endPeak.sampleIndex;\r\n var interval = endPos - startPos;\r\n\r\n // add a sample interval to the startPeak in the allPeaks array\r\n if (interval > 0) {\r\n startPeak.intervals.push(interval);\r\n }\r\n\r\n // tally the intervals and return interval counts\r\n var foundInterval = intervalCounts.some(function(intervalCount) {\r\n if (intervalCount.interval === interval) {\r\n intervalCount.count++;\r\n return intervalCount;\r\n }\r\n });\r\n\r\n // store with JSON like formatting\r\n if (!foundInterval) {\r\n intervalCounts.push({\r\n interval: interval,\r\n count: 1,\r\n });\r\n }\r\n }\r\n }\r\n }\r\n\r\n return intervalCounts;\r\n }\r\n\r\n\r\n // 3. for processPeaks --> find tempo\r\n function groupNeighborsByTempo(intervalCounts, sampleRate) {\r\n var tempoCounts = [];\r\n\r\n intervalCounts.forEach(function(intervalCount) {\r\n\r\n try {\r\n // Convert an interval to tempo\r\n var theoreticalTempo = Math.abs( 60 / (intervalCount.interval / sampleRate ) );\r\n\r\n theoreticalTempo = mapTempo(theoreticalTempo);\r\n\r\n var foundTempo = tempoCounts.some(function(tempoCount) {\r\n if (tempoCount.tempo === theoreticalTempo)\r\n return tempoCount.count += intervalCount.count;\r\n });\r\n if (!foundTempo) {\r\n if (isNaN(theoreticalTempo)) {\r\n return;\r\n }\r\n tempoCounts.push({\r\n tempo: Math.round(theoreticalTempo),\r\n count: intervalCount.count\r\n });\r\n }\r\n } catch(e) {\r\n throw e;\r\n }\r\n\r\n });\r\n\r\n return tempoCounts;\r\n }\r\n\r\n // 4. for processPeaks - get peaks at top tempo\r\n function getPeaksAtTopTempo(peaksObj, tempo, sampleRate, bpmVariance) {\r\n var peaksAtTopTempo = [];\r\n var peaksArray = Object.keys(peaksObj).sort();\r\n\r\n // TO DO: filter out peaks that have the tempo and return\r\n for (var i = 0; i < peaksArray.length; i++) {\r\n var key = peaksArray[i];\r\n var peak = peaksObj[key];\r\n\r\n for (var j = 0; j < peak.intervals.length; j++) {\r\n var intervalBPM = Math.round(Math.abs( 60 / (peak.intervals[j] / sampleRate) ) );\r\n\r\n intervalBPM = mapTempo(intervalBPM);\r\n\r\n if ( Math.abs(intervalBPM - tempo) < bpmVariance ) {\r\n // convert sampleIndex to seconds\r\n peaksAtTopTempo.push(peak.sampleIndex/sampleRate);\r\n }\r\n }\r\n }\r\n\r\n // filter out peaks that are very close to each other\r\n peaksAtTopTempo = peaksAtTopTempo.filter(function(peakTime, index, arr) {\r\n var dif = arr[index + 1] - peakTime;\r\n if (dif > 0.01) {\r\n return true;\r\n }\r\n });\r\n\r\n return peaksAtTopTempo;\r\n }\r\n\r\n // helper function for processPeaks\r\n function mapTempo(theoreticalTempo) {\r\n // these scenarios create infinite while loop\r\n if (!isFinite(theoreticalTempo) || theoreticalTempo === 0 ) {\r\n return;\r\n }\r\n\r\n // Adjust the tempo to fit within the 90-180 BPM range\r\n while (theoreticalTempo < 90) theoreticalTempo *= 2;\r\n while (theoreticalTempo > 180 && theoreticalTempo > 90) theoreticalTempo /= 2;\r\n\r\n return theoreticalTempo;\r\n }\r\n\r\n\r\n /*** SCHEDULE EVENTS ***/\r\n\r\n // Cue inspired by JavaScript setTimeout, and the\r\n // Tone.js Transport Timeline Event, MIT License Yotam Mann 2015 tonejs.org\r\n var Cue = function(callback, time, id, val) {\r\n this.callback = callback;\r\n this.time = time;\r\n this.id = id;\r\n this.val = val;\r\n };\r\n\r\n /**\r\n * Schedule events to trigger every time a MediaElement\r\n * (audio/video) reaches a playback cue point.\r\n *\r\n * Accepts a callback function, a time (in seconds) at which to trigger\r\n * the callback, and an optional parameter for the callback.\r\n *\r\n * Time will be passed as the first parameter to the callback function,\r\n * and param will be the second parameter.\r\n *\r\n *\r\n * @method addCue\r\n * @for p5.SoundFile\r\n * @param {Number} time Time in seconds, relative to this media\r\n * element's playback. For example, to trigger\r\n * an event every time playback reaches two\r\n * seconds, pass in the number 2. This will be\r\n * passed as the first parameter to\r\n * the callback function.\r\n * @param {Function} callback Name of a function that will be\r\n * called at the given time. The callback will\r\n * receive time and (optionally) param as its\r\n * two parameters.\r\n * @param {Object} [value] An object to be passed as the\r\n * second parameter to the\r\n * callback function.\r\n * @return {Number} id ID of this cue,\r\n * useful for removeCue(id)\r\n * @example\r\n *
\r\n */\r\n p5.SoundFile.prototype.addCue = function(time, callback, val) {\r\n var id = this._cueIDCounter++;\r\n\r\n var cue = new Cue(callback, time, id, val);\r\n this._cues.push(cue);\r\n\r\n // if (!this.elt.ontimeupdate) {\r\n // this.elt.ontimeupdate = this._onTimeUpdate.bind(this);\r\n // }\r\n\r\n return id;\r\n };\r\n\r\n /**\r\n * Remove a callback based on its ID. The ID is returned by the\r\n * addCue method.\r\n *\r\n * @method removeCue\r\n * @for p5.SoundFile\r\n * @param {Number} id ID of the cue, as returned by addCue\r\n */\r\n p5.SoundFile.prototype.removeCue = function(id) {\r\n var cueLength = this._cues.length;\r\n for (var i = 0; i < cueLength; i++) {\r\n var cue = this._cues[i];\r\n if (cue.id === id) {\r\n this._cues.splice(i, 1);\r\n break;\r\n }\r\n }\r\n\r\n if (this._cues.length === 0) {\r\n // TO DO: remove callback\r\n // this.elt.ontimeupdate = null\r\n }\r\n };\r\n\r\n /**\r\n * Remove all of the callbacks that had originally been scheduled\r\n * via the addCue method.\r\n *\r\n * @method clearCues\r\n */\r\n p5.SoundFile.prototype.clearCues = function() {\r\n this._cues = [];\r\n // this.elt.ontimeupdate = null;\r\n };\r\n\r\n // private method that checks for cues to be fired if events\r\n // have been scheduled using addCue(callback, time).\r\n p5.SoundFile.prototype._onTimeUpdate = function(position) {\r\n var playbackTime = position/this.buffer.sampleRate;\r\n var cueLength = this._cues.length;\r\n\r\n for (var i = 0 ; i < cueLength; i++) {\r\n var cue = this._cues[i];\r\n var callbackTime = cue.time;\r\n var val = cue.val;\r\n\r\n if (this._prevTime < callbackTime && callbackTime <= playbackTime) {\r\n\r\n // pass the scheduled callbackTime as parameter to the callback\r\n cue.callback(val);\r\n }\r\n\r\n }\r\n\r\n this._prevTime = playbackTime;\r\n };\r\n\r\n /**\r\n * Save a p5.SoundFile as a .wav file. The browser will prompt the user\r\n * to download the file to their device. To upload a file to a server, see\r\n * getBlob\r\n *\r\n * @method save\r\n * @for p5.SoundFile\r\n * @param {String} [fileName] name of the resulting .wav file.\r\n * @example\r\n *
\r\n * var inp, button, mySound;\r\n * var fileName = 'cool';\r\n * function preload() {\r\n * mySound = loadSound('assets/doorbell.mp3');\r\n * }\r\n * function setup() {\r\n * btn = createButton('click to save file');\r\n * btn.position(0, 0);\r\n * btn.mouseClicked(handleMouseClick);\r\n * }\r\n *\r\n * function handleMouseClick() {\r\n * mySound.save(fileName);\r\n * }\r\n *
\r\n */\r\n p5.SoundFile.prototype.save = function(fileName) {\r\n const dataView = convertToWav(this.buffer);\r\n p5.prototype.saveSound([dataView], fileName, 'wav');\r\n };\r\n\r\n /**\r\n * This method is useful for sending a SoundFile to a server. It returns the\r\n * .wav-encoded audio data as a \"Blob\".\r\n * A Blob is a file-like data object that can be uploaded to a server\r\n * with an http request. We'll\r\n * use the `httpDo` options object to send a POST request with some\r\n * specific options: we encode the request as `multipart/form-data`,\r\n * and attach the blob as one of the form values using `FormData`.\r\n *\r\n *\r\n * @method getBlob\r\n * @for p5.SoundFile\r\n * @returns {Blob} A file-like data object\r\n * @example\r\n *
\r\n *\r\n * function preload() {\r\n * mySound = loadSound('assets/doorbell.mp3');\r\n * }\r\n *\r\n * function setup() {\r\n * noCanvas();\r\n * var soundBlob = mySound.getBlob();\r\n *\r\n * // Now we can send the blob to a server...\r\n * var serverUrl = 'https://jsonplaceholder.typicode.com/posts';\r\n * var httpRequestOptions = {\r\n * method: 'POST',\r\n * body: new FormData().append('soundBlob', soundBlob),\r\n * headers: new Headers({\r\n * 'Content-Type': 'multipart/form-data'\r\n * })\r\n * };\r\n * httpDo(serverUrl, httpRequestOptions);\r\n *\r\n * // We can also create an `ObjectURL` pointing to the Blob\r\n * var blobUrl = URL.createObjectURL(soundBlob);\r\n *\r\n * // The `
\r\n */\r\n p5.SoundFile.prototype.getBlob = function() {\r\n const dataView = convertToWav(this.buffer);\r\n return new Blob([dataView], { type: 'audio/wav' });\r\n };\r\n\r\n // event handler to keep track of current position\r\n function _onAudioProcess(processEvent) {\r\n var inputBuffer = processEvent.inputBuffer.getChannelData(0);\r\n\r\n this._lastPos = inputBuffer[inputBuffer.length - 1] || 0;\r\n\r\n // do any callbacks that have been scheduled\r\n this._onTimeUpdate(self._lastPos);\r\n }\r\n\r\n // event handler to remove references to the bufferSourceNode when it is done playing\r\n function _clearOnEnd(e) {\r\n const thisBufferSourceNode = e.target;\r\n const soundFile = this;\r\n\r\n // delete this.bufferSourceNode from the sources array when it is done playing:\r\n thisBufferSourceNode._playing = false;\r\n thisBufferSourceNode.removeEventListener('ended', soundFile._clearOnEnd);\r\n\r\n // call the onended callback\r\n soundFile._onended(soundFile);\r\n\r\n soundFile.bufferSourceNodes.forEach(function (n, i) {\r\n if (n._playing === false) {\r\n soundFile.bufferSourceNodes.splice(i);\r\n }\r\n });\r\n\r\n if (soundFile.bufferSourceNodes.length === 0) {\r\n soundFile._playing = false;\r\n }\r\n }\r\n});\r\n","'use strict';\r\n\r\ndefine(function (require) {\r\n var p5sound = require('master');\r\n var processorNames = require('./audioWorklet/processorNames');\r\n\r\n /**\r\n * Amplitude measures volume between 0.0 and 1.0.\r\n * Listens to all p5sound by default, or use setInput()\r\n * to listen to a specific sound source. Accepts an optional\r\n * smoothing value, which defaults to 0.\r\n *\r\n * @class p5.Amplitude\r\n * @constructor\r\n * @param {Number} [smoothing] between 0.0 and .999 to smooth\r\n * amplitude readings (defaults to 0)\r\n * @example\r\n *
\r\n * var sound, amplitude, cnv;\r\n *\r\n * function preload(){\r\n * sound = loadSound('assets/beat.mp3');\r\n * }\r\n * function setup() {\r\n * cnv = createCanvas(100,100);\r\n * amplitude = new p5.Amplitude();\r\n *\r\n * // start / stop the sound when canvas is clicked\r\n * cnv.mouseClicked(function() {\r\n * if (sound.isPlaying() ){\r\n * sound.stop();\r\n * } else {\r\n * sound.play();\r\n * }\r\n * });\r\n * }\r\n * function draw() {\r\n * background(0);\r\n * fill(255);\r\n * var level = amplitude.getLevel();\r\n * var size = map(level, 0, 1, 0, 200);\r\n * ellipse(width/2, height/2, size, size);\r\n * }\r\n *\r\n *
\r\n */\r\n p5.Amplitude = function(smoothing) {\r\n\r\n // Set to 2048 for now. In future iterations, this should be inherited or parsed from p5sound's default\r\n this.bufferSize = 2048;\r\n\r\n // set audio context\r\n this.audiocontext = p5sound.audiocontext;\r\n this._workletNode = new AudioWorkletNode(this.audiocontext, processorNames.amplitudeProcessor, {\r\n outputChannelCount: [1],\r\n parameterData: { smoothing: smoothing || 0 },\r\n processorOptions: { normalize: false }\r\n });\r\n\r\n this._workletNode.port.onmessage = function(event) {\r\n if (event.data.name === 'amplitude') {\r\n this.volume = event.data.volume;\r\n this.volNorm = event.data.volNorm;\r\n this.stereoVol = event.data.stereoVol;\r\n this.stereoVolNorm = event.data.stereoVolNorm;\r\n }\r\n }.bind(this);\r\n\r\n // for connections\r\n this.input = this._workletNode;\r\n\r\n this.output = this.audiocontext.createGain();\r\n\r\n // the variables to return\r\n this.volume = 0;\r\n this.volNorm = 0;\r\n this.stereoVol = [0, 0];\r\n this.stereoVolNorm = [0, 0];\r\n\r\n this.normalize = false;\r\n\r\n this._workletNode.connect(this.output);\r\n this.output.gain.value = 0;\r\n\r\n // this may only be necessary because of a Chrome bug\r\n this.output.connect(this.audiocontext.destination);\r\n\r\n // connect to p5sound master output by default, unless set by input()\r\n p5sound.meter.connect(this._workletNode);\r\n\r\n // add this p5.SoundFile to the soundArray\r\n p5sound.soundArray.push(this);\r\n };\r\n\r\n /**\r\n * Connects to the p5sound instance (master output) by default.\r\n * Optionally, you can pass in a specific source (i.e. a soundfile).\r\n *\r\n * @method setInput\r\n * @for p5.Amplitude\r\n * @param {soundObject|undefined} [snd] set the sound source\r\n * (optional, defaults to\r\n * master output)\r\n * @param {Number|undefined} [smoothing] a range between 0.0 and 1.0\r\n * to smooth amplitude readings\r\n * @example\r\n *
\r\n * function preload(){\r\n * sound1 = loadSound('assets/beat.mp3');\r\n * sound2 = loadSound('assets/drum.mp3');\r\n * }\r\n * function setup(){\r\n * amplitude = new p5.Amplitude();\r\n * sound1.play();\r\n * sound2.play();\r\n * amplitude.setInput(sound2);\r\n * }\r\n * function draw() {\r\n * background(0);\r\n * fill(255);\r\n * var level = amplitude.getLevel();\r\n * var size = map(level, 0, 1, 0, 200);\r\n * ellipse(width/2, height/2, size, size);\r\n * }\r\n * function mouseClicked(){\r\n * sound1.stop();\r\n * sound2.stop();\r\n * }\r\n *
\r\n */\r\n p5.Amplitude.prototype.setInput = function(source, smoothing) {\r\n\r\n p5sound.meter.disconnect();\r\n\r\n if (smoothing) {\r\n this._workletNode.parameters.get('smoothing').value = smoothing;\r\n }\r\n\r\n // connect to the master out of p5s instance if no snd is provided\r\n if (source == null) {\r\n console.log('Amplitude input source is not ready! Connecting to master output instead');\r\n p5sound.meter.connect(this._workletNode);\r\n }\r\n\r\n // if it is a p5.Signal\r\n else if (source instanceof p5.Signal) {\r\n source.output.connect(this._workletNode);\r\n }\r\n // connect to the sound if it is available\r\n else if (source) {\r\n source.connect(this._workletNode);\r\n this._workletNode.disconnect();\r\n this._workletNode.connect(this.output);\r\n }\r\n\r\n // otherwise, connect to the master out of p5s instance (default)\r\n else {\r\n p5sound.meter.connect(this._workletNode);\r\n }\r\n };\r\n\r\n p5.Amplitude.prototype.connect = function(unit) {\r\n if (unit) {\r\n if (unit.hasOwnProperty('input')) {\r\n this.output.connect(unit.input);\r\n } else {\r\n this.output.connect(unit);\r\n }\r\n } else {\r\n this.output.connect(this.panner.connect(p5sound.input));\r\n }\r\n };\r\n\r\n p5.Amplitude.prototype.disconnect = function() {\r\n if (this.output) {\r\n this.output.disconnect();\r\n }\r\n };\r\n\r\n /**\r\n * Returns a single Amplitude reading at the moment it is called.\r\n * For continuous readings, run in the draw loop.\r\n *\r\n * @method getLevel\r\n * @for p5.Amplitude\r\n * @param {Number} [channel] Optionally return only channel 0 (left) or 1 (right)\r\n * @return {Number} Amplitude as a number between 0.0 and 1.0\r\n * @example\r\n *
\r\n * function preload(){\r\n * sound = loadSound('assets/beat.mp3');\r\n * }\r\n * function setup() {\r\n * amplitude = new p5.Amplitude();\r\n * sound.play();\r\n * }\r\n * function draw() {\r\n * background(0);\r\n * fill(255);\r\n * var level = amplitude.getLevel();\r\n * var size = map(level, 0, 1, 0, 200);\r\n * ellipse(width/2, height/2, size, size);\r\n * }\r\n * function mouseClicked(){\r\n * sound.stop();\r\n * }\r\n *
\r\n */\r\n p5.Amplitude.prototype.getLevel = function(channel) {\r\n if (typeof channel !== 'undefined') {\r\n if (this.normalize) {\r\n return this.stereoVolNorm[channel];\r\n } else {\r\n return this.stereoVol[channel];\r\n }\r\n }\r\n else if (this.normalize) {\r\n return this.volNorm;\r\n }\r\n else {\r\n return this.volume;\r\n }\r\n };\r\n\r\n /**\r\n * Determines whether the results of Amplitude.process() will be\r\n * Normalized. To normalize, Amplitude finds the difference the\r\n * loudest reading it has processed and the maximum amplitude of\r\n * 1.0. Amplitude adds this difference to all values to produce\r\n * results that will reliably map between 0.0 and 1.0. However,\r\n * if a louder moment occurs, the amount that Normalize adds to\r\n * all the values will change. Accepts an optional boolean parameter\r\n * (true or false). Normalizing is off by default.\r\n *\r\n * @method toggleNormalize\r\n * @for p5.Amplitude\r\n * @param {boolean} [boolean] set normalize to true (1) or false (0)\r\n */\r\n p5.Amplitude.prototype.toggleNormalize = function(bool) {\r\n if (typeof bool === 'boolean') {\r\n this.normalize = bool;\r\n }\r\n else {\r\n this.normalize = !this.normalize;\r\n }\r\n this._workletNode.port.postMessage({ name: 'toggleNormalize', normalize: this.normalize });\r\n };\r\n\r\n /**\r\n * Smooth Amplitude analysis by averaging with the last analysis\r\n * frame. Off by default.\r\n *\r\n * @method smooth\r\n * @for p5.Amplitude\r\n * @param {Number} set smoothing from 0.0 <= 1\r\n */\r\n p5.Amplitude.prototype.smooth = function(s) {\r\n if (s >= 0 && s < 1) {\r\n this._workletNode.parameters.get('smoothing').value = s;\r\n } else {\r\n console.log('Error: smoothing must be between 0 and 1');\r\n }\r\n };\r\n\r\n p5.Amplitude.prototype.dispose = function() {\r\n // remove reference from soundArray\r\n var index = p5sound.soundArray.indexOf(this);\r\n p5sound.soundArray.splice(index, 1);\r\n\r\n if (this.input) {\r\n this.input.disconnect();\r\n delete this.input;\r\n }\r\n if (this.output) {\r\n this.output.disconnect();\r\n delete this.output;\r\n }\r\n\r\n this._workletNode.disconnect();\r\n delete this._workletNode;\r\n };\r\n\r\n});\r\n","'use strict';\r\n\r\ndefine(function(require) {\r\n var p5sound = require('master');\r\n\r\n /**\r\n *
FFT (Fast Fourier Transform) is an analysis algorithm that\r\n * isolates individual\r\n * \r\n * audio frequencies within a waveform.
\r\n *\r\n *
Once instantiated, a p5.FFT object can return an array based on\r\n * two types of analyses: • FFT.waveform() computes\r\n * amplitude values along the time domain. The array indices correspond\r\n * to samples across a brief moment in time. Each value represents\r\n * amplitude of the waveform at that sample of time. \r\n * • FFT.analyze() computes amplitude values along the\r\n * frequency domain. The array indices correspond to frequencies (i.e.\r\n * pitches), from the lowest to the highest that humans can hear. Each\r\n * value represents amplitude at that slice of the frequency spectrum.\r\n * Use with getEnergy() to measure amplitude at specific\r\n * frequencies, or within a range of frequencies.
\r\n *\r\n *
FFT analyzes a very short snapshot of sound called a sample\r\n * buffer. It returns an array of amplitude measurements, referred\r\n * to as bins. The array is 1024 bins long by default.\r\n * You can change the bin array length, but it must be a power of 2\r\n * between 16 and 1024 in order for the FFT algorithm to function\r\n * correctly. The actual size of the FFT buffer is twice the\r\n * number of bins, so given a standard sample rate, the buffer is\r\n * 2048/44100 seconds long.
\r\n *\r\n *\r\n * @class p5.FFT\r\n * @constructor\r\n * @param {Number} [smoothing] Smooth results of Freq Spectrum.\r\n * 0.0 < smoothing < 1.0.\r\n * Defaults to 0.8.\r\n * @param {Number} [bins] Length of resulting array.\r\n * Must be a power of two between\r\n * 16 and 1024. Defaults to 1024.\r\n * @example\r\n *
\r\n * function preload(){\r\n * sound = loadSound('assets/Damscray_DancingTiger.mp3');\r\n * }\r\n *\r\n * function setup(){\r\n * var cnv = createCanvas(100,100);\r\n * cnv.mouseClicked(togglePlay);\r\n * fft = new p5.FFT();\r\n * sound.amp(0.2);\r\n * }\r\n *\r\n * function draw(){\r\n * background(0);\r\n *\r\n * var spectrum = fft.analyze();\r\n * noStroke();\r\n * fill(0,255,0); // spectrum is green\r\n * for (var i = 0; i< spectrum.length; i++){\r\n * var x = map(i, 0, spectrum.length, 0, width);\r\n * var h = -height + map(spectrum[i], 0, 255, height, 0);\r\n * rect(x, height, width / spectrum.length, h )\r\n * }\r\n *\r\n * var waveform = fft.waveform();\r\n * noFill();\r\n * beginShape();\r\n * stroke(255,0,0); // waveform is red\r\n * strokeWeight(1);\r\n * for (var i = 0; i< waveform.length; i++){\r\n * var x = map(i, 0, waveform.length, 0, width);\r\n * var y = map( waveform[i], -1, 1, 0, height);\r\n * vertex(x,y);\r\n * }\r\n * endShape();\r\n *\r\n * text('click to play/pause', 4, 10);\r\n * }\r\n *\r\n * // fade sound if mouse is over canvas\r\n * function togglePlay() {\r\n * if (sound.isPlaying()) {\r\n * sound.pause();\r\n * } else {\r\n * sound.loop();\r\n * }\r\n * }\r\n *
\r\n */\r\n p5.FFT = function(smoothing, bins) {\r\n this.input = this.analyser = p5sound.audiocontext.createAnalyser();\r\n\r\n Object.defineProperties(this, {\r\n bins: {\r\n get: function() {\r\n return this.analyser.fftSize / 2;\r\n },\r\n set: function(b) {\r\n this.analyser.fftSize = b * 2;\r\n },\r\n configurable: true,\r\n enumerable: true\r\n },\r\n smoothing: {\r\n get: function() {\r\n return this.analyser.smoothingTimeConstant;\r\n },\r\n set: function(s) {\r\n this.analyser.smoothingTimeConstant = s;\r\n },\r\n configurable: true,\r\n enumerable: true\r\n }\r\n });\r\n\r\n // set default smoothing and bins\r\n this.smooth(smoothing);\r\n this.bins = bins || 1024;\r\n\r\n // default connections to p5sound fftMeter\r\n p5sound.fftMeter.connect(this.analyser);\r\n\r\n this.freqDomain = new Uint8Array(this.analyser.frequencyBinCount);\r\n this.timeDomain = new Uint8Array(this.analyser.frequencyBinCount);\r\n\r\n // predefined frequency ranges, these will be tweakable\r\n this.bass = [20, 140];\r\n this.lowMid = [140, 400];\r\n this.mid = [400, 2600];\r\n this.highMid = [2600, 5200];\r\n this.treble = [5200, 14000];\r\n\r\n // add this p5.SoundFile to the soundArray\r\n p5sound.soundArray.push(this);\r\n };\r\n\r\n /**\r\n * Set the input source for the FFT analysis. If no source is\r\n * provided, FFT will analyze all sound in the sketch.\r\n *\r\n * @method setInput\r\n * @for p5.FFT\r\n * @param {Object} [source] p5.sound object (or web audio API source node)\r\n */\r\n p5.FFT.prototype.setInput = function(source) {\r\n if (!source) {\r\n p5sound.fftMeter.connect(this.analyser);\r\n } else {\r\n if (source.output) {\r\n source.output.connect(this.analyser);\r\n } else if (source.connect) {\r\n source.connect(this.analyser);\r\n }\r\n p5sound.fftMeter.disconnect();\r\n }\r\n };\r\n\r\n /**\r\n * Returns an array of amplitude values (between -1.0 and +1.0) that represent\r\n * a snapshot of amplitude readings in a single buffer. Length will be\r\n * equal to bins (defaults to 1024). Can be used to draw the waveform\r\n * of a sound.\r\n *\r\n * @method waveform\r\n * @for p5.FFT\r\n * @param {Number} [bins] Must be a power of two between\r\n * 16 and 1024. Defaults to 1024.\r\n * @param {String} [precision] If any value is provided, will return results\r\n * in a Float32 Array which is more precise\r\n * than a regular array.\r\n * @return {Array} Array Array of amplitude values (-1 to 1)\r\n * over time. Array length = bins.\r\n *\r\n */\r\n p5.FFT.prototype.waveform = function() {\r\n var bins, mode, normalArray;\r\n\r\n for (var i = 0; i < arguments.length; i++) {\r\n if (typeof arguments[i] === 'number') {\r\n bins = arguments[i];\r\n this.analyser.fftSize = bins * 2;\r\n }\r\n if (typeof arguments[i] === 'string') {\r\n mode = arguments[i];\r\n }\r\n }\r\n\r\n // getFloatFrequencyData doesnt work in Safari as of 5/2015\r\n if (mode && !p5.prototype._isSafari()) {\r\n timeToFloat(this, this.timeDomain);\r\n this.analyser.getFloatTimeDomainData(this.timeDomain);\r\n return this.timeDomain;\r\n } else {\r\n timeToInt(this, this.timeDomain);\r\n this.analyser.getByteTimeDomainData(this.timeDomain);\r\n var normalArray = new Array();\r\n for (var j = 0; j < this.timeDomain.length; j++) {\r\n var scaled = p5.prototype.map(this.timeDomain[j], 0, 255, -1, 1);\r\n normalArray.push(scaled);\r\n }\r\n return normalArray;\r\n }\r\n };\r\n\r\n /**\r\n * Returns an array of amplitude values (between 0 and 255)\r\n * across the frequency spectrum. Length is equal to FFT bins\r\n * (1024 by default). The array indices correspond to frequencies\r\n * (i.e. pitches), from the lowest to the highest that humans can\r\n * hear. Each value represents amplitude at that slice of the\r\n * frequency spectrum. Must be called prior to using\r\n * getEnergy().\r\n *\r\n * @method analyze\r\n * @for p5.FFT\r\n * @param {Number} [bins] Must be a power of two between\r\n * 16 and 1024. Defaults to 1024.\r\n * @param {Number} [scale] If \"dB,\" returns decibel\r\n * float measurements between\r\n * -140 and 0 (max).\r\n * Otherwise returns integers from 0-255.\r\n * @return {Array} spectrum Array of energy (amplitude/volume)\r\n * values across the frequency spectrum.\r\n * Lowest energy (silence) = 0, highest\r\n * possible is 255.\r\n * @example\r\n *
\r\n * var osc;\r\n * var fft;\r\n *\r\n * function setup(){\r\n * createCanvas(100,100);\r\n * osc = new p5.Oscillator();\r\n * osc.amp(0);\r\n * osc.start();\r\n * fft = new p5.FFT();\r\n * }\r\n *\r\n * function draw(){\r\n * background(0);\r\n *\r\n * var freq = map(mouseX, 0, 800, 20, 15000);\r\n * freq = constrain(freq, 1, 20000);\r\n * osc.freq(freq);\r\n *\r\n * var spectrum = fft.analyze();\r\n * noStroke();\r\n * fill(0,255,0); // spectrum is green\r\n * for (var i = 0; i< spectrum.length; i++){\r\n * var x = map(i, 0, spectrum.length, 0, width);\r\n * var h = -height + map(spectrum[i], 0, 255, height, 0);\r\n * rect(x, height, width / spectrum.length, h );\r\n * }\r\n *\r\n * stroke(255);\r\n * text('Freq: ' + round(freq)+'Hz', 10, 10);\r\n *\r\n * isMouseOverCanvas();\r\n * }\r\n *\r\n * // only play sound when mouse is over canvas\r\n * function isMouseOverCanvas() {\r\n * var mX = mouseX, mY = mouseY;\r\n * if (mX > 0 && mX < width && mY < height && mY > 0) {\r\n * osc.amp(0.5, 0.2);\r\n * } else {\r\n * osc.amp(0, 0.2);\r\n * }\r\n * }\r\n *
\r\n *\r\n *\r\n */\r\n p5.FFT.prototype.analyze = function() {\r\n var mode;\r\n\r\n for (var i = 0; i < arguments.length; i++) {\r\n if (typeof arguments[i] === 'number') {\r\n this.bins = arguments[i];\r\n this.analyser.fftSize = this.bins * 2;\r\n }\r\n if (typeof arguments[i] === 'string') {\r\n mode = arguments[i];\r\n }\r\n }\r\n\r\n if (mode && mode.toLowerCase() === 'db') {\r\n freqToFloat(this);\r\n this.analyser.getFloatFrequencyData(this.freqDomain);\r\n return this.freqDomain;\r\n } else {\r\n freqToInt(this, this.freqDomain);\r\n this.analyser.getByteFrequencyData(this.freqDomain);\r\n var normalArray = Array.apply([], this.freqDomain);\r\n \r\n return normalArray;\r\n }\r\n };\r\n\r\n /**\r\n * Returns the amount of energy (volume) at a specific\r\n * \r\n * frequency, or the average amount of energy between two\r\n * frequencies. Accepts Number(s) corresponding\r\n * to frequency (in Hz), or a String corresponding to predefined\r\n * frequency ranges (\"bass\", \"lowMid\", \"mid\", \"highMid\", \"treble\").\r\n * Returns a range between 0 (no energy/volume at that frequency) and\r\n * 255 (maximum energy).\r\n * NOTE: analyze() must be called prior to getEnergy(). Analyze()\r\n * tells the FFT to analyze frequency data, and getEnergy() uses\r\n * the results determine the value at a specific frequency or\r\n * range of frequencies.
\r\n *\r\n * @method getEnergy\r\n * @for p5.FFT\r\n * @param {Number|String} frequency1 Will return a value representing\r\n * energy at this frequency. Alternately,\r\n * the strings \"bass\", \"lowMid\" \"mid\",\r\n * \"highMid\", and \"treble\" will return\r\n * predefined frequency ranges.\r\n * @param {Number} [frequency2] If a second frequency is given,\r\n * will return average amount of\r\n * energy that exists between the\r\n * two frequencies.\r\n * @return {Number} Energy Energy (volume/amplitude) from\r\n * 0 and 255.\r\n *\r\n */\r\n p5.FFT.prototype.getEnergy = function(frequency1, frequency2) {\r\n var nyquist = p5sound.audiocontext.sampleRate / 2;\r\n\r\n if (frequency1 === 'bass') {\r\n frequency1 = this.bass[0];\r\n frequency2 = this.bass[1];\r\n } else if (frequency1 === 'lowMid') {\r\n frequency1 = this.lowMid[0];\r\n frequency2 = this.lowMid[1];\r\n } else if (frequency1 === 'mid') {\r\n frequency1 = this.mid[0];\r\n frequency2 = this.mid[1];\r\n } else if (frequency1 === 'highMid') {\r\n frequency1 = this.highMid[0];\r\n frequency2 = this.highMid[1];\r\n } else if (frequency1 === 'treble') {\r\n frequency1 = this.treble[0];\r\n frequency2 = this.treble[1];\r\n }\r\n\r\n if (typeof frequency1 !== 'number') {\r\n throw 'invalid input for getEnergy()';\r\n } else if (!frequency2) {\r\n // if only one parameter:\r\n var index = Math.round(frequency1 / nyquist * this.freqDomain.length);\r\n return this.freqDomain[index];\r\n } else if (frequency1 && frequency2) {\r\n // if two parameters:\r\n // if second is higher than first\r\n if (frequency1 > frequency2) {\r\n var swap = frequency2;\r\n frequency2 = frequency1;\r\n frequency1 = swap;\r\n }\r\n var lowIndex = Math.round(frequency1 / nyquist * this.freqDomain.length);\r\n var highIndex = Math.round(frequency2 / nyquist * this.freqDomain.length);\r\n\r\n var total = 0;\r\n var numFrequencies = 0;\r\n // add up all of the values for the frequencies\r\n for (var i = lowIndex; i <= highIndex; i++) {\r\n total += this.freqDomain[i];\r\n numFrequencies += 1;\r\n }\r\n // divide by total number of frequencies\r\n var toReturn = total / numFrequencies;\r\n return toReturn;\r\n } else {\r\n throw 'invalid input for getEnergy()';\r\n }\r\n };\r\n\r\n // compatability with v.012, changed to getEnergy in v.0121. Will be deprecated...\r\n p5.FFT.prototype.getFreq = function(freq1, freq2) {\r\n console.log('getFreq() is deprecated. Please use getEnergy() instead.');\r\n var x = this.getEnergy(freq1, freq2);\r\n return x;\r\n };\r\n\r\n /**\r\n * Returns the\r\n * \r\n * spectral centroid of the input signal.\r\n * NOTE: analyze() must be called prior to getCentroid(). Analyze()\r\n * tells the FFT to analyze frequency data, and getCentroid() uses\r\n * the results determine the spectral centroid.\r\n *\r\n * @method getCentroid\r\n * @for p5.FFT\r\n * @return {Number} Spectral Centroid Frequency Frequency of the spectral centroid in Hz.\r\n *\r\n *\r\n * @example\r\n *
\r\n *\r\n *\r\n *function setup(){\r\n * cnv = createCanvas(100,100);\r\n * sound = new p5.AudioIn();\r\n * sound.start();\r\n * fft = new p5.FFT();\r\n * sound.connect(fft);\r\n *}\r\n *\r\n *\r\n *function draw(){\r\n *\r\n * var centroidplot = 0.0;\r\n * var spectralCentroid = 0;\r\n *\r\n *\r\n * background(0);\r\n * stroke(0,255,0);\r\n * var spectrum = fft.analyze();\r\n * fill(0,255,0); // spectrum is green\r\n *\r\n * //draw the spectrum\r\n * for (var i = 0; i< spectrum.length; i++){\r\n * var x = map(log(i), 0, log(spectrum.length), 0, width);\r\n * var h = map(spectrum[i], 0, 255, 0, height);\r\n * var rectangle_width = (log(i+1)-log(i))*(width/log(spectrum.length));\r\n * rect(x, height, rectangle_width, -h )\r\n * }\r\n\r\n * var nyquist = 22050;\r\n *\r\n * // get the centroid\r\n * spectralCentroid = fft.getCentroid();\r\n *\r\n * // the mean_freq_index calculation is for the display.\r\n * var mean_freq_index = spectralCentroid/(nyquist/spectrum.length);\r\n *\r\n * centroidplot = map(log(mean_freq_index), 0, log(spectrum.length), 0, width);\r\n *\r\n *\r\n * stroke(255,0,0); // the line showing where the centroid is will be red\r\n *\r\n * rect(centroidplot, 0, width / spectrum.length, height)\r\n * noStroke();\r\n * fill(255,255,255); // text is white\r\n * text(\"centroid: \", 10, 20);\r\n * text(round(spectralCentroid)+\" Hz\", 10, 40);\r\n *}\r\n *
\r\n */\r\n p5.FFT.prototype.getCentroid = function() {\r\n var nyquist = p5sound.audiocontext.sampleRate / 2;\r\n var cumulative_sum = 0;\r\n var centroid_normalization = 0;\r\n\r\n for (var i = 0; i < this.freqDomain.length; i++) {\r\n cumulative_sum += i * this.freqDomain[i];\r\n centroid_normalization += this.freqDomain[i];\r\n }\r\n\r\n var mean_freq_index = 0;\r\n\r\n if (centroid_normalization !== 0) {\r\n mean_freq_index = cumulative_sum / centroid_normalization;\r\n }\r\n\r\n var spec_centroid_freq =\r\n mean_freq_index * (nyquist / this.freqDomain.length);\r\n return spec_centroid_freq;\r\n };\r\n\r\n /**\r\n * Smooth FFT analysis by averaging with the last analysis frame.\r\n *\r\n * @method smooth\r\n * @param {Number} smoothing 0.0 < smoothing < 1.0.\r\n * Defaults to 0.8.\r\n */\r\n p5.FFT.prototype.smooth = function(s) {\r\n if (typeof s !== 'undefined') {\r\n this.smoothing = s;\r\n }\r\n return this.smoothing;\r\n };\r\n\r\n p5.FFT.prototype.dispose = function() {\r\n // remove reference from soundArray\r\n var index = p5sound.soundArray.indexOf(this);\r\n p5sound.soundArray.splice(index, 1);\r\n\r\n if (this.analyser) {\r\n this.analyser.disconnect();\r\n delete this.analyser;\r\n }\r\n };\r\n\r\n /**\r\n * Returns an array of average amplitude values for a given number\r\n * of frequency bands split equally. N defaults to 16.\r\n * NOTE: analyze() must be called prior to linAverages(). Analyze()\r\n * tells the FFT to analyze frequency data, and linAverages() uses\r\n * the results to group them into a smaller set of averages.\r\n *\r\n * @method linAverages\r\n * @for p5.FFT\r\n * @param {Number} N Number of returned frequency groups\r\n * @return {Array} linearAverages Array of average amplitude values for each group\r\n */\r\n p5.FFT.prototype.linAverages = function(N) {\r\n var N = N || 16; // This prevents undefined, null or 0 values of N\r\n\r\n var spectrum = this.freqDomain;\r\n var spectrumLength = spectrum.length;\r\n var spectrumStep = Math.floor(spectrumLength / N);\r\n\r\n var linearAverages = new Array(N);\r\n // Keep a second index for the current average group and place the values accordingly\r\n // with only one loop in the spectrum data\r\n var groupIndex = 0;\r\n\r\n for (var specIndex = 0; specIndex < spectrumLength; specIndex++) {\r\n linearAverages[groupIndex] =\r\n linearAverages[groupIndex] !== undefined\r\n ? (linearAverages[groupIndex] + spectrum[specIndex]) / 2\r\n : spectrum[specIndex];\r\n\r\n // Increase the group index when the last element of the group is processed\r\n if (specIndex % spectrumStep === spectrumStep - 1) {\r\n groupIndex++;\r\n }\r\n }\r\n\r\n return linearAverages;\r\n };\r\n\r\n /**\r\n * Returns an array of average amplitude values of the spectrum, for a given\r\n * set of \r\n * Octave Bands\r\n * NOTE: analyze() must be called prior to logAverages(). Analyze()\r\n * tells the FFT to analyze frequency data, and logAverages() uses\r\n * the results to group them into a smaller set of averages.\r\n *\r\n * @method logAverages\r\n * @for p5.FFT\r\n * @param {Array} octaveBands Array of Octave Bands objects for grouping\r\n * @return {Array} logAverages Array of average amplitude values for each group\r\n */\r\n p5.FFT.prototype.logAverages = function(octaveBands) {\r\n var nyquist = p5sound.audiocontext.sampleRate / 2;\r\n var spectrum = this.freqDomain;\r\n var spectrumLength = spectrum.length;\r\n\r\n var logAverages = new Array(octaveBands.length);\r\n // Keep a second index for the current average group and place the values accordingly\r\n // With only one loop in the spectrum data\r\n var octaveIndex = 0;\r\n\r\n for (var specIndex = 0; specIndex < spectrumLength; specIndex++) {\r\n var specIndexFrequency = Math.round(\r\n specIndex * nyquist / this.freqDomain.length\r\n );\r\n\r\n // Increase the group index if the current frequency exceeds the limits of the band\r\n if (specIndexFrequency > octaveBands[octaveIndex].hi) {\r\n octaveIndex++;\r\n }\r\n\r\n logAverages[octaveIndex] =\r\n logAverages[octaveIndex] !== undefined\r\n ? (logAverages[octaveIndex] + spectrum[specIndex]) / 2\r\n : spectrum[specIndex];\r\n }\r\n\r\n return logAverages;\r\n };\r\n\r\n /**\r\n * Calculates and Returns the 1/N\r\n * Octave Bands\r\n * N defaults to 3 and minimum central frequency to 15.625Hz.\r\n * (1/3 Octave Bands ~= 31 Frequency Bands)\r\n * Setting fCtr0 to a central value of a higher octave will ignore the lower bands\r\n * and produce less frequency groups.\r\n *\r\n * @method getOctaveBands\r\n * @for p5.FFT\r\n * @param {Number} N Specifies the 1/N type of generated octave bands\r\n * @param {Number} fCtr0 Minimum central frequency for the lowest band\r\n * @return {Array} octaveBands Array of octave band objects with their bounds\r\n */\r\n p5.FFT.prototype.getOctaveBands = function(N, fCtr0) {\r\n var N = N || 3; // Default to 1/3 Octave Bands\r\n var fCtr0 = fCtr0 || 15.625; // Minimum central frequency, defaults to 15.625Hz\r\n\r\n var octaveBands = [];\r\n var lastFrequencyBand = {\r\n lo: fCtr0 / Math.pow(2, 1 / (2 * N)),\r\n ctr: fCtr0,\r\n hi: fCtr0 * Math.pow(2, 1 / (2 * N))\r\n };\r\n octaveBands.push(lastFrequencyBand);\r\n\r\n var nyquist = p5sound.audiocontext.sampleRate / 2;\r\n while (lastFrequencyBand.hi < nyquist) {\r\n var newFrequencyBand = {};\r\n newFrequencyBand.lo = lastFrequencyBand.hi;\r\n newFrequencyBand.ctr = lastFrequencyBand.ctr * Math.pow(2, 1 / N);\r\n newFrequencyBand.hi = newFrequencyBand.ctr * Math.pow(2, 1 / (2 * N));\r\n\r\n octaveBands.push(newFrequencyBand);\r\n lastFrequencyBand = newFrequencyBand;\r\n }\r\n\r\n return octaveBands;\r\n };\r\n\r\n // helper methods to convert type from float (dB) to int (0-255)\r\n var freqToFloat = function(fft) {\r\n if (fft.freqDomain instanceof Float32Array === false) {\r\n fft.freqDomain = new Float32Array(fft.analyser.frequencyBinCount);\r\n }\r\n };\r\n var freqToInt = function(fft) {\r\n if (fft.freqDomain instanceof Uint8Array === false) {\r\n fft.freqDomain = new Uint8Array(fft.analyser.frequencyBinCount);\r\n }\r\n };\r\n var timeToFloat = function(fft) {\r\n if (fft.timeDomain instanceof Float32Array === false) {\r\n fft.timeDomain = new Float32Array(fft.analyser.frequencyBinCount);\r\n }\r\n };\r\n var timeToInt = function(fft) {\r\n if (fft.timeDomain instanceof Uint8Array === false) {\r\n fft.timeDomain = new Uint8Array(fft.analyser.frequencyBinCount);\r\n }\r\n };\r\n});\r\n","'use strict';\r\n\r\ndefine(function (require) {\r\n\r\n // Signal is built with the Tone.js signal by Yotam Mann\r\n // https://github.com/TONEnoTONE/Tone.js/\r\n var Signal = require('Tone/signal/Signal');\r\n var Add = require('Tone/signal/Add');\r\n var Mult = require('Tone/signal/Multiply');\r\n var Scale = require('Tone/signal/Scale');\r\n\r\n /**\r\n *
p5.Signal is a constant audio-rate signal used by p5.Oscillator\r\n * and p5.Envelope for modulation math.
\r\n *\r\n *
This is necessary because Web Audio is processed on a seprate clock.\r\n * For example, the p5 draw loop runs about 60 times per second. But\r\n * the audio clock must process samples 44100 times per second. If we\r\n * want to add a value to each of those samples, we can't do it in the\r\n * draw loop, but we can do it by adding a constant-rate audio signal.This class mostly functions behind the scenes in p5.sound, and returns\r\n * a Tone.Signal from the Tone.js library by Yotam Mann.\r\n * If you want to work directly with audio signals for modular\r\n * synthesis, check out\r\n * tone.js.
\r\n *\r\n * @class p5.Signal\r\n * @constructor\r\n * @return {Tone.Signal} A Signal object from the Tone.js library\r\n * @example\r\n *
\r\n * function setup() {\r\n * carrier = new p5.Oscillator('sine');\r\n * carrier.amp(1); // set amplitude\r\n * carrier.freq(220); // set frequency\r\n * carrier.start(); // start oscillating\r\n *\r\n * modulator = new p5.Oscillator('sawtooth');\r\n * modulator.disconnect();\r\n * modulator.amp(1);\r\n * modulator.freq(4);\r\n * modulator.start();\r\n *\r\n * // Modulator's default amplitude range is -1 to 1.\r\n * // Multiply it by -200, so the range is -200 to 200\r\n * // then add 220 so the range is 20 to 420\r\n * carrier.freq( modulator.mult(-200).add(220) );\r\n * }\r\n *
\r\n */\r\n p5.Signal = function(value) {\r\n var s = new Signal(value);\r\n // p5sound.soundArray.push(s);\r\n return s; // TODO: is this really a constructor?\r\n };\r\n\r\n /**\r\n * Fade to value, for smooth transitions\r\n *\r\n * @method fade\r\n * @for p5.Signal\r\n * @param {Number} value Value to set this signal\r\n * @param {Number} [secondsFromNow] Length of fade, in seconds from now\r\n */\r\n Signal.prototype.fade = Signal.prototype.linearRampToValueAtTime;\r\n Mult.prototype.fade = Signal.prototype.fade;\r\n Add.prototype.fade = Signal.prototype.fade;\r\n Scale.prototype.fade = Signal.prototype.fade;\r\n\r\n\r\n /**\r\n * Connect a p5.sound object or Web Audio node to this\r\n * p5.Signal so that its amplitude values can be scaled.\r\n *\r\n * @method setInput\r\n * @for p5.Signal\r\n * @param {Object} input\r\n */\r\n Signal.prototype.setInput = function(_input) {\r\n _input.connect(this);\r\n };\r\n Mult.prototype.setInput = Signal.prototype.setInput;\r\n Add.prototype.setInput = Signal.prototype.setInput;\r\n Scale.prototype.setInput = Signal.prototype.setInput;\r\n\r\n\r\n // signals can add / mult / scale themselves\r\n\r\n /**\r\n * Add a constant value to this audio signal,\r\n * and return the resulting audio signal. Does\r\n * not change the value of the original signal,\r\n * instead it returns a new p5.SignalAdd.\r\n *\r\n * @method add\r\n * @for p5.Signal\r\n * @param {Number} number\r\n * @return {p5.Signal} object\r\n */\r\n Signal.prototype.add = function(num) {\r\n var add = new Add(num);\r\n // add.setInput(this);\r\n this.connect(add);\r\n return add;\r\n };\r\n Mult.prototype.add = Signal.prototype.add;\r\n Add.prototype.add = Signal.prototype.add;\r\n Scale.prototype.add = Signal.prototype.add;\r\n\r\n /**\r\n * Multiply this signal by a constant value,\r\n * and return the resulting audio signal. Does\r\n * not change the value of the original signal,\r\n * instead it returns a new p5.SignalMult.\r\n *\r\n * @method mult\r\n * @for p5.Signal\r\n * @param {Number} number to multiply\r\n * @return {p5.Signal} object\r\n */\r\n Signal.prototype.mult = function(num) {\r\n var mult = new Mult(num);\r\n // mult.setInput(this);\r\n this.connect(mult);\r\n return mult;\r\n };\r\n Mult.prototype.mult = Signal.prototype.mult;\r\n Add.prototype.mult = Signal.prototype.mult;\r\n Scale.prototype.mult = Signal.prototype.mult;\r\n\r\n /**\r\n * Scale this signal value to a given range,\r\n * and return the result as an audio signal. Does\r\n * not change the value of the original signal,\r\n * instead it returns a new p5.SignalScale.\r\n *\r\n * @method scale\r\n * @for p5.Signal\r\n * @param {Number} number to multiply\r\n * @param {Number} inMin input range minumum\r\n * @param {Number} inMax input range maximum\r\n * @param {Number} outMin input range minumum\r\n * @param {Number} outMax input range maximum\r\n * @return {p5.Signal} object\r\n */\r\n Signal.prototype.scale = function(inMin, inMax, outMin, outMax) {\r\n var mapOutMin, mapOutMax;\r\n if (arguments.length === 4) {\r\n mapOutMin = p5.prototype.map(outMin, inMin, inMax, 0, 1) - 0.5;\r\n mapOutMax = p5.prototype.map(outMax, inMin, inMax, 0, 1) - 0.5;\r\n }\r\n else {\r\n mapOutMin = arguments[0];\r\n mapOutMax = arguments[1];\r\n }\r\n var scale = new Scale(mapOutMin, mapOutMax);\r\n this.connect(scale);\r\n return scale;\r\n };\r\n Mult.prototype.scale = Signal.prototype.scale;\r\n Add.prototype.scale = Signal.prototype.scale;\r\n Scale.prototype.scale = Signal.prototype.scale;\r\n\r\n});\r\n\r\n\r\n","define([\"Tone/core/Tone\", \"Tone/type/TimeBase\"], function (Tone) {\n\n\t/**\n\t * @class Tone.Frequency is a primitive type for encoding Frequency values. \n\t * Eventually all time values are evaluated to hertz\n\t * using the `eval` method. \n\t * @constructor\n\t * @extends {Tone.TimeBase}\n\t * @param {String|Number} val The time value.\n\t * @param {String=} units The units of the value.\n\t * @example\n\t * Tone.Frequency(\"C3\") // 261\n\t * Tone.Frequency(38, \"midi\") //\n\t * Tone.Frequency(\"C3\").transpose(4);\n\t */\n\tTone.Frequency = function(val, units){\n\t\tif (this instanceof Tone.Frequency){\n\t\t\t\n\t\t\tTone.TimeBase.call(this, val, units);\n\n\t\t} else {\n\t\t\treturn new Tone.Frequency(val, units);\n\t\t}\n\t};\n\n\tTone.extend(Tone.Frequency, Tone.TimeBase);\n\n\t///////////////////////////////////////////////////////////////////////////\n\t//\tAUGMENT BASE EXPRESSIONS\n\t///////////////////////////////////////////////////////////////////////////\n\n\t//clone the expressions so that \n\t//we can add more without modifying the original\n\tTone.Frequency.prototype._primaryExpressions = Object.create(Tone.TimeBase.prototype._primaryExpressions);\n\n\t/*\n\t * midi type primary expression\n\t * @type {Object}\n\t * @private\n\t */\n\tTone.Frequency.prototype._primaryExpressions.midi = {\n\t\tregexp : /^(\\d+(?:\\.\\d+)?midi)/,\n\t\tmethod : function(value){\n\t\t\treturn this.midiToFrequency(value);\n\t\t}\t\n\t};\n\n\t/*\n\t * note type primary expression\n\t * @type {Object}\n\t * @private\n\t */\n\tTone.Frequency.prototype._primaryExpressions.note = {\n\t\tregexp : /^([a-g]{1}(?:b|#|x|bb)?)(-?[0-9]+)/i,\n\t\tmethod : function(pitch, octave){\n\t\t\tvar index = noteToScaleIndex[pitch.toLowerCase()];\n\t\t\tvar noteNumber = index + (parseInt(octave) + 1) * 12;\n\t\t\treturn this.midiToFrequency(noteNumber);\n\t\t}\t\n\t};\n\n\t/*\n\t * BeatsBarsSixteenths type primary expression\n\t * @type {Object}\n\t * @private\n\t */\n\tTone.Frequency.prototype._primaryExpressions.tr = {\n\t\t\tregexp : /^(\\d+(?:\\.\\d+)?):(\\d+(?:\\.\\d+)?):?(\\d+(?:\\.\\d+)?)?/,\n\t\t\tmethod : function(m, q, s){\n\t\t\tvar total = 1;\n\t\t\tif (m && m !== \"0\"){\n\t\t\t\ttotal *= this._beatsToUnits(this._timeSignature() * parseFloat(m));\n\t\t\t}\n\t\t\tif (q && q !== \"0\"){\n\t\t\t\ttotal *= this._beatsToUnits(parseFloat(q));\n\t\t\t}\n\t\t\tif (s && s !== \"0\"){\n\t\t\t\ttotal *= this._beatsToUnits(parseFloat(s) / 4);\n\t\t\t}\n\t\t\treturn total;\n\t\t}\n\t};\n\n\t///////////////////////////////////////////////////////////////////////////\n\t//\tEXPRESSIONS\n\t///////////////////////////////////////////////////////////////////////////\n\n\t/**\n\t * Transposes the frequency by the given number of semitones.\n\t * @param {Interval} interval\n\t * @return {Tone.Frequency} this\n\t * @example\n\t * Tone.Frequency(\"A4\").transpose(3); //\"C5\"\n\t */\n\tTone.Frequency.prototype.transpose = function(interval){\n\t\tthis._expr = function(expr, interval){\n\t\t\tvar val = expr();\n\t\t\treturn val * this.intervalToFrequencyRatio(interval);\n\t\t}.bind(this, this._expr, interval);\n\t\treturn this;\n\t};\n\n\t/**\n\t * Takes an array of semitone intervals and returns\n\t * an array of frequencies transposed by those intervals.\n\t * @param {Array} intervals\n\t * @return {Tone.Frequency} this\n\t * @example\n\t * Tone.Frequency(\"A4\").harmonize([0, 3, 7]); //[\"A4\", \"C5\", \"E5\"]\n\t */\n\tTone.Frequency.prototype.harmonize = function(intervals){\n\t\tthis._expr = function(expr, intervals){\n\t\t\tvar val = expr();\n\t\t\tvar ret = [];\n\t\t\tfor (var i = 0; i < intervals.length; i++){\n\t\t\t\tret[i] = val * this.intervalToFrequencyRatio(intervals[i]);\n\t\t\t}\n\t\t\treturn ret;\n\t\t}.bind(this, this._expr, intervals);\n\t\treturn this;\n\t};\n\n\t///////////////////////////////////////////////////////////////////////////\n\t//\tUNIT CONVERSIONS\n\t///////////////////////////////////////////////////////////////////////////\n\n\t/**\n\t * Return the value of the frequency as a MIDI note\n\t * @return {MIDI}\n\t * @example\n\t * Tone.Frequency(\"C4\").toMidi(); //60\n\t */\n\tTone.Frequency.prototype.toMidi = function(){\n\t\treturn this.frequencyToMidi(this.valueOf());\n\t};\n\n\t/**\n\t * Return the value of the frequency in Scientific Pitch Notation\n\t * @return {Note}\n\t * @example\n\t * Tone.Frequency(69, \"midi\").toNote(); //\"A4\"\n\t */\n\tTone.Frequency.prototype.toNote = function(){\n\t\tvar freq = this.valueOf();\n\t\tvar log = Math.log(freq / Tone.Frequency.A4) / Math.LN2;\n\t\tvar noteNumber = Math.round(12 * log) + 57;\n\t\tvar octave = Math.floor(noteNumber/12);\n\t\tif(octave < 0){\n\t\t\tnoteNumber += -12 * octave;\n\t\t}\n\t\tvar noteName = scaleIndexToNote[noteNumber % 12];\n\t\treturn noteName + octave.toString();\n\t};\n\n\t/**\n\t * Return the duration of one cycle in seconds.\n\t * @return {Seconds}\n\t */\n\tTone.Frequency.prototype.toSeconds = function(){\n\t\treturn 1 / this.valueOf();\n\t};\n\n\t/**\n\t * Return the value in Hertz\n\t * @return {Frequency}\n\t */\n\tTone.Frequency.prototype.toFrequency = function(){\n\t\treturn this.valueOf();\n\t};\n\n\t/**\n\t * Return the duration of one cycle in ticks\n\t * @return {Ticks}\n\t */\n\tTone.Frequency.prototype.toTicks = function(){\n\t\tvar quarterTime = this._beatsToUnits(1);\n\t\tvar quarters = this.valueOf() / quarterTime;\n\t\treturn Math.floor(quarters * Tone.Transport.PPQ);\n\t};\n\n\t///////////////////////////////////////////////////////////////////////////\n\t//\tUNIT CONVERSIONS HELPERS\n\t///////////////////////////////////////////////////////////////////////////\n\n\t/**\n\t * Returns the value of a frequency in the current units\n\t * @param {Frequency} freq\n\t * @return {Number}\n\t * @private\n\t */\n\tTone.Frequency.prototype._frequencyToUnits = function(freq){\n\t\treturn freq;\n\t};\n\n\t/**\n\t * Returns the value of a tick in the current time units\n\t * @param {Ticks} ticks\n\t * @return {Number}\n\t * @private\n\t */\n\tTone.Frequency.prototype._ticksToUnits = function(ticks){\n\t\treturn 1 / ((ticks * 60) / (Tone.Transport.bpm.value * Tone.Transport.PPQ));\n\t};\n\n\t/**\n\t * Return the value of the beats in the current units\n\t * @param {Number} beats\n\t * @return {Number}\n\t * @private\n\t */\n\tTone.Frequency.prototype._beatsToUnits = function(beats){\n\t\treturn 1 / Tone.TimeBase.prototype._beatsToUnits.call(this, beats);\n\t};\n\n\t/**\n\t * Returns the value of a second in the current units\n\t * @param {Seconds} seconds\n\t * @return {Number}\n\t * @private\n\t */\n\tTone.Frequency.prototype._secondsToUnits = function(seconds){\n\t\treturn 1 / seconds;\n\t};\n\n\t/**\n\t * The default units if none are given.\n\t * @private\n\t */\n\tTone.Frequency.prototype._defaultUnits = \"hz\";\n\n\t///////////////////////////////////////////////////////////////////////////\n\t//\tFREQUENCY CONVERSIONS\n\t///////////////////////////////////////////////////////////////////////////\n\n\t/**\n\t * Note to scale index\n\t * @type {Object}\n\t */\n\tvar noteToScaleIndex = {\n\t\t\"cbb\" : -2, \"cb\" : -1, \"c\" : 0, \"c#\" : 1, \"cx\" : 2, \n\t\t\"dbb\" : 0, \"db\" : 1, \"d\" : 2, \"d#\" : 3, \"dx\" : 4,\n\t\t\"ebb\" : 2, \"eb\" : 3, \"e\" : 4, \"e#\" : 5, \"ex\" : 6, \n\t\t\"fbb\" : 3, \"fb\" : 4, \"f\" : 5, \"f#\" : 6, \"fx\" : 7,\n\t\t\"gbb\" : 5, \"gb\" : 6, \"g\" : 7, \"g#\" : 8, \"gx\" : 9,\n\t\t\"abb\" : 7, \"ab\" : 8, \"a\" : 9, \"a#\" : 10, \"ax\" : 11,\n\t\t\"bbb\" : 9, \"bb\" : 10, \"b\" : 11, \"b#\" : 12, \"bx\" : 13,\n\t};\n\n\t/**\n\t * scale index to note (sharps)\n\t * @type {Array}\n\t */\n\tvar scaleIndexToNote = [\"C\", \"C#\", \"D\", \"D#\", \"E\", \"F\", \"F#\", \"G\", \"G#\", \"A\", \"A#\", \"B\"];\n\n\t/**\n\t * The [concert pitch](https://en.wikipedia.org/wiki/Concert_pitch)\n\t * A4's values in Hertz. \n\t * @type {Frequency}\n\t * @static\n\t */\n\tTone.Frequency.A4 = 440;\n\n\t/**\n\t * Convert a MIDI note to frequency value. \n\t * @param {MIDI} midi The midi number to convert.\n\t * @return {Frequency} the corresponding frequency value\n\t * @example\n\t * tone.midiToFrequency(69); // returns 440\n\t */\n\tTone.Frequency.prototype.midiToFrequency = function(midi){\n\t\treturn Tone.Frequency.A4 * Math.pow(2, (midi - 69) / 12);\n\t};\n\n\t/**\n\t * Convert a frequency value to a MIDI note.\n\t * @param {Frequency} frequency The value to frequency value to convert.\n\t * @returns {MIDI}\n\t * @example\n\t * tone.midiToFrequency(440); // returns 69\n\t */\n\tTone.Frequency.prototype.frequencyToMidi = function(frequency){\n\t\treturn 69 + 12 * Math.log(frequency / Tone.Frequency.A4) / Math.LN2;\n\t};\n\n\treturn Tone.Frequency;\n});","define([\"Tone/core/Tone\", \"Tone/type/Time\"], function (Tone) {\n\n\t/**\n\t * @class Tone.TransportTime is a the time along the Transport's\n\t * timeline. It is similar to Tone.Time, but instead of evaluating\n\t * against the AudioContext's clock, it is evaluated against\n\t * the Transport's position. See [TransportTime wiki](https://github.com/Tonejs/Tone.js/wiki/TransportTime).\n\t * @constructor\n\t * @param {Time} val The time value as a number or string\n\t * @param {String=} units Unit values\n\t * @extends {Tone.Time}\n\t */\n\tTone.TransportTime = function(val, units){\n\t\tif (this instanceof Tone.TransportTime){\n\t\t\t\n\t\t\tTone.Time.call(this, val, units);\n\n\t\t} else {\n\t\t\treturn new Tone.TransportTime(val, units);\n\t\t}\n\t};\n\n\tTone.extend(Tone.TransportTime, Tone.Time);\n\n\t//clone the expressions so that \n\t//we can add more without modifying the original\n\tTone.TransportTime.prototype._unaryExpressions = Object.create(Tone.Time.prototype._unaryExpressions);\n\n\t/**\n\t * Adds an additional unary expression\n\t * which quantizes values to the next subdivision\n\t * @type {Object}\n\t * @private\n\t */\n\tTone.TransportTime.prototype._unaryExpressions.quantize = {\n\t\tregexp : /^@/,\n\t\tmethod : function(rh){\n\t\t\tvar subdivision = this._secondsToTicks(rh());\n\t\t\tvar multiple = Math.ceil(Tone.Transport.ticks / subdivision);\n\t\t\treturn this._ticksToUnits(multiple * subdivision);\n\t\t}\n\t};\n\n\t/**\n\t * Convert seconds into ticks\n\t * @param {Seconds} seconds\n\t * @return {Ticks}\n\t * @private\n\t */\n\tTone.TransportTime.prototype._secondsToTicks = function(seconds){\n\t\tvar quarterTime = this._beatsToUnits(1);\n\t\tvar quarters = seconds / quarterTime;\n\t\treturn Math.round(quarters * Tone.Transport.PPQ);\n\t};\n\n\t/**\n\t * Evaluate the time expression. Returns values in ticks\n\t * @return {Ticks}\n\t */\n\tTone.TransportTime.prototype.valueOf = function(){\n\t\tvar val = this._secondsToTicks(this._expr());\n\t\treturn val + (this._plusNow ? Tone.Transport.ticks : 0);\n\t};\n\n\t/**\n\t * Return the time in ticks.\n\t * @return {Ticks}\n\t */\n\tTone.TransportTime.prototype.toTicks = function(){\n\t\treturn this.valueOf();\n\t};\n\n\t/**\n\t * Return the time in seconds.\n\t * @return {Seconds}\n\t */\n\tTone.TransportTime.prototype.toSeconds = function(){\n\t\tvar val = this._expr();\n\t\treturn val + (this._plusNow ? Tone.Transport.seconds : 0);\n\t};\n\n\t/**\n\t * Return the time as a frequency value\n\t * @return {Frequency} \n\t */\n\tTone.TransportTime.prototype.toFrequency = function(){\n\t\treturn 1/this.toSeconds();\n\t};\n\n\treturn Tone.TransportTime;\n});","'use strict';\r\n\r\ndefine(function (require) {\r\n\r\n var p5sound = require('master');\r\n var Add = require('Tone/signal/Add');\r\n var Mult = require('Tone/signal/Multiply');\r\n var Scale = require('Tone/signal/Scale');\r\n var TimelineSignal = require('Tone/signal/TimelineSignal');\r\n\r\n /**\r\n *
Envelopes are pre-defined amplitude distribution over time.\r\n * Typically, envelopes are used to control the output volume\r\n * of an object, a series of fades referred to as Attack, Decay,\r\n * Sustain and Release (\r\n * ADSR\r\n * ). Envelopes can also control other Web Audio Parameters—for example, a p5.Envelope can\r\n * control an Oscillator's frequency like this: osc.freq(env).
\r\n *
Use setRange to change the attack/release level.\r\n * Use setADSR to change attackTime, decayTime, sustainPercent and releaseTime.
\r\n *
Use the play method to play the entire envelope,\r\n * the ramp method for a pingable trigger,\r\n * or triggerAttack/\r\n * triggerRelease to trigger noteOn/noteOff.
\r\n * var attackLevel = 1.0;\r\n * var releaseLevel = 0;\r\n *\r\n * var attackTime = 0.001;\r\n * var decayTime = 0.2;\r\n * var susPercent = 0.2;\r\n * var releaseTime = 0.5;\r\n *\r\n * var env, triOsc;\r\n *\r\n * function setup() {\r\n * var cnv = createCanvas(100, 100);\r\n *\r\n * textAlign(CENTER);\r\n * text('click to play', width/2, height/2);\r\n *\r\n * env = new p5.Envelope();\r\n * env.setADSR(attackTime, decayTime, susPercent, releaseTime);\r\n * env.setRange(attackLevel, releaseLevel);\r\n *\r\n * triOsc = new p5.Oscillator('triangle');\r\n * triOsc.amp(env);\r\n * triOsc.start();\r\n * triOsc.freq(220);\r\n *\r\n * cnv.mousePressed(playEnv);\r\n * }\r\n *\r\n * function playEnv() {\r\n * env.play();\r\n * }\r\n *
\r\n */\r\n p5.Envelope = function(t1, l1, t2, l2, t3, l3) {\r\n /**\r\n * Time until envelope reaches attackLevel\r\n * @property attackTime\r\n */\r\n this.aTime = t1 || 0.1;\r\n /**\r\n * Level once attack is complete.\r\n * @property attackLevel\r\n */\r\n this.aLevel = l1 || 1;\r\n /**\r\n * Time until envelope reaches decayLevel.\r\n * @property decayTime\r\n */\r\n this.dTime = t2 || 0.5;\r\n /**\r\n * Level after decay. The envelope will sustain here until it is released.\r\n * @property decayLevel\r\n */\r\n this.dLevel = l2 || 0;\r\n /**\r\n * Duration of the release portion of the envelope.\r\n * @property releaseTime\r\n */\r\n this.rTime = t3 || 0;\r\n /**\r\n * Level at the end of the release.\r\n * @property releaseLevel\r\n */\r\n this.rLevel = l3 || 0;\r\n\r\n this._rampHighPercentage = 0.98;\r\n\r\n this._rampLowPercentage = 0.02;\r\n\r\n\r\n this.output = p5sound.audiocontext.createGain();\r\n\r\n this.control = new TimelineSignal();\r\n\r\n this._init(); // this makes sure the envelope starts at zero\r\n\r\n this.control.connect(this.output); // connect to the output\r\n\r\n this.connection = null; // store connection\r\n\r\n //array of math operation signal chaining\r\n this.mathOps = [this.control];\r\n\r\n //whether envelope should be linear or exponential curve\r\n this.isExponential = false;\r\n\r\n // oscillator or buffer source to clear on env complete\r\n // to save resources if/when it is retriggered\r\n this.sourceToClear = null;\r\n\r\n // set to true if attack is set, then false on release\r\n this.wasTriggered = false;\r\n\r\n\r\n // add to the soundArray so we can dispose of the env later\r\n p5sound.soundArray.push(this);\r\n };\r\n\r\n // this init function just smooths the starting value to zero and gives a start point for the timeline\r\n // - it was necessary to remove glitches at the beginning.\r\n p5.Envelope.prototype._init = function () {\r\n var now = p5sound.audiocontext.currentTime;\r\n var t = now;\r\n this.control.setTargetAtTime(0.00001, t, .001);\r\n //also, compute the correct time constants\r\n this._setRampAD(this.aTime, this.dTime);\r\n };\r\n\r\n /**\r\n * Reset the envelope with a series of time/value pairs.\r\n *\r\n * @method set\r\n * @for p5.Envelope\r\n * @param {Number} attackTime Time (in seconds) before level\r\n * reaches attackLevel\r\n * @param {Number} attackLevel Typically an amplitude between\r\n * 0.0 and 1.0\r\n * @param {Number} decayTime Time\r\n * @param {Number} decayLevel Amplitude (In a standard ADSR envelope,\r\n * decayLevel = sustainLevel)\r\n * @param {Number} releaseTime Release Time (in seconds)\r\n * @param {Number} releaseLevel Amplitude\r\n * @example\r\n *
\r\n * var t1 = 0.1; // attack time in seconds\r\n * var l1 = 0.7; // attack level 0.0 to 1.0\r\n * var t2 = 0.3; // decay time in seconds\r\n * var l2 = 0.1; // decay level 0.0 to 1.0\r\n * var t3 = 0.2; // sustain time in seconds\r\n * var l3 = 0.5; // sustain level 0.0 to 1.0\r\n * // release level defaults to zero\r\n *\r\n * var env;\r\n * var triOsc;\r\n *\r\n * function setup() {\r\n * background(0);\r\n * noStroke();\r\n * fill(255);\r\n * textAlign(CENTER);\r\n * text('click to play', width/2, height/2);\r\n *\r\n * env = new p5.Envelope(t1, l1, t2, l2, t3, l3);\r\n * triOsc = new p5.Oscillator('triangle');\r\n * triOsc.amp(env); // give the env control of the triOsc's amp\r\n * triOsc.start();\r\n * }\r\n *\r\n * // mouseClick triggers envelope if over canvas\r\n * function mouseClicked() {\r\n * // is mouse over canvas?\r\n * if (mouseX > 0 && mouseX < width && mouseY > 0 && mouseY < height) {\r\n * env.play(triOsc);\r\n * }\r\n * }\r\n *
\r\n *\r\n */\r\n p5.Envelope.prototype.set = function(t1, l1, t2, l2, t3, l3) {\r\n this.aTime = t1;\r\n this.aLevel = l1;\r\n this.dTime = t2 || 0;\r\n this.dLevel = l2 || 0;\r\n this.rTime = t3 || 0;\r\n this.rLevel = l3 || 0;\r\n\r\n // set time constants for ramp\r\n this._setRampAD(t1, t2);\r\n };\r\n\r\n /**\r\n * Set values like a traditional\r\n * \r\n * ADSR envelope\r\n * .\r\n *\r\n * @method setADSR\r\n * @for p5.Envelope\r\n * @param {Number} attackTime Time (in seconds before envelope\r\n * reaches Attack Level\r\n * @param {Number} [decayTime] Time (in seconds) before envelope\r\n * reaches Decay/Sustain Level\r\n * @param {Number} [susRatio] Ratio between attackLevel and releaseLevel, on a scale from 0 to 1,\r\n * where 1.0 = attackLevel, 0.0 = releaseLevel.\r\n * The susRatio determines the decayLevel and the level at which the\r\n * sustain portion of the envelope will sustain.\r\n * For example, if attackLevel is 0.4, releaseLevel is 0,\r\n * and susAmt is 0.5, the decayLevel would be 0.2. If attackLevel is\r\n * increased to 1.0 (using setRange),\r\n * then decayLevel would increase proportionally, to become 0.5.\r\n * @param {Number} [releaseTime] Time in seconds from now (defaults to 0)\r\n * @example\r\n *
\r\n * var attackLevel = 1.0;\r\n * var releaseLevel = 0;\r\n *\r\n * var attackTime = 0.001;\r\n * var decayTime = 0.2;\r\n * var susPercent = 0.2;\r\n * var releaseTime = 0.5;\r\n *\r\n * var env, triOsc;\r\n *\r\n * function setup() {\r\n * var cnv = createCanvas(100, 100);\r\n *\r\n * textAlign(CENTER);\r\n * text('click to play', width/2, height/2);\r\n *\r\n * env = new p5.Envelope();\r\n * env.setADSR(attackTime, decayTime, susPercent, releaseTime);\r\n * env.setRange(attackLevel, releaseLevel);\r\n *\r\n * triOsc = new p5.Oscillator('triangle');\r\n * triOsc.amp(env);\r\n * triOsc.start();\r\n * triOsc.freq(220);\r\n *\r\n * cnv.mousePressed(playEnv);\r\n * }\r\n *\r\n * function playEnv() {\r\n * env.play();\r\n * }\r\n *
\r\n */\r\n p5.Envelope.prototype.setADSR = function(aTime, dTime, sPercent, rTime) {\r\n this.aTime = aTime;\r\n this.dTime = dTime || 0;\r\n\r\n // lerp\r\n this.sPercent = sPercent || 0;\r\n this.dLevel = typeof sPercent !== 'undefined' ? sPercent * (this.aLevel - this.rLevel) + this.rLevel : 0;\r\n\r\n this.rTime = rTime || 0;\r\n\r\n // also set time constants for ramp\r\n this._setRampAD(aTime, dTime);\r\n };\r\n\r\n /**\r\n * Set max (attackLevel) and min (releaseLevel) of envelope.\r\n *\r\n * @method setRange\r\n * @for p5.Envelope\r\n * @param {Number} aLevel attack level (defaults to 1)\r\n * @param {Number} rLevel release level (defaults to 0)\r\n * @example\r\n *
\r\n * var attackLevel = 1.0;\r\n * var releaseLevel = 0;\r\n *\r\n * var attackTime = 0.001;\r\n * var decayTime = 0.2;\r\n * var susPercent = 0.2;\r\n * var releaseTime = 0.5;\r\n *\r\n * var env, triOsc;\r\n *\r\n * function setup() {\r\n * var cnv = createCanvas(100, 100);\r\n *\r\n * textAlign(CENTER);\r\n * text('click to play', width/2, height/2);\r\n *\r\n * env = new p5.Envelope();\r\n * env.setADSR(attackTime, decayTime, susPercent, releaseTime);\r\n * env.setRange(attackLevel, releaseLevel);\r\n *\r\n * triOsc = new p5.Oscillator('triangle');\r\n * triOsc.amp(env);\r\n * triOsc.start();\r\n * triOsc.freq(220);\r\n *\r\n * cnv.mousePressed(playEnv);\r\n * }\r\n *\r\n * function playEnv() {\r\n * env.play();\r\n * }\r\n *
\r\n */\r\n p5.Envelope.prototype.setRange = function(aLevel, rLevel) {\r\n this.aLevel = aLevel || 1;\r\n this.rLevel = rLevel || 0;\r\n\r\n // not sure if this belongs here:\r\n\r\n // {Number} [dLevel] decay/sustain level (optional)\r\n // if (typeof(dLevel) !== 'undefined') {\r\n // this.dLevel = dLevel\r\n // } else if (this.sPercent) {\r\n // this.dLevel = this.sPercent ? this.sPercent * (this.aLevel - this.rLevel) + this.rLevel : 0;\r\n // }\r\n };\r\n\r\n // private (undocumented) method called when ADSR is set to set time constants for ramp\r\n //\r\n // Set the \r\n // time constants for simple exponential ramps.\r\n // The larger the time constant value, the slower the\r\n // transition will be.\r\n //\r\n // method _setRampAD\r\n // param {Number} attackTimeConstant attack time constant\r\n // param {Number} decayTimeConstant decay time constant\r\n //\r\n p5.Envelope.prototype._setRampAD = function(t1, t2) {\r\n this._rampAttackTime = this.checkExpInput(t1);\r\n this._rampDecayTime = this.checkExpInput(t2);\r\n\r\n var TCDenominator = 1.0;\r\n /// Aatish Bhatia's calculation for time constant for rise(to adjust 1/1-e calculation to any percentage)\r\n TCDenominator = Math.log(1.0 / this.checkExpInput(1.0 - this._rampHighPercentage));\r\n this._rampAttackTC = t1 / this.checkExpInput(TCDenominator);\r\n TCDenominator = Math.log(1.0 / this._rampLowPercentage);\r\n this._rampDecayTC = t2 / this.checkExpInput(TCDenominator);\r\n };\r\n\r\n // private method\r\n p5.Envelope.prototype.setRampPercentages = function(p1, p2) {\r\n //set the percentages that the simple exponential ramps go to\r\n this._rampHighPercentage = this.checkExpInput(p1);\r\n this._rampLowPercentage = this.checkExpInput(p2);\r\n var TCDenominator = 1.0;\r\n //now re-compute the time constants based on those percentages\r\n /// Aatish Bhatia's calculation for time constant for rise(to adjust 1/1-e calculation to any percentage)\r\n TCDenominator = Math.log(1.0 / this.checkExpInput(1.0 - this._rampHighPercentage));\r\n this._rampAttackTC = this._rampAttackTime / this.checkExpInput(TCDenominator);\r\n TCDenominator = Math.log(1.0 / this._rampLowPercentage);\r\n this._rampDecayTC = this._rampDecayTime / this.checkExpInput(TCDenominator);\r\n };\r\n\r\n\r\n /**\r\n * Assign a parameter to be controlled by this envelope.\r\n * If a p5.Sound object is given, then the p5.Envelope will control its\r\n * output gain. If multiple inputs are provided, the env will\r\n * control all of them.\r\n *\r\n * @method setInput\r\n * @for p5.Envelope\r\n * @param {Object} [...inputs] A p5.sound object or\r\n * Web Audio Param.\r\n */\r\n p5.Envelope.prototype.setInput = function() {\r\n for (var i = 0; i\r\n * Web Audio Audio Param.\r\n *\r\n * @method play\r\n * @for p5.Envelope\r\n * @param {Object} unit A p5.sound object or\r\n * Web Audio Param.\r\n * @param {Number} [startTime] time from now (in seconds) at which to play\r\n * @param {Number} [sustainTime] time to sustain before releasing the envelope\r\n * @example\r\n *
\r\n * var attackLevel = 1.0;\r\n * var releaseLevel = 0;\r\n *\r\n * var attackTime = 0.001;\r\n * var decayTime = 0.2;\r\n * var susPercent = 0.2;\r\n * var releaseTime = 0.5;\r\n *\r\n * var env, triOsc;\r\n *\r\n * function setup() {\r\n * var cnv = createCanvas(100, 100);\r\n *\r\n * textAlign(CENTER);\r\n * text('click to play', width/2, height/2);\r\n *\r\n * env = new p5.Envelope();\r\n * env.setADSR(attackTime, decayTime, susPercent, releaseTime);\r\n * env.setRange(attackLevel, releaseLevel);\r\n *\r\n * triOsc = new p5.Oscillator('triangle');\r\n * triOsc.amp(env);\r\n * triOsc.start();\r\n * triOsc.freq(220);\r\n *\r\n * cnv.mousePressed(playEnv);\r\n * }\r\n *\r\n * function playEnv() {\r\n * // trigger env on triOsc, 0 seconds from now\r\n * // After decay, sustain for 0.2 seconds before release\r\n * env.play(triOsc, 0, 0.2);\r\n * }\r\n *
\r\n */\r\n p5.Envelope.prototype.play = function(unit, secondsFromNow, susTime) {\r\n var tFromNow = secondsFromNow || 0;\r\n var susTime = susTime || 0;\r\n\r\n if (unit) {\r\n if (this.connection !== unit) {\r\n this.connect(unit);\r\n }\r\n }\r\n\r\n this.triggerAttack(unit, tFromNow);\r\n\r\n this.triggerRelease(unit, tFromNow + this.aTime + this.dTime + susTime);\r\n\r\n };\r\n\r\n /**\r\n * Trigger the Attack, and Decay portion of the Envelope.\r\n * Similar to holding down a key on a piano, but it will\r\n * hold the sustain level until you let go. Input can be\r\n * any p5.sound object, or a \r\n * Web Audio Param.\r\n *\r\n * @method triggerAttack\r\n * @for p5.Envelope\r\n * @param {Object} unit p5.sound Object or Web Audio Param\r\n * @param {Number} secondsFromNow time from now (in seconds)\r\n * @example\r\n *
\r\n *\r\n * var attackLevel = 1.0;\r\n * var releaseLevel = 0;\r\n *\r\n * var attackTime = 0.001;\r\n * var decayTime = 0.3;\r\n * var susPercent = 0.4;\r\n * var releaseTime = 0.5;\r\n *\r\n * var env, triOsc;\r\n *\r\n * function setup() {\r\n * var cnv = createCanvas(100, 100);\r\n * background(200);\r\n * textAlign(CENTER);\r\n * text('click to play', width/2, height/2);\r\n *\r\n * env = new p5.Envelope();\r\n * env.setADSR(attackTime, decayTime, susPercent, releaseTime);\r\n * env.setRange(attackLevel, releaseLevel);\r\n *\r\n * triOsc = new p5.Oscillator('triangle');\r\n * triOsc.amp(env);\r\n * triOsc.start();\r\n * triOsc.freq(220);\r\n *\r\n * cnv.mousePressed(envAttack);\r\n * }\r\n *\r\n * function envAttack() {\r\n * console.log('trigger attack');\r\n * env.triggerAttack();\r\n *\r\n * background(0,255,0);\r\n * text('attack!', width/2, height/2);\r\n * }\r\n *\r\n * function mouseReleased() {\r\n * env.triggerRelease();\r\n *\r\n * background(200);\r\n * text('click to play', width/2, height/2);\r\n * }\r\n *
\r\n */\r\n p5.Envelope.prototype.triggerAttack = function(unit, secondsFromNow) {\r\n var now = p5sound.audiocontext.currentTime;\r\n var tFromNow = secondsFromNow || 0;\r\n var t = now + tFromNow;\r\n this.lastAttack = t;\r\n this.wasTriggered = true;\r\n\r\n if (unit) {\r\n if (this.connection !== unit) {\r\n this.connect(unit);\r\n }\r\n }\r\n\r\n // get and set value (with linear ramp) to anchor automation\r\n var valToSet = this.control.getValueAtTime(t);\r\n\r\n if (this.isExponential === true)\r\n {\r\n this.control.exponentialRampToValueAtTime(this.checkExpInput(valToSet), t);\r\n }\r\n else\r\n {\r\n this.control.linearRampToValueAtTime(valToSet, t);\r\n }\r\n\r\n // after each ramp completes, cancel scheduled values\r\n // (so they can be overridden in case env has been re-triggered)\r\n // then, set current value (with linearRamp to avoid click)\r\n // then, schedule the next automation...\r\n\r\n // attack\r\n t += this.aTime;\r\n if (this.isExponential === true)\r\n {\r\n this.control.exponentialRampToValueAtTime(this.checkExpInput(this.aLevel), t);\r\n valToSet = this.checkExpInput(this.control.getValueAtTime(t));\r\n this.control.cancelScheduledValues(t);\r\n this.control.exponentialRampToValueAtTime(valToSet, t);\r\n }\r\n else\r\n {\r\n this.control.linearRampToValueAtTime(this.aLevel, t);\r\n valToSet = this.control.getValueAtTime(t);\r\n this.control.cancelScheduledValues(t);\r\n this.control.linearRampToValueAtTime(valToSet, t);\r\n\r\n }\r\n\r\n // decay to decay level (if using ADSR, then decay level == sustain level)\r\n t += this.dTime;\r\n if (this.isExponential === true)\r\n {\r\n this.control.exponentialRampToValueAtTime(this.checkExpInput(this.dLevel), t);\r\n valToSet = this.checkExpInput(this.control.getValueAtTime(t));\r\n this.control.cancelScheduledValues(t);\r\n this.control.exponentialRampToValueAtTime(valToSet, t);\r\n }\r\n else\r\n {\r\n this.control.linearRampToValueAtTime(this.dLevel, t);\r\n valToSet = this.control.getValueAtTime(t);\r\n this.control.cancelScheduledValues(t);\r\n this.control.linearRampToValueAtTime(valToSet, t);\r\n }\r\n };\r\n\r\n /**\r\n * Trigger the Release of the Envelope. This is similar to releasing\r\n * the key on a piano and letting the sound fade according to the\r\n * release level and release time.\r\n *\r\n * @method triggerRelease\r\n * @for p5.Envelope\r\n * @param {Object} unit p5.sound Object or Web Audio Param\r\n * @param {Number} secondsFromNow time to trigger the release\r\n * @example\r\n *
\r\n *\r\n * var attackLevel = 1.0;\r\n * var releaseLevel = 0;\r\n *\r\n * var attackTime = 0.001;\r\n * var decayTime = 0.3;\r\n * var susPercent = 0.4;\r\n * var releaseTime = 0.5;\r\n *\r\n * var env, triOsc;\r\n *\r\n * function setup() {\r\n * var cnv = createCanvas(100, 100);\r\n * background(200);\r\n * textAlign(CENTER);\r\n * text('click to play', width/2, height/2);\r\n *\r\n * env = new p5.Envelope();\r\n * env.setADSR(attackTime, decayTime, susPercent, releaseTime);\r\n * env.setRange(attackLevel, releaseLevel);\r\n *\r\n * triOsc = new p5.Oscillator('triangle');\r\n * triOsc.amp(env);\r\n * triOsc.start();\r\n * triOsc.freq(220);\r\n *\r\n * cnv.mousePressed(envAttack);\r\n * }\r\n *\r\n * function envAttack() {\r\n * console.log('trigger attack');\r\n * env.triggerAttack();\r\n *\r\n * background(0,255,0);\r\n * text('attack!', width/2, height/2);\r\n * }\r\n *\r\n * function mouseReleased() {\r\n * env.triggerRelease();\r\n *\r\n * background(200);\r\n * text('click to play', width/2, height/2);\r\n * }\r\n *
\r\n */\r\n p5.Envelope.prototype.triggerRelease = function(unit, secondsFromNow) {\r\n\r\n // only trigger a release if an attack was triggered\r\n if (!this.wasTriggered) {\r\n // this currently causes a bit of trouble:\r\n // if a later release has been scheduled (via the play function)\r\n // a new earlier release won't interrupt it, because\r\n // this.wasTriggered has already been set to false.\r\n // If we want new earlier releases to override, then we need to\r\n // keep track of the last release time, and if the new release time is\r\n // earlier, then use it.\r\n return;\r\n }\r\n\r\n var now = p5sound.audiocontext.currentTime;\r\n var tFromNow = secondsFromNow || 0;\r\n var t = now + tFromNow;\r\n\r\n if (unit) {\r\n if (this.connection !== unit) {\r\n this.connect(unit);\r\n }\r\n }\r\n\r\n // get and set value (with linear or exponential ramp) to anchor automation\r\n var valToSet = this.control.getValueAtTime(t);\r\n if (this.isExponential === true)\r\n {\r\n this.control.exponentialRampToValueAtTime(this.checkExpInput(valToSet), t);\r\n }\r\n else\r\n {\r\n this.control.linearRampToValueAtTime(valToSet, t);\r\n }\r\n\r\n // release\r\n t += this.rTime;\r\n\r\n if (this.isExponential === true)\r\n {\r\n this.control.exponentialRampToValueAtTime(this.checkExpInput(this.rLevel), t);\r\n valToSet = this.checkExpInput(this.control.getValueAtTime(t));\r\n this.control.cancelScheduledValues(t);\r\n this.control.exponentialRampToValueAtTime(valToSet, t);\r\n }\r\n else\r\n {\r\n this.control.linearRampToValueAtTime(this.rLevel, t);\r\n valToSet = this.control.getValueAtTime(t);\r\n this.control.cancelScheduledValues(t);\r\n this.control.linearRampToValueAtTime(valToSet, t);\r\n }\r\n\r\n this.wasTriggered = false;\r\n };\r\n\r\n /**\r\n * Exponentially ramp to a value using the first two\r\n * values from setADSR(attackTime, decayTime)\r\n * as \r\n * time constants for simple exponential ramps.\r\n * If the value is higher than current value, it uses attackTime,\r\n * while a decrease uses decayTime.\r\n *\r\n * @method ramp\r\n * @for p5.Envelope\r\n * @param {Object} unit p5.sound Object or Web Audio Param\r\n * @param {Number} secondsFromNow When to trigger the ramp\r\n * @param {Number} v Target value\r\n * @param {Number} [v2] Second target value (optional)\r\n * @example\r\n *
\r\n * var env, osc, amp, cnv;\r\n *\r\n * var attackTime = 0.001;\r\n * var decayTime = 0.2;\r\n * var attackLevel = 1;\r\n * var decayLevel = 0;\r\n *\r\n * function setup() {\r\n * cnv = createCanvas(100, 100);\r\n * fill(0,255,0);\r\n * noStroke();\r\n *\r\n * env = new p5.Envelope();\r\n * env.setADSR(attackTime, decayTime);\r\n *\r\n * osc = new p5.Oscillator();\r\n * osc.amp(env);\r\n * osc.start();\r\n *\r\n * amp = new p5.Amplitude();\r\n *\r\n * cnv.mousePressed(triggerRamp);\r\n * }\r\n *\r\n * function triggerRamp() {\r\n * env.ramp(osc, 0, attackLevel, decayLevel);\r\n * }\r\n *\r\n * function draw() {\r\n * background(20,20,20);\r\n * text('click me', 10, 20);\r\n * var h = map(amp.getLevel(), 0, 0.4, 0, height);;\r\n *\r\n * rect(0, height, width, -h);\r\n * }\r\n *
\r\n */\r\n p5.Envelope.prototype.ramp = function(unit, secondsFromNow, v1, v2) {\r\n\r\n var now = p5sound.audiocontext.currentTime;\r\n var tFromNow = secondsFromNow || 0;\r\n var t = now + tFromNow;\r\n var destination1 = this.checkExpInput(v1);\r\n var destination2 = typeof v2 !== 'undefined' ? this.checkExpInput(v2) : undefined;\r\n\r\n // connect env to unit if not already connected\r\n if (unit) {\r\n if (this.connection !== unit) {\r\n this.connect(unit);\r\n }\r\n }\r\n\r\n //get current value\r\n var currentVal = this.checkExpInput(this.control.getValueAtTime(t));\r\n // this.control.cancelScheduledValues(t);\r\n\r\n //if it's going up\r\n if (destination1 > currentVal) {\r\n this.control.setTargetAtTime(destination1, t, this._rampAttackTC);\r\n t += this._rampAttackTime;\r\n }\r\n\r\n //if it's going down\r\n else if (destination1 < currentVal) {\r\n this.control.setTargetAtTime(destination1, t, this._rampDecayTC);\r\n t += this._rampDecayTime;\r\n }\r\n\r\n // Now the second part of envelope begins\r\n if (destination2 === undefined) return;\r\n\r\n //if it's going up\r\n if (destination2 > destination1) {\r\n this.control.setTargetAtTime(destination2, t, this._rampAttackTC);\r\n }\r\n\r\n //if it's going down\r\n else if (destination2 < destination1) {\r\n this.control.setTargetAtTime(destination2, t, this._rampDecayTC);\r\n }\r\n };\r\n\r\n\r\n p5.Envelope.prototype.connect = function(unit) {\r\n this.connection = unit;\r\n\r\n // assume we're talking about output gain\r\n // unless given a different audio param\r\n if (unit instanceof p5.Oscillator ||\r\n unit instanceof p5.SoundFile ||\r\n unit instanceof p5.AudioIn ||\r\n unit instanceof p5.Reverb ||\r\n unit instanceof p5.Noise ||\r\n unit instanceof p5.Filter ||\r\n unit instanceof p5.Delay\r\n ) {\r\n unit = unit.output.gain;\r\n }\r\n if (unit instanceof AudioParam) {\r\n //set the initial value\r\n unit.setValueAtTime(0, p5sound.audiocontext.currentTime);\r\n }\r\n if (unit instanceof p5.Signal) {\r\n unit.setValue(0);\r\n }\r\n this.output.connect(unit);\r\n };\r\n\r\n p5.Envelope.prototype.disconnect = function() {\r\n if (this.output) {\r\n this.output.disconnect();\r\n }\r\n };\r\n\r\n\r\n // Signal Math\r\n\r\n /**\r\n * Add a value to the p5.Oscillator's output amplitude,\r\n * and return the oscillator. Calling this method\r\n * again will override the initial add() with new values.\r\n *\r\n * @method add\r\n * @for p5.Envelope\r\n * @param {Number} number Constant number to add\r\n * @return {p5.Envelope} Envelope Returns this envelope\r\n * with scaled output\r\n */\r\n p5.Envelope.prototype.add = function(num) {\r\n var add = new Add(num);\r\n var thisChain = this.mathOps.length;\r\n var nextChain = this.output;\r\n return p5.prototype._mathChain(this, add, thisChain, nextChain, Add);\r\n };\r\n\r\n /**\r\n * Multiply the p5.Envelope's output amplitude\r\n * by a fixed value. Calling this method\r\n * again will override the initial mult() with new values.\r\n *\r\n * @method mult\r\n * @for p5.Envelope\r\n * @param {Number} number Constant number to multiply\r\n * @return {p5.Envelope} Envelope Returns this envelope\r\n * with scaled output\r\n */\r\n p5.Envelope.prototype.mult = function(num) {\r\n var mult = new Mult(num);\r\n var thisChain = this.mathOps.length;\r\n var nextChain = this.output;\r\n return p5.prototype._mathChain(this, mult, thisChain, nextChain, Mult);\r\n };\r\n\r\n /**\r\n * Scale this envelope's amplitude values to a given\r\n * range, and return the envelope. Calling this method\r\n * again will override the initial scale() with new values.\r\n *\r\n * @method scale\r\n * @for p5.Envelope\r\n * @param {Number} inMin input range minumum\r\n * @param {Number} inMax input range maximum\r\n * @param {Number} outMin input range minumum\r\n * @param {Number} outMax input range maximum\r\n * @return {p5.Envelope} Envelope Returns this envelope\r\n * with scaled output\r\n */\r\n p5.Envelope.prototype.scale = function(inMin, inMax, outMin, outMax) {\r\n var scale = new Scale(inMin, inMax, outMin, outMax);\r\n var thisChain = this.mathOps.length;\r\n var nextChain = this.output;\r\n return p5.prototype._mathChain(this, scale, thisChain, nextChain, Scale);\r\n };\r\n\r\n\r\n // get rid of the oscillator\r\n p5.Envelope.prototype.dispose = function() {\r\n // remove reference from soundArray\r\n var index = p5sound.soundArray.indexOf(this);\r\n p5sound.soundArray.splice(index, 1);\r\n\r\n this.disconnect();\r\n if (this.control) {\r\n this.control.dispose();\r\n this.control = null;\r\n }\r\n for (var i = 1; i < this.mathOps.length; i++) {\r\n this.mathOps[i].dispose();\r\n }\r\n };\r\n\r\n // Different name for backwards compatibility, replicates p5.Envelope class\r\n p5.Env = function(t1, l1, t2, l2, t3, l3) {\r\n console.warn('WARNING: p5.Env is now deprecated and may be removed in future versions. ' +\r\n 'Please use the new p5.Envelope instead.');\r\n p5.Envelope.call(this, t1, l1, t2, l2, t3, l3);\r\n };\r\n p5.Env.prototype = Object.create(p5.Envelope.prototype);\r\n\r\n});\r\n","'use strict';\r\n\r\ndefine(function (require) {\r\n\r\n var p5sound = require('master');\r\n require('oscillator');\r\n\r\n /**\r\n * Creates a Pulse object, an oscillator that implements\r\n * Pulse Width Modulation.\r\n * The pulse is created with two oscillators.\r\n * Accepts a parameter for frequency, and to set the\r\n * width between the pulses. See \r\n * p5.Oscillator for a full list of methods.\r\n *\r\n * @class p5.Pulse\r\n * @extends p5.Oscillator\r\n * @constructor\r\n * @param {Number} [freq] Frequency in oscillations per second (Hz)\r\n * @param {Number} [w] Width between the pulses (0 to 1.0,\r\n * defaults to 0)\r\n * @example\r\n *
Note: This uses the getUserMedia/\r\n * Stream API, which is not supported by certain browsers. Access in Chrome browser\r\n * is limited to localhost and https, but access over http may be limited.
\r\n *\r\n * @class p5.AudioIn\r\n * @constructor\r\n * @param {Function} [errorCallback] A function to call if there is an error\r\n * accessing the AudioIn. For example,\r\n * Safari and iOS devices do not\r\n * currently allow microphone access.\r\n * @example\r\n *
\r\n * var mic;\r\n * function setup(){\r\n * mic = new p5.AudioIn()\r\n * mic.start();\r\n * }\r\n * function draw(){\r\n * background(0);\r\n * micLevel = mic.getLevel();\r\n * ellipse(width/2, constrain(height-micLevel*height*5, 0, height), 10, 10);\r\n * }\r\n *
\r\n */\r\n p5.AudioIn = function(errorCallback) {\r\n // set up audio input\r\n /**\r\n * @property {GainNode} input\r\n */\r\n this.input = p5sound.audiocontext.createGain();\r\n /**\r\n * @property {GainNode} output\r\n */\r\n this.output = p5sound.audiocontext.createGain();\r\n\r\n /**\r\n * @property {MediaStream|null} stream\r\n */\r\n this.stream = null;\r\n /**\r\n * @property {MediaStreamAudioSourceNode|null} mediaStream\r\n */\r\n this.mediaStream = null;\r\n /**\r\n * @property {Number|null} currentSource\r\n */\r\n this.currentSource = null;\r\n\r\n /**\r\n * Client must allow browser to access their microphone / audioin source.\r\n * Default: false. Will become true when the client enables acces.\r\n *\r\n * @property {Boolean} enabled\r\n */\r\n this.enabled = false;\r\n\r\n /**\r\n * Input amplitude, connect to it by default but not to master out\r\n *\r\n * @property {p5.Amplitude} amplitude\r\n */\r\n this.amplitude = new p5.Amplitude();\r\n this.output.connect(this.amplitude.input);\r\n\r\n if (!window.MediaStreamTrack || !window.navigator.mediaDevices || !window.navigator.mediaDevices.getUserMedia) {\r\n errorCallback ? errorCallback() : window.alert('This browser does not support MediaStreamTrack and mediaDevices');\r\n }\r\n\r\n // add to soundArray so we can dispose on close\r\n p5sound.soundArray.push(this);\r\n };\r\n\r\n /**\r\n * Start processing audio input. This enables the use of other\r\n * AudioIn methods like getLevel(). Note that by default, AudioIn\r\n * is not connected to p5.sound's output. So you won't hear\r\n * anything unless you use the connect() method. \r\n *\r\n * Certain browsers limit access to the user's microphone. For example,\r\n * Chrome only allows access from localhost and over https. For this reason,\r\n * you may want to include an errorCallback—a function that is called in case\r\n * the browser won't provide mic access.\r\n *\r\n * @method start\r\n * @for p5.AudioIn\r\n * @param {Function} [successCallback] Name of a function to call on\r\n * success.\r\n * @param {Function} [errorCallback] Name of a function to call if\r\n * there was an error. For example,\r\n * some browsers do not support\r\n * getUserMedia.\r\n */\r\n p5.AudioIn.prototype.start = function(successCallback, errorCallback) {\r\n var self = this;\r\n\r\n if (this.stream) {\r\n this.stop();\r\n }\r\n\r\n // set the audio source\r\n var audioSource = p5sound.inputSources[self.currentSource];\r\n var constraints = {\r\n audio: {\r\n sampleRate: p5sound.audiocontext.sampleRate,\r\n echoCancellation: false\r\n }\r\n };\r\n\r\n // if developers determine which source to use\r\n if (p5sound.inputSources[this.currentSource]) {\r\n constraints.audio.deviceId = audioSource.deviceId;\r\n }\r\n\r\n window.navigator.mediaDevices.getUserMedia( constraints )\r\n .then( function(stream) {\r\n self.stream = stream;\r\n self.enabled = true;\r\n // Wrap a MediaStreamSourceNode around the live input\r\n self.mediaStream = p5sound.audiocontext.createMediaStreamSource(stream);\r\n self.mediaStream.connect(self.output);\r\n // only send to the Amplitude reader, so we can see it but not hear it.\r\n self.amplitude.setInput(self.output);\r\n if (successCallback) successCallback();\r\n })\r\n .catch( function(err) {\r\n if (errorCallback) errorCallback(err);\r\n else console.error(err);\r\n });\r\n };\r\n\r\n /**\r\n * Turn the AudioIn off. If the AudioIn is stopped, it cannot getLevel().\r\n * If re-starting, the user may be prompted for permission access.\r\n *\r\n * @method stop\r\n * @for p5.AudioIn\r\n */\r\n p5.AudioIn.prototype.stop = function() {\r\n if (this.stream) {\r\n this.stream.getTracks().forEach(function(track) {\r\n track.stop();\r\n });\r\n\r\n this.mediaStream.disconnect();\r\n\r\n delete this.mediaStream;\r\n delete this.stream;\r\n }\r\n };\r\n\r\n /**\r\n * Connect to an audio unit. If no parameter is provided, will\r\n * connect to the master output (i.e. your speakers). \r\n *\r\n * @method connect\r\n * @for p5.AudioIn\r\n * @param {Object} [unit] An object that accepts audio input,\r\n * such as an FFT\r\n */\r\n p5.AudioIn.prototype.connect = function(unit) {\r\n if (unit) {\r\n if (unit.hasOwnProperty('input')) {\r\n this.output.connect(unit.input);\r\n }\r\n else if (unit.hasOwnProperty('analyser')) {\r\n this.output.connect(unit.analyser);\r\n }\r\n else {\r\n this.output.connect(unit);\r\n }\r\n }\r\n else {\r\n this.output.connect(p5sound.input);\r\n }\r\n };\r\n\r\n /**\r\n * Disconnect the AudioIn from all audio units. For example, if\r\n * connect() had been called, disconnect() will stop sending\r\n * signal to your speakers. \r\n *\r\n * @method disconnect\r\n * @for p5.AudioIn\r\n */\r\n p5.AudioIn.prototype.disconnect = function() {\r\n if (this.output) {\r\n this.output.disconnect();\r\n // stay connected to amplitude even if not outputting to p5\r\n this.output.connect(this.amplitude.input);\r\n }\r\n };\r\n\r\n /**\r\n * Read the Amplitude (volume level) of an AudioIn. The AudioIn\r\n * class contains its own instance of the Amplitude class to help\r\n * make it easy to get a microphone's volume level. Accepts an\r\n * optional smoothing value (0.0 < 1.0). NOTE: AudioIn must\r\n * .start() before using .getLevel(). \r\n *\r\n * @method getLevel\r\n * @for p5.AudioIn\r\n * @param {Number} [smoothing] Smoothing is 0.0 by default.\r\n * Smooths values based on previous values.\r\n * @return {Number} Volume level (between 0.0 and 1.0)\r\n */\r\n p5.AudioIn.prototype.getLevel = function(smoothing) {\r\n if (smoothing) {\r\n this.amplitude.smoothing = smoothing;\r\n }\r\n return this.amplitude.getLevel();\r\n };\r\n\r\n /**\r\n * Set amplitude (volume) of a mic input between 0 and 1.0. \r\n *\r\n * @method amp\r\n * @for p5.AudioIn\r\n * @param {Number} vol between 0 and 1.0\r\n * @param {Number} [time] ramp time (optional)\r\n */\r\n p5.AudioIn.prototype.amp = function(vol, t) {\r\n if (t) {\r\n var rampTime = t || 0;\r\n var currentVol = this.output.gain.value;\r\n this.output.gain.cancelScheduledValues(p5sound.audiocontext.currentTime);\r\n this.output.gain.setValueAtTime(currentVol, p5sound.audiocontext.currentTime);\r\n this.output.gain.linearRampToValueAtTime(vol, rampTime + p5sound.audiocontext.currentTime);\r\n } else {\r\n this.output.gain.cancelScheduledValues(p5sound.audiocontext.currentTime);\r\n this.output.gain.setValueAtTime(vol, p5sound.audiocontext.currentTime);\r\n }\r\n };\r\n\r\n /**\r\n * Returns a list of available input sources. This is a wrapper\r\n * for and it returns a Promise.\r\n *\r\n * @method getSources\r\n * @for p5.AudioIn\r\n * @param {Function} [successCallback] This callback function handles the sources when they\r\n * have been enumerated. The callback function\r\n * receives the deviceList array as its only argument\r\n * @param {Function} [errorCallback] This optional callback receives the error\r\n * message as its argument.\r\n * @returns {Promise} Returns a Promise that can be used in place of the callbacks, similar\r\n * to the enumerateDevices() method\r\n * @example\r\n *
\r\n */\r\n p5.AudioIn.prototype.getSources = function (onSuccess, onError) {\r\n return new Promise( function(resolve, reject) {\r\n window.navigator.mediaDevices.enumerateDevices()\r\n .then( function(devices) {\r\n p5sound.inputSources = devices.filter(function(device) {\r\n return device.kind === 'audioinput';\r\n });\r\n resolve(p5sound.inputSources);\r\n if (onSuccess) {\r\n onSuccess(p5sound.inputSources);\r\n }\r\n })\r\n .catch( function(error) {\r\n reject(error);\r\n if (onError) {\r\n onError(error);\r\n } else {\r\n console.error('This browser does not support MediaStreamTrack.getSources()');\r\n }\r\n });\r\n });\r\n };\r\n\r\n /**\r\n * Set the input source. Accepts a number representing a\r\n * position in the array returned by getSources().\r\n * This is only available in browsers that support\r\n * navigator.mediaDevices.enumerateDevices(). \r\n *\r\n * @method setSource\r\n * @for p5.AudioIn\r\n * @param {number} num position of input source in the array\r\n */\r\n p5.AudioIn.prototype.setSource = function(num) {\r\n if (p5sound.inputSources.length > 0 && num < p5sound.inputSources.length) {\r\n // set the current source\r\n this.currentSource = num;\r\n console.log('set source to ', p5sound.inputSources[this.currentSource]);\r\n } else {\r\n console.log('unable to set input source');\r\n }\r\n\r\n // restart stream if currently active\r\n if (this.stream && this.stream.active) {\r\n this.start();\r\n }\r\n };\r\n\r\n // private method\r\n p5.AudioIn.prototype.dispose = function() {\r\n // remove reference from soundArray\r\n var index = p5sound.soundArray.indexOf(this);\r\n p5sound.soundArray.splice(index, 1);\r\n\r\n this.stop();\r\n\r\n if (this.output) {\r\n this.output.disconnect();\r\n }\r\n if (this.amplitude) {\r\n this.amplitude.disconnect();\r\n }\r\n delete this.amplitude;\r\n delete this.output;\r\n };\r\n\r\n});\r\n","define([\"Tone/core/Tone\", \"Tone/signal/Signal\", \"Tone/signal/Expr\", \n\t\"Tone/signal/EqualPowerGain\", \"Tone/core/Gain\"], function(Tone){\n\n\t\"use strict\";\n\n\t/**\n\t * @class Tone.Crossfade provides equal power fading between two inputs. \n\t * More on crossfading technique [here](https://en.wikipedia.org/wiki/Fade_(audio_engineering)#Crossfading).\n\t *\n\t * @constructor\n\t * @extends {Tone}\n\t * @param {NormalRange} [initialFade=0.5]\n\t * @example\n\t * var crossFade = new Tone.CrossFade(0.5);\n\t * //connect effect A to crossfade from\n\t * //effect output 0 to crossfade input 0\n\t * effectA.connect(crossFade, 0, 0);\n\t * //connect effect B to crossfade from\n\t * //effect output 0 to crossfade input 1\n\t * effectB.connect(crossFade, 0, 1);\n\t * crossFade.fade.value = 0;\n\t * // ^ only effectA is output\n\t * crossFade.fade.value = 1;\n\t * // ^ only effectB is output\n\t * crossFade.fade.value = 0.5;\n\t * // ^ the two signals are mixed equally. \n\t */\t\t\n\tTone.CrossFade = function(initialFade){\n\n\t\tthis.createInsOuts(2, 1);\n\n\t\t/**\n\t\t * Alias for input[0]. \n\t\t * @type {Tone.Gain}\n\t\t */\n\t\tthis.a = this.input[0] = new Tone.Gain();\n\n\t\t/**\n\t\t * Alias for input[1]. \n\t\t * @type {Tone.Gain}\n\t\t */\n\t\tthis.b = this.input[1] = new Tone.Gain();\n\n\t\t/**\n\t\t * \tThe mix between the two inputs. A fade value of 0\n\t\t * \twill output 100% input[0] and \n\t\t * \ta value of 1 will output 100% input[1]. \n\t\t * @type {NormalRange}\n\t\t * @signal\n\t\t */\n\t\tthis.fade = new Tone.Signal(this.defaultArg(initialFade, 0.5), Tone.Type.NormalRange);\n\n\t\t/**\n\t\t * equal power gain cross fade\n\t\t * @private\n\t\t * @type {Tone.EqualPowerGain}\n\t\t */\n\t\tthis._equalPowerA = new Tone.EqualPowerGain();\n\n\t\t/**\n\t\t * equal power gain cross fade\n\t\t * @private\n\t\t * @type {Tone.EqualPowerGain}\n\t\t */\n\t\tthis._equalPowerB = new Tone.EqualPowerGain();\n\t\t\n\t\t/**\n\t\t * invert the incoming signal\n\t\t * @private\n\t\t * @type {Tone}\n\t\t */\n\t\tthis._invert = new Tone.Expr(\"1 - $0\");\n\n\t\t//connections\n\t\tthis.a.connect(this.output);\n\t\tthis.b.connect(this.output);\n\t\tthis.fade.chain(this._equalPowerB, this.b.gain);\n\t\tthis.fade.chain(this._invert, this._equalPowerA, this.a.gain);\n\t\tthis._readOnly(\"fade\");\n\t};\n\n\tTone.extend(Tone.CrossFade);\n\n\t/**\n\t * clean up\n\t * @returns {Tone.CrossFade} this\n\t */\n\tTone.CrossFade.prototype.dispose = function(){\n\t\tTone.prototype.dispose.call(this);\n\t\tthis._writable(\"fade\");\n\t\tthis._equalPowerA.dispose();\n\t\tthis._equalPowerA = null;\n\t\tthis._equalPowerB.dispose();\n\t\tthis._equalPowerB = null;\n\t\tthis.fade.dispose();\n\t\tthis.fade = null;\n\t\tthis._invert.dispose();\n\t\tthis._invert = null;\n\t\tthis.a.dispose();\n\t\tthis.a = null;\n\t\tthis.b.dispose();\n\t\tthis.b = null;\n\t\treturn this;\n\t};\n\n\treturn Tone.CrossFade;\n});\n","define([\"Tone/core/Tone\", \"Tone/signal/Add\", \"Tone/signal/Subtract\", \"Tone/signal/Multiply\", \n\t\"Tone/signal/GreaterThan\", \"Tone/signal/GreaterThanZero\", \"Tone/signal/Abs\", \"Tone/signal/Negate\", \n\t\"Tone/signal/Modulo\", \"Tone/signal/Pow\", \"Tone/signal/AudioToGain\"], \n\tfunction(Tone){\n\n\t\"use strict\";\n\n\t/**\n\t * @class Evaluate an expression at audio rate.
\n\t * Parsing code modified from https://code.google.com/p/tapdigit/\n\t * Copyright 2011 2012 Ariya Hidayat, New BSD License\n\t *\n\t * @extends {Tone.SignalBase}\n\t * @constructor\n\t * @param {string} expr the expression to generate\n\t * @example\n\t * //adds the signals from input[0] and input[1].\n\t * var expr = new Tone.Expr(\"$0 + $1\");\n\t */\n\tTone.Expr = function(){\n\n\t\tvar expr = this._replacements(Array.prototype.slice.call(arguments));\n\t\tvar inputCount = this._parseInputs(expr);\n\n\t\t/**\n\t\t * hold onto all of the nodes for disposal\n\t\t * @type {Array}\n\t\t * @private\n\t\t */\n\t\tthis._nodes = [];\n\n\t\t/**\n\t\t * The inputs. The length is determined by the expression. \n\t\t * @type {Array}\n\t\t */\n\t\tthis.input = new Array(inputCount);\n\n\t\t//create a gain for each input\n\t\tfor (var i = 0; i < inputCount; i++){\n\t\t\tthis.input[i] = this.context.createGain();\n\t\t}\n\n\t\t//parse the syntax tree\n\t\tvar tree = this._parseTree(expr);\n\t\t//evaluate the results\n\t\tvar result;\n\t\ttry {\n\t\t\tresult = this._eval(tree);\n\t\t} catch (e){\n\t\t\tthis._disposeNodes();\n\t\t\tthrow new Error(\"Tone.Expr: Could evaluate expression: \"+expr);\n\t\t}\n\n\t\t/**\n\t\t * The output node is the result of the expression\n\t\t * @type {Tone}\n\t\t */\n\t\tthis.output = result;\n\t};\n\n\tTone.extend(Tone.Expr, Tone.SignalBase);\n\n\t//some helpers to cut down the amount of code\n\tfunction applyBinary(Constructor, args, self){\n\t\tvar op = new Constructor();\n\t\tself._eval(args[0]).connect(op, 0, 0);\n\t\tself._eval(args[1]).connect(op, 0, 1);\n\t\treturn op;\n\t}\n\tfunction applyUnary(Constructor, args, self){\n\t\tvar op = new Constructor();\n\t\tself._eval(args[0]).connect(op, 0, 0);\n\t\treturn op;\n\t}\n\tfunction getNumber(arg){\n\t\treturn arg ? parseFloat(arg) : undefined;\n\t}\n\tfunction literalNumber(arg){\n\t\treturn arg && arg.args ? parseFloat(arg.args) : undefined;\n\t}\n\n\t/*\n\t * the Expressions that Tone.Expr can parse.\n\t *\n\t * each expression belongs to a group and contains a regexp \n\t * for selecting the operator as well as that operators method\n\t * \n\t * @type {Object}\n\t * @private\n\t */\n\tTone.Expr._Expressions = {\n\t\t//values\n\t\t\"value\" : {\n\t\t\t\"signal\" : {\n\t\t\t\tregexp : /^\\d+\\.\\d+|^\\d+/,\n\t\t\t\tmethod : function(arg){\n\t\t\t\t\tvar sig = new Tone.Signal(getNumber(arg));\n\t\t\t\t\treturn sig;\n\t\t\t\t}\n\t\t\t},\n\t\t\t\"input\" : {\n\t\t\t\tregexp : /^\\$\\d/,\n\t\t\t\tmethod : function(arg, self){\n\t\t\t\t\treturn self.input[getNumber(arg.substr(1))];\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\t\t//syntactic glue\n\t\t\"glue\" : {\n\t\t\t\"(\" : {\n\t\t\t\tregexp : /^\\(/,\n\t\t\t},\n\t\t\t\")\" : {\n\t\t\t\tregexp : /^\\)/,\n\t\t\t},\n\t\t\t\",\" : {\n\t\t\t\tregexp : /^,/,\n\t\t\t}\n\t\t},\n\t\t//functions\n\t\t\"func\" : {\n\t\t\t\"abs\" : {\n\t\t\t\tregexp : /^abs/,\n\t\t\t\tmethod : applyUnary.bind(this, Tone.Abs)\n\t\t\t},\n\t\t\t\"mod\" : {\n\t\t\t\tregexp : /^mod/,\n\t\t\t\tmethod : function(args, self){\n\t\t\t\t\tvar modulus = literalNumber(args[1]);\n\t\t\t\t\tvar op = new Tone.Modulo(modulus);\n\t\t\t\t\tself._eval(args[0]).connect(op);\n\t\t\t\t\treturn op;\n\t\t\t\t}\n\t\t\t},\n\t\t\t\"pow\" : {\n\t\t\t\tregexp : /^pow/,\n\t\t\t\tmethod : function(args, self){\n\t\t\t\t\tvar exp = literalNumber(args[1]);\n\t\t\t\t\tvar op = new Tone.Pow(exp);\n\t\t\t\t\tself._eval(args[0]).connect(op);\n\t\t\t\t\treturn op;\n\t\t\t\t}\n\t\t\t},\n\t\t\t\"a2g\" : {\n\t\t\t\tregexp : /^a2g/,\n\t\t\t\tmethod : function(args, self){\n\t\t\t\t\tvar op = new Tone.AudioToGain();\n\t\t\t\t\tself._eval(args[0]).connect(op);\n\t\t\t\t\treturn op;\n\t\t\t\t}\n\t\t\t},\n\t\t},\n\t\t//binary expressions\n\t\t\"binary\" : {\n\t\t\t\"+\" : {\n\t\t\t\tregexp : /^\\+/,\n\t\t\t\tprecedence : 1,\n\t\t\t\tmethod : applyBinary.bind(this, Tone.Add)\n\t\t\t},\n\t\t\t\"-\" : {\n\t\t\t\tregexp : /^\\-/,\n\t\t\t\tprecedence : 1,\n\t\t\t\tmethod : function(args, self){\n\t\t\t\t\t//both unary and binary op\n\t\t\t\t\tif (args.length === 1){\n\t\t\t\t\t\treturn applyUnary(Tone.Negate, args, self);\n\t\t\t\t\t} else {\n\t\t\t\t\t\treturn applyBinary(Tone.Subtract, args, self);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t},\n\t\t\t\"*\" : {\n\t\t\t\tregexp : /^\\*/,\n\t\t\t\tprecedence : 0,\n\t\t\t\tmethod : applyBinary.bind(this, Tone.Multiply)\n\t\t\t}\n\t\t},\n\t\t//unary expressions\n\t\t\"unary\" : {\n\t\t\t\"-\" : {\n\t\t\t\tregexp : /^\\-/,\n\t\t\t\tmethod : applyUnary.bind(this, Tone.Negate)\n\t\t\t},\n\t\t\t\"!\" : {\n\t\t\t\tregexp : /^\\!/,\n\t\t\t\tmethod : applyUnary.bind(this, Tone.NOT)\n\t\t\t},\n\t\t},\n\t};\n\t\t\n\t/**\n\t * @param {string} expr the expression string\n\t * @return {number} the input count\n\t * @private\n\t */\n\tTone.Expr.prototype._parseInputs = function(expr){\n\t\tvar inputArray = expr.match(/\\$\\d/g);\n\t\tvar inputMax = 0;\n\t\tif (inputArray !== null){\n\t\t\tfor (var i = 0; i < inputArray.length; i++){\n\t\t\t\tvar inputNum = parseInt(inputArray[i].substr(1)) + 1;\n\t\t\t\tinputMax = Math.max(inputMax, inputNum);\n\t\t\t}\n\t\t}\n\t\treturn inputMax;\n\t};\n\n\t/**\n\t * @param {Array} args \tan array of arguments\n\t * @return {string} the results of the replacements being replaced\n\t * @private\n\t */\n\tTone.Expr.prototype._replacements = function(args){\n\t\tvar expr = args.shift();\n\t\tfor (var i = 0; i < args.length; i++){\n\t\t\texpr = expr.replace(/\\%/i, args[i]);\n\t\t}\n\t\treturn expr;\n\t};\n\n\t/**\n\t * tokenize the expression based on the Expressions object\n\t * @param {string} expr \n\t * @return {Object} returns two methods on the tokenized list, next and peek\n\t * @private\n\t */\n\tTone.Expr.prototype._tokenize = function(expr){\n\t\tvar position = -1;\n\t\tvar tokens = [];\n\n\t\twhile(expr.length > 0){\n\t\t\texpr = expr.trim();\n\t\t\tvar token = getNextToken(expr);\n\t\t\ttokens.push(token);\n\t\t\texpr = expr.substr(token.value.length);\n\t\t}\n\n\t\tfunction getNextToken(expr){\n\t\t\tfor (var type in Tone.Expr._Expressions){\n\t\t\t\tvar group = Tone.Expr._Expressions[type];\n\t\t\t\tfor (var opName in group){\n\t\t\t\t\tvar op = group[opName];\n\t\t\t\t\tvar reg = op.regexp;\n\t\t\t\t\tvar match = expr.match(reg);\n\t\t\t\t\tif (match !== null){\n\t\t\t\t\t\treturn {\n\t\t\t\t\t\t\ttype : type,\n\t\t\t\t\t\t\tvalue : match[0],\n\t\t\t\t\t\t\tmethod : op.method\n\t\t\t\t\t\t};\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\tthrow new SyntaxError(\"Tone.Expr: Unexpected token \"+expr);\n\t\t}\n\n\t\treturn {\n\t\t\tnext : function(){\n\t\t\t\treturn tokens[++position];\n\t\t\t},\n\t\t\tpeek : function(){\n\t\t\t\treturn tokens[position + 1];\n\t\t\t}\n\t\t};\n\t};\n\n\t/**\n\t * recursively parse the string expression into a syntax tree\n\t * \n\t * @param {string} expr \n\t * @return {Object}\n\t * @private\n\t */\n\tTone.Expr.prototype._parseTree = function(expr){\n\t\tvar lexer = this._tokenize(expr);\n\t\tvar isUndef = this.isUndef.bind(this);\n\n\t\tfunction matchSyntax(token, syn) {\n\t\t\treturn !isUndef(token) && \n\t\t\t\ttoken.type === \"glue\" &&\n\t\t\t\ttoken.value === syn;\n\t\t}\n\n\t\tfunction matchGroup(token, groupName, prec) {\n\t\t\tvar ret = false;\n\t\t\tvar group = Tone.Expr._Expressions[groupName];\n\t\t\tif (!isUndef(token)){\n\t\t\t\tfor (var opName in group){\n\t\t\t\t\tvar op = group[opName];\n\t\t\t\t\tif (op.regexp.test(token.value)){\n\t\t\t\t\t\tif (!isUndef(prec)){\n\t\t\t\t\t\t\tif(op.precedence === prec){\t\n\t\t\t\t\t\t\t\treturn true;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\treturn true;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn ret;\n\t\t}\n\n\t\tfunction parseExpression(precedence) {\n\t\t\tif (isUndef(precedence)){\n\t\t\t\tprecedence = 5;\n\t\t\t}\n\t\t\tvar expr;\n\t\t\tif (precedence < 0){\n\t\t\t\texpr = parseUnary();\n\t\t\t} else {\n\t\t\t\texpr = parseExpression(precedence-1);\n\t\t\t}\n\t\t\tvar token = lexer.peek();\n\t\t\twhile (matchGroup(token, \"binary\", precedence)) {\n\t\t\t\ttoken = lexer.next();\n\t\t\t\texpr = {\n\t\t\t\t\toperator: token.value,\n\t\t\t\t\tmethod : token.method,\n\t\t\t\t\targs : [\n\t\t\t\t\t\texpr,\n\t\t\t\t\t\tparseExpression(precedence-1)\n\t\t\t\t\t]\n\t\t\t\t};\n\t\t\t\ttoken = lexer.peek();\n\t\t\t}\n\t\t\treturn expr;\n\t\t}\n\n\t\tfunction parseUnary() {\n\t\t\tvar token, expr;\n\t\t\ttoken = lexer.peek();\n\t\t\tif (matchGroup(token, \"unary\")) {\n\t\t\t\ttoken = lexer.next();\n\t\t\t\texpr = parseUnary();\n\t\t\t\treturn {\n\t\t\t\t\toperator: token.value,\n\t\t\t\t\tmethod : token.method,\n\t\t\t\t\targs : [expr]\n\t\t\t\t};\n\t\t\t}\n\t\t\treturn parsePrimary();\n\t\t}\n\n\t\tfunction parsePrimary() {\n\t\t\tvar token, expr;\n\t\t\ttoken = lexer.peek();\n\t\t\tif (isUndef(token)) {\n\t\t\t\tthrow new SyntaxError(\"Tone.Expr: Unexpected termination of expression\");\n\t\t\t}\n\t\t\tif (token.type === \"func\") {\n\t\t\t\ttoken = lexer.next();\n\t\t\t\treturn parseFunctionCall(token);\n\t\t\t}\n\t\t\tif (token.type === \"value\") {\n\t\t\t\ttoken = lexer.next();\n\t\t\t\treturn {\n\t\t\t\t\tmethod : token.method,\n\t\t\t\t\targs : token.value\n\t\t\t\t};\n\t\t\t}\n\t\t\tif (matchSyntax(token, \"(\")) {\n\t\t\t\tlexer.next();\n\t\t\t\texpr = parseExpression();\n\t\t\t\ttoken = lexer.next();\n\t\t\t\tif (!matchSyntax(token, \")\")) {\n\t\t\t\t\tthrow new SyntaxError(\"Expected )\");\n\t\t\t\t}\n\t\t\t\treturn expr;\n\t\t\t}\n\t\t\tthrow new SyntaxError(\"Tone.Expr: Parse error, cannot process token \" + token.value);\n\t\t}\n\n\t\tfunction parseFunctionCall(func) {\n\t\t\tvar token, args = [];\n\t\t\ttoken = lexer.next();\n\t\t\tif (!matchSyntax(token, \"(\")) {\n\t\t\t\tthrow new SyntaxError(\"Tone.Expr: Expected ( in a function call \\\"\" + func.value + \"\\\"\");\n\t\t\t}\n\t\t\ttoken = lexer.peek();\n\t\t\tif (!matchSyntax(token, \")\")) {\n\t\t\t\targs = parseArgumentList();\n\t\t\t}\n\t\t\ttoken = lexer.next();\n\t\t\tif (!matchSyntax(token, \")\")) {\n\t\t\t\tthrow new SyntaxError(\"Tone.Expr: Expected ) in a function call \\\"\" + func.value + \"\\\"\");\n\t\t\t}\n\t\t\treturn {\n\t\t\t\tmethod : func.method,\n\t\t\t\targs : args,\n\t\t\t\tname : name\n\t\t\t};\n\t\t}\n\n\t\tfunction parseArgumentList() {\n\t\t\tvar token, expr, args = [];\n\t\t\twhile (true) {\n\t\t\t\texpr = parseExpression();\n\t\t\t\tif (isUndef(expr)) {\n\t\t\t\t\t// TODO maybe throw exception?\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\targs.push(expr);\n\t\t\t\ttoken = lexer.peek();\n\t\t\t\tif (!matchSyntax(token, \",\")) {\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tlexer.next();\n\t\t\t}\n\t\t\treturn args;\n\t\t}\n\n\t\treturn parseExpression();\n\t};\n\n\t/**\n\t * recursively evaluate the expression tree\n\t * @param {Object} tree \n\t * @return {AudioNode} the resulting audio node from the expression\n\t * @private\n\t */\n\tTone.Expr.prototype._eval = function(tree){\n\t\tif (!this.isUndef(tree)){\n\t\t\tvar node = tree.method(tree.args, this);\n\t\t\tthis._nodes.push(node);\n\t\t\treturn node;\n\t\t} \n\t};\n\n\t/**\n\t * dispose all the nodes\n\t * @private\n\t */\n\tTone.Expr.prototype._disposeNodes = function(){\n\t\tfor (var i = 0; i < this._nodes.length; i++){\n\t\t\tvar node = this._nodes[i];\n\t\t\tif (this.isFunction(node.dispose)) {\n\t\t\t\tnode.dispose();\n\t\t\t} else if (this.isFunction(node.disconnect)) {\n\t\t\t\tnode.disconnect();\n\t\t\t}\n\t\t\tnode = null;\n\t\t\tthis._nodes[i] = null;\n\t\t}\n\t\tthis._nodes = null;\n\t};\n\n\t/**\n\t * clean up\n\t */\n\tTone.Expr.prototype.dispose = function(){\n\t\tTone.prototype.dispose.call(this);\n\t\tthis._disposeNodes();\n\t};\n\n\treturn Tone.Expr;\n});","define([\"Tone/core/Tone\", \"Tone/signal/GreaterThanZero\", \"Tone/signal/Subtract\", \"Tone/signal/Signal\"], \n\tfunction(Tone){\n\n\t\"use strict\";\n\n\t/**\n\t * @class Output 1 if the signal is greater than the value, otherwise outputs 0.\n\t * can compare two signals or a signal and a number. \n\t * \n\t * @constructor\n\t * @extends {Tone.Signal}\n\t * @param {number} [value=0] the value to compare to the incoming signal\n\t * @example\n\t * var gt = new Tone.GreaterThan(2);\n\t * var sig = new Tone.Signal(4).connect(gt);\n\t * //output of gt is equal 1. \n\t */\n\tTone.GreaterThan = function(value){\n\n\t\tthis.createInsOuts(2, 0);\n\t\t\n\t\t/**\n\t\t * subtract the amount from the incoming signal\n\t\t * @type {Tone.Subtract}\n\t\t * @private\n\t\t */\n\t\tthis._param = this.input[0] = new Tone.Subtract(value);\n\t\tthis.input[1] = this._param.input[1];\n\n\t\t/**\n\t\t * compare that amount to zero\n\t\t * @type {Tone.GreaterThanZero}\n\t\t * @private\n\t\t */\n\t\tthis._gtz = this.output = new Tone.GreaterThanZero();\n\n\t\t//connect\n\t\tthis._param.connect(this._gtz);\n\t};\n\n\tTone.extend(Tone.GreaterThan, Tone.Signal);\n\n\t/**\n\t * dispose method\n\t * @returns {Tone.GreaterThan} this\n\t */\n\tTone.GreaterThan.prototype.dispose = function(){\n\t\tTone.prototype.dispose.call(this);\n\t\tthis._param.dispose();\n\t\tthis._param = null;\n\t\tthis._gtz.dispose();\n\t\tthis._gtz = null;\n\t\treturn this;\n\t};\n\n\treturn Tone.GreaterThan;\n});","define([\"Tone/core/Tone\", \"Tone/signal/WaveShaper\", \"Tone/signal/SignalBase\"], \nfunction(Tone){\n\n\t\"use strict\";\n\n\t/**\n\t * @class Return the absolute value of an incoming signal. \n\t * \n\t * @constructor\n\t * @extends {Tone.SignalBase}\n\t * @example\n\t * var signal = new Tone.Signal(-1);\n\t * var abs = new Tone.Abs();\n\t * signal.connect(abs);\n\t * //the output of abs is 1. \n\t */\n\tTone.Abs = function(){\n\t\t/**\n\t\t * @type {Tone.LessThan}\n\t\t * @private\n\t\t */\n\t\tthis._abs = this.input = this.output = new Tone.WaveShaper(function(val){\n\t\t\tif (val === 0){\n\t\t\t\treturn 0;\n\t\t\t} else {\n\t\t\t\treturn Math.abs(val);\n\t\t\t}\n\t\t}, 127);\n\t};\n\n\tTone.extend(Tone.Abs, Tone.SignalBase);\n\n\t/**\n\t * dispose method\n\t * @returns {Tone.Abs} this\n\t */\n\tTone.Abs.prototype.dispose = function(){\n\t\tTone.prototype.dispose.call(this);\n\t\tthis._abs.dispose();\n\t\tthis._abs = null;\n\t\treturn this;\n\t}; \n\n\treturn Tone.Abs;\n});","define([\"Tone/core/Tone\", \"Tone/signal/WaveShaper\", \"Tone/signal/Multiply\", \"Tone/signal/Subtract\"], \nfunction(Tone){\n\n\t\"use strict\";\n\n\t/**\n\t * @class Signal-rate modulo operator. Only works in AudioRange [-1, 1] and for modulus\n\t * values in the NormalRange. \n\t *\n\t * @constructor\n\t * @extends {Tone.SignalBase}\n\t * @param {NormalRange} modulus The modulus to apply.\n\t * @example\n\t * var mod = new Tone.Modulo(0.2)\n\t * var sig = new Tone.Signal(0.5).connect(mod);\n\t * //mod outputs 0.1\n\t */\n\tTone.Modulo = function(modulus){\n\n\t\tthis.createInsOuts(1, 0);\n\n\t\t/**\n\t\t * A waveshaper gets the integer multiple of \n\t\t * the input signal and the modulus.\n\t\t * @private\n\t\t * @type {Tone.WaveShaper}\n\t\t */\n\t\tthis._shaper = new Tone.WaveShaper(Math.pow(2, 16));\n\n\t\t/**\n\t\t * the integer multiple is multiplied by the modulus\n\t\t * @type {Tone.Multiply}\n\t\t * @private\n\t\t */\n\t\tthis._multiply = new Tone.Multiply();\n\n\t\t/**\n\t\t * and subtracted from the input signal\n\t\t * @type {Tone.Subtract}\n\t\t * @private\n\t\t */\n\t\tthis._subtract = this.output = new Tone.Subtract();\n\n\t\t/**\n\t\t * the modulus signal\n\t\t * @type {Tone.Signal}\n\t\t * @private\n\t\t */\n\t\tthis._modSignal = new Tone.Signal(modulus);\n\n\t\t//connections\n\t\tthis.input.fan(this._shaper, this._subtract);\n\t\tthis._modSignal.connect(this._multiply, 0, 0);\n\t\tthis._shaper.connect(this._multiply, 0, 1);\n\t\tthis._multiply.connect(this._subtract, 0, 1);\n\t\tthis._setWaveShaper(modulus);\n\t};\n\n\tTone.extend(Tone.Modulo, Tone.SignalBase);\n\n\t/**\n\t * @param {number} mod the modulus to apply\n\t * @private\n\t */\n\tTone.Modulo.prototype._setWaveShaper = function(mod){\n\t\tthis._shaper.setMap(function(val){\n\t\t\tvar multiple = Math.floor((val + 0.0001) / mod);\n\t\t\treturn multiple;\n\t\t});\n\t};\n\n\t/**\n\t * The modulus value.\n\t * @memberOf Tone.Modulo#\n\t * @type {NormalRange}\n\t * @name value\n\t */\n\tObject.defineProperty(Tone.Modulo.prototype, \"value\", {\n\t\tget : function(){\n\t\t\treturn this._modSignal.value;\n\t\t},\n\t\tset : function(mod){\n\t\t\tthis._modSignal.value = mod;\n\t\t\tthis._setWaveShaper(mod);\n\t\t}\n\t});\n\n\t/**\n\t * clean up\n\t * @returns {Tone.Modulo} this\n\t */\n\tTone.Modulo.prototype.dispose = function(){\n\t\tTone.prototype.dispose.call(this);\n\t\tthis._shaper.dispose();\n\t\tthis._shaper = null;\n\t\tthis._multiply.dispose();\n\t\tthis._multiply = null;\n\t\tthis._subtract.dispose();\n\t\tthis._subtract = null;\n\t\tthis._modSignal.dispose();\n\t\tthis._modSignal = null;\n\t\treturn this;\n\t};\n\n\treturn Tone.Modulo;\n});","define([\"Tone/core/Tone\", \"Tone/signal/WaveShaper\"], function(Tone){\n\n\t\"use strict\";\n\n\t/**\n\t * @class Pow applies an exponent to the incoming signal. The incoming signal\n\t * must be AudioRange.\n\t *\n\t * @extends {Tone.SignalBase}\n\t * @constructor\n\t * @param {Positive} exp The exponent to apply to the incoming signal, must be at least 2. \n\t * @example\n\t * var pow = new Tone.Pow(2);\n\t * var sig = new Tone.Signal(0.5).connect(pow);\n\t * //output of pow is 0.25. \n\t */\n\tTone.Pow = function(exp){\n\n\t\t/**\n\t\t * the exponent\n\t\t * @private\n\t\t * @type {number}\n\t\t */\n\t\tthis._exp = this.defaultArg(exp, 1);\n\n\t\t/**\n\t\t * @type {WaveShaperNode}\n\t\t * @private\n\t\t */\n\t\tthis._expScaler = this.input = this.output = new Tone.WaveShaper(this._expFunc(this._exp), 8192);\n\t};\n\n\tTone.extend(Tone.Pow, Tone.SignalBase);\n\n\t/**\n\t * The value of the exponent.\n\t * @memberOf Tone.Pow#\n\t * @type {number}\n\t * @name value\n\t */\n\tObject.defineProperty(Tone.Pow.prototype, \"value\", {\n\t\tget : function(){\n\t\t\treturn this._exp;\n\t\t},\n\t\tset : function(exp){\n\t\t\tthis._exp = exp;\n\t\t\tthis._expScaler.setMap(this._expFunc(this._exp));\n\t\t}\n\t});\n\n\n\t/**\n\t * the function which maps the waveshaper\n\t * @param {number} exp\n\t * @return {function}\n\t * @private\n\t */\n\tTone.Pow.prototype._expFunc = function(exp){\n\t\treturn function(val){\n\t\t\treturn Math.pow(Math.abs(val), exp);\n\t\t};\n\t};\n\n\t/**\n\t * Clean up.\n\t * @returns {Tone.Pow} this\n\t */\n\tTone.Pow.prototype.dispose = function(){\n\t\tTone.prototype.dispose.call(this);\n\t\tthis._expScaler.dispose();\n\t\tthis._expScaler = null;\n\t\treturn this;\n\t};\n\n\treturn Tone.Pow;\n});","define([\"Tone/core/Tone\", \"Tone/signal/WaveShaper\", \"Tone/signal/Signal\"], function(Tone){\n\n\t\"use strict\";\n\n\t/**\n\t * @class AudioToGain converts an input in AudioRange [-1,1] to NormalRange [0,1]. \n\t * See Tone.GainToAudio.\n\t *\n\t * @extends {Tone.SignalBase}\n\t * @constructor\n\t * @example\n\t * var a2g = new Tone.AudioToGain();\n\t */\n\tTone.AudioToGain = function(){\n\n\t\t/**\n\t\t * @type {WaveShaperNode}\n\t\t * @private\n\t\t */\n\t\tthis._norm = this.input = this.output = new Tone.WaveShaper(function(x){\n\t\t\treturn (x + 1) / 2;\n\t\t});\n\t};\n\n\tTone.extend(Tone.AudioToGain, Tone.SignalBase);\n\n\t/**\n\t * clean up\n\t * @returns {Tone.AudioToGain} this\n\t */\n\tTone.AudioToGain.prototype.dispose = function(){\n\t\tTone.prototype.dispose.call(this);\n\t\tthis._norm.dispose();\n\t\tthis._norm = null;\n\t\treturn this;\n\t};\n\n\treturn Tone.AudioToGain;\n});","define([\"Tone/core/Tone\", \"Tone/signal/WaveShaper\"], function(Tone){\n\n\t\"use strict\";\n\n\t/**\n\t * @class Convert an incoming signal between 0, 1 to an equal power gain scale.\n\t *\n\t * @extends {Tone.SignalBase}\n\t * @constructor\n\t * @example\n\t * var eqPowGain = new Tone.EqualPowerGain();\n\t */\n\tTone.EqualPowerGain = function(){\n\n\t\t/**\n\t\t * @type {Tone.WaveShaper}\n\t\t * @private\n\t\t */\n\t\tthis._eqPower = this.input = this.output = new Tone.WaveShaper(function(val){\n\t\t\tif (Math.abs(val) < 0.001){\n\t\t\t\t//should output 0 when input is 0\n\t\t\t\treturn 0;\n\t\t\t} else {\n\t\t\t\treturn this.equalPowerScale(val);\n\t\t\t}\n\t\t}.bind(this), 4096);\n\t};\n\n\tTone.extend(Tone.EqualPowerGain, Tone.SignalBase);\n\n\t/**\n\t * clean up\n\t * @returns {Tone.EqualPowerGain} this\n\t */\n\tTone.EqualPowerGain.prototype.dispose = function(){\n\t\tTone.prototype.dispose.call(this);\n\t\tthis._eqPower.dispose();\n\t\tthis._eqPower = null;\n\t\treturn this;\n\t};\n\n\treturn Tone.EqualPowerGain;\n});","'use strict';\r\n\r\ndefine(function (require) {\r\n\r\n var Effect = require('effect');\r\n var EQFilter = require('eqFilter');\r\n\r\n /**\r\n * p5.EQ is an audio effect that performs the function of a multiband\r\n * audio equalizer. Equalization is used to adjust the balance of\r\n * frequency compoenents of an audio signal. This process is commonly used\r\n * in sound production and recording to change the waveform before it reaches\r\n * a sound output device. EQ can also be used as an audio effect to create\r\n * interesting distortions by filtering out parts of the spectrum. p5.EQ is\r\n * built using a chain of Web Audio Biquad Filter Nodes and can be\r\n * instantiated with 3 or 8 bands. Bands can be added or removed from\r\n * the EQ by directly modifying p5.EQ.bands (the array that stores filters).\r\n *\r\n * This class extends p5.Effect.\r\n * Methods amp(), chain(),\r\n * drywet(), connect(), and\r\n * disconnect() are available.\r\n *\r\n * @class p5.EQ\r\n * @constructor\r\n * @extends p5.Effect\r\n * @param {Number} [_eqsize] Constructor will accept 3 or 8, defaults to 3\r\n * @return {Object} p5.EQ object\r\n *\r\n * @example\r\n *
\r\n * var eq;\r\n * var band_names;\r\n * var band_index;\r\n *\r\n * var soundFile, play;\r\n *\r\n * function preload() {\r\n * soundFormats('mp3', 'ogg');\r\n * soundFile = loadSound('assets/beat');\r\n * }\r\n *\r\n * function setup() {\r\n * eq = new p5.EQ(3);\r\n * soundFile.disconnect();\r\n * eq.process(soundFile);\r\n *\r\n * band_names = ['lows','mids','highs'];\r\n * band_index = 0;\r\n * play = false;\r\n * textAlign(CENTER);\r\n * }\r\n *\r\n * function draw() {\r\n * background(30);\r\n * noStroke();\r\n * fill(255);\r\n * text('click to kill',50,25);\r\n *\r\n * fill(255, 40, 255);\r\n * textSize(26);\r\n * text(band_names[band_index],50,55);\r\n *\r\n * fill(255);\r\n * textSize(9);\r\n * text('space = play/pause',50,80);\r\n * }\r\n *\r\n * //If mouse is over canvas, cycle to the next band and kill the frequency\r\n * function mouseClicked() {\r\n * for (var i = 0; i < eq.bands.length; i++) {\r\n * eq.bands[i].gain(0);\r\n * }\r\n * eq.bands[band_index].gain(-40);\r\n * if (mouseX > 0 && mouseX < width && mouseY < height && mouseY > 0) {\r\n * band_index === 2 ? band_index = 0 : band_index++;\r\n * }\r\n * }\r\n *\r\n * //use space bar to trigger play / pause\r\n * function keyPressed() {\r\n * if (key===' ') {\r\n * play = !play\r\n * play ? soundFile.loop() : soundFile.pause();\r\n * }\r\n * }\r\n *
\r\n */\r\n p5.EQ = function(_eqsize) {\r\n Effect.call(this);\r\n\r\n //p5.EQ can be of size (3) or (8), defaults to 3\r\n _eqsize = _eqsize === 3 || _eqsize === 8 ? _eqsize : 3;\r\n\r\n var factor;\r\n _eqsize === 3 ? factor = Math.pow(2,3) : factor = 2;\r\n\r\n /**\r\n * The p5.EQ is built with abstracted p5.Filter objects.\r\n * To modify any bands, use methods of the \r\n * p5.Filter API, especially `gain` and `freq`.\r\n * Bands are stored in an array, with indices 0 - 3, or 0 - 7\r\n * @property {Array} bands\r\n *\r\n */\r\n this.bands = [];\r\n\r\n\r\n var freq, res;\r\n for (var i = 0; i < _eqsize; i++) {\r\n if (i === _eqsize - 1) {\r\n freq = 21000;\r\n res = .01;\r\n } else if (i === 0) {\r\n freq = 100;\r\n res = .1;\r\n }\r\n else if (i===1) {\r\n freq = _eqsize === 3 ? 360 * factor : 360;\r\n res = 1;\r\n }else {\r\n freq = this.bands[i-1].freq() * factor;\r\n res = 1;\r\n }\r\n this.bands[i] = this._newBand(freq, res);\r\n\r\n if (i>0) {\r\n this.bands[i-1].connect(this.bands[i].biquad);\r\n } else {\r\n this.input.connect(this.bands[i].biquad);\r\n }\r\n }\r\n this.bands[_eqsize-1].connect(this.output);\r\n };\r\n p5.EQ.prototype = Object.create(Effect.prototype);\r\n\r\n /**\r\n * Process an input by connecting it to the EQ\r\n * @method process\r\n * @param {Object} src Audio source\r\n */\r\n p5.EQ.prototype.process = function (src) {\r\n src.connect(this.input);\r\n };\r\n\r\n // /**\r\n // * Set the frequency and gain of each band in the EQ. This method should be\r\n // * called with 3 or 8 frequency and gain pairs, depending on the size of the EQ.\r\n // * ex. eq.set(freq0, gain0, freq1, gain1, freq2, gain2);\r\n // *\r\n // * @method set\r\n // * @for p5.EQ\r\n // * @param {Number} [freq0] Frequency value for band with index 0\r\n // * @param {Number} [gain0] Gain value for band with index 0\r\n // * @param {Number} [freq1] Frequency value for band with index 1\r\n // * @param {Number} [gain1] Gain value for band with index 1\r\n // * @param {Number} [freq2] Frequency value for band with index 2\r\n // * @param {Number} [gain2] Gain value for band with index 2\r\n // * @param {Number} [freq3] Frequency value for band with index 3\r\n // * @param {Number} [gain3] Gain value for band with index 3\r\n // * @param {Number} [freq4] Frequency value for band with index 4\r\n // * @param {Number} [gain4] Gain value for band with index 4\r\n // * @param {Number} [freq5] Frequency value for band with index 5\r\n // * @param {Number} [gain5] Gain value for band with index 5\r\n // * @param {Number} [freq6] Frequency value for band with index 6\r\n // * @param {Number} [gain6] Gain value for band with index 6\r\n // * @param {Number} [freq7] Frequency value for band with index 7\r\n // * @param {Number} [gain7] Gain value for band with index 7\r\n // */\r\n p5.EQ.prototype.set = function() {\r\n if (arguments.length === this.bands.length * 2) {\r\n for (var i = 0; i < arguments.length; i+=2) {\r\n this.bands[i/2].freq(arguments[i]);\r\n this.bands[i/2].gain(arguments[i+1]);\r\n }\r\n }\r\n else {\r\n console.error('Argument mismatch. .set() should be called with ' + this.bands.length*2 +\r\n ' arguments. (one frequency and gain value pair for each band of the eq)');\r\n }\r\n };\r\n\r\n /**\r\n * Add a new band. Creates a p5.Filter and strips away everything but\r\n * the raw biquad filter. This method returns an abstracted p5.Filter,\r\n * which can be added to p5.EQ.bands, in order to create new EQ bands.\r\n * @private\r\n * @for p5.EQ\r\n * @method _newBand\r\n * @param {Number} freq\r\n * @param {Number} res\r\n * @return {Object} Abstracted Filter\r\n */\r\n p5.EQ.prototype._newBand = function(freq, res) {\r\n return new EQFilter(freq, res);\r\n };\r\n\r\n p5.EQ.prototype.dispose = function () {\r\n Effect.prototype.dispose.apply(this);\r\n\r\n if (this.bands) {\r\n while (this.bands.length > 0) {\r\n delete this.bands.pop().dispose();\r\n }\r\n delete this.bands;\r\n }\r\n };\r\n\r\n return p5.EQ;\r\n});\r\n","'use strict';\r\n\r\ndefine(function (require) {\r\n var Filter = require('filter');\r\n var p5sound = require('master');\r\n\r\n /**\r\n * EQFilter extends p5.Filter with constraints\r\n * necessary for the p5.EQ\r\n *\r\n * @private\r\n */\r\n var EQFilter = function(freq, res) {\r\n Filter.call(this, 'peaking');\r\n this.disconnect();\r\n this.set(freq, res);\r\n this.biquad.gain.value = 0;\r\n delete this.input;\r\n delete this.output;\r\n delete this._drywet;\r\n delete this.wet;\r\n\r\n };\r\n EQFilter.prototype = Object.create(Filter.prototype);\r\n\r\n EQFilter.prototype.amp = function() {\r\n console.warn('`amp()` is not available for p5.EQ bands. Use `.gain()`');\r\n };\r\n EQFilter.prototype.drywet = function() {\r\n console.warn('`drywet()` is not available for p5.EQ bands.');\r\n };\r\n EQFilter.prototype.connect = function(unit) {\r\n var u = unit || p5.soundOut.input;\r\n if (this.biquad) {\r\n this.biquad.connect(u.input ? u.input : u);\r\n } else {\r\n this.output.connect(u.input ? u.input : u);\r\n }\r\n };\r\n\r\n EQFilter.prototype.disconnect = function() {\r\n if (this.biquad) {\r\n this.biquad.disconnect();\r\n }\r\n };\r\n EQFilter.prototype.dispose = function() {\r\n // remove reference form soundArray\r\n var index = p5sound.soundArray.indexOf(this);\r\n p5sound.soundArray.splice(index, 1);\r\n this.disconnect();\r\n delete this.biquad;\r\n };\r\n\r\n return EQFilter;\r\n});\r\n","'use strict'\r\n\r\ndefine(function (require) {\r\n var p5sound = require('master');\r\n var Effect = require('effect');\r\n\r\n /**\r\n * Panner3D is based on the \r\n * Web Audio Spatial Panner Node.\r\n * This panner is a spatial processing node that allows audio to be positioned\r\n * and oriented in 3D space.\r\n *\r\n * The position is relative to an \r\n * Audio Context Listener, which can be accessed\r\n * by p5.soundOut.audiocontext.listener\r\n *\r\n *\r\n * @class p5.Panner3D\r\n * @constructor\r\n */\r\n\tp5.Panner3D = function() {\r\n Effect.call(this);\r\n\r\n /**\r\n * \r\n * Web Audio Spatial Panner Node\r\n *\r\n * Properties include\r\n * - panningModel: \"equal power\" or \"HRTF\"\r\n * - distanceModel: \"linear\", \"inverse\", or \"exponential\"\r\n *\r\n * @property {AudioNode} panner\r\n *\r\n */\r\n this.panner = this.ac.createPanner();\r\n this.panner.panningModel = 'HRTF';\r\n this.panner.distanceModel = 'linear';\r\n this.panner.connect(this.output);\r\n this.input.connect(this.panner);\r\n\t};\r\n\r\n p5.Panner3D.prototype = Object.create(Effect.prototype);\r\n\r\n\r\n /**\r\n * Connect an audio sorce\r\n *\r\n * @method process\r\n * @for p5.Panner3D\r\n * @param {Object} src Input source\r\n */\r\n p5.Panner3D.prototype.process = function(src) {\r\n src.connect(this.input);\r\n }\r\n /**\r\n * Set the X,Y,Z position of the Panner\r\n * @method set\r\n * @for p5.Panner3D\r\n * @param {Number} xVal\r\n * @param {Number} yVal\r\n * @param {Number} zVal\r\n * @param {Number} time\r\n * @return {Array} Updated x, y, z values as an array\r\n */\r\n p5.Panner3D.prototype.set = function(xVal, yVal, zVal, time) {\r\n this.positionX(xVal,time);\r\n this.positionY(yVal,time);\r\n this.positionZ(zVal,time);\r\n return [this.panner.positionX.value,\r\n this.panner.positionY.value,\r\n this.panner.positionZ.value];\r\n };\r\n\r\n /**\r\n * Getter and setter methods for position coordinates\r\n * @method positionX\r\n * @for p5.Panner3D\r\n * @return {Number} updated coordinate value\r\n */\r\n /**\r\n * Getter and setter methods for position coordinates\r\n * @method positionY\r\n * @for p5.Panner3D\r\n * @return {Number} updated coordinate value\r\n */\r\n /**\r\n * Getter and setter methods for position coordinates\r\n * @method positionZ\r\n * @for p5.Panner3D\r\n * @return {Number} updated coordinate value\r\n */\r\n p5.Panner3D.prototype.positionX = function(xVal, time) {\r\n var t = time || 0;\r\n if (typeof xVal === 'number') {\r\n this.panner.positionX.value = xVal;\r\n this.panner.positionX.cancelScheduledValues(this.ac.currentTime + 0.01 + t);\r\n this.panner.positionX.linearRampToValueAtTime(xVal, this.ac.currentTime + 0.02 + t);\r\n } else if (xVal) {\r\n xVal.connect(this.panner.positionX);\r\n }\r\n return this.panner.positionX.value;\r\n };\r\n p5.Panner3D.prototype.positionY = function(yVal, time) {\r\n var t = time || 0;\r\n if (typeof yVal === 'number') {\r\n this.panner.positionY.value = yVal;\r\n this.panner.positionY.cancelScheduledValues(this.ac.currentTime + 0.01 + t);\r\n this.panner.positionY.linearRampToValueAtTime(yVal, this.ac.currentTime + 0.02 + t);\r\n } else if (yVal) {\r\n yVal.connect(this.panner.positionY);\r\n }\r\n return this.panner.positionY.value;\r\n };\r\n p5.Panner3D.prototype.positionZ = function(zVal, time) {\r\n var t = time || 0;\r\n if (typeof zVal === 'number') {\r\n this.panner.positionZ.value = zVal;\r\n this.panner.positionZ.cancelScheduledValues(this.ac.currentTime + 0.01 + t);\r\n this.panner.positionZ.linearRampToValueAtTime(zVal, this.ac.currentTime + 0.02 + t);\r\n } else if (zVal) {\r\n zVal.connect(this.panner.positionZ);\r\n }\r\n return this.panner.positionZ.value;\r\n };\r\n\r\n /**\r\n * Set the X,Y,Z position of the Panner\r\n * @method orient\r\n * @for p5.Panner3D\r\n * @param {Number} xVal\r\n * @param {Number} yVal\r\n * @param {Number} zVal\r\n * @param {Number} time\r\n * @return {Array} Updated x, y, z values as an array\r\n */\r\n p5.Panner3D.prototype.orient = function(xVal, yVal, zVal, time) {\r\n this.orientX(xVal,time);\r\n this.orientY(yVal,time);\r\n this.orientZ(zVal,time);\r\n return [this.panner.orientationX.value,\r\n this.panner.orientationY.value,\r\n this.panner.orientationZ.value];\r\n };\r\n\r\n /**\r\n * Getter and setter methods for orient coordinates\r\n * @method orientX\r\n * @for p5.Panner3D\r\n * @return {Number} updated coordinate value\r\n */\r\n /**\r\n * Getter and setter methods for orient coordinates\r\n * @method orientY\r\n * @for p5.Panner3D\r\n * @return {Number} updated coordinate value\r\n */\r\n /**\r\n * Getter and setter methods for orient coordinates\r\n * @method orientZ\r\n * @for p5.Panner3D\r\n * @return {Number} updated coordinate value\r\n */\r\n p5.Panner3D.prototype.orientX = function(xVal, time) {\r\n var t = time || 0;\r\n if (typeof xVal === 'number') {\r\n this.panner.orientationX.value = xVal;\r\n this.panner.orientationX.cancelScheduledValues(this.ac.currentTime + 0.01 + t);\r\n this.panner.orientationX.linearRampToValueAtTime(xVal, this.ac.currentTime + 0.02 + t);\r\n } else if (xVal) {\r\n xVal.connect(this.panner.orientationX);\r\n }\r\n return this.panner.orientationX.value;\r\n };\r\n p5.Panner3D.prototype.orientY = function(yVal, time) {\r\n var t = time || 0;\r\n if (typeof yVal === 'number') {\r\n this.panner.orientationY.value = yVal;\r\n this.panner.orientationY.cancelScheduledValues(this.ac.currentTime + 0.01 + t);\r\n this.panner.orientationY.linearRampToValueAtTime(yVal, this.ac.currentTime + 0.02 + t);\r\n } else if (yVal) {\r\n yVal.connect(this.panner.orientationY);\r\n }\r\n return this.panner.orientationY.value;\r\n };\r\n p5.Panner3D.prototype.orientZ = function(zVal, time) {\r\n var t = time || 0;\r\n if (typeof zVal === 'number') {\r\n this.panner.orientationZ.value = zVal;\r\n this.panner.orientationZ.cancelScheduledValues(this.ac.currentTime + 0.01 + t);\r\n this.panner.orientationZ.linearRampToValueAtTime(zVal, this.ac.currentTime + 0.02 + t);\r\n } else if (zVal) {\r\n zVal.connect(this.panner.orientationZ);\r\n }\r\n return this.panner.orientationZ.value;\r\n };\r\n\r\n /**\r\n * Set the rolloff factor and max distance\r\n * @method setFalloff\r\n * @for p5.Panner3D\r\n * @param {Number} [maxDistance]\r\n * @param {Number} [rolloffFactor]\r\n */\r\n p5.Panner3D.prototype.setFalloff = function(maxDistance, rolloffFactor) {\r\n this.maxDist(maxDistance);\r\n this.rolloff(rolloffFactor);\r\n };\r\n /**\r\n * Maxium distance between the source and the listener\r\n * @method maxDist\r\n * @for p5.Panner3D\r\n * @param {Number} maxDistance\r\n * @return {Number} updated value\r\n */\r\n p5.Panner3D.prototype.maxDist = function(maxDistance){\r\n if (typeof maxDistance === 'number') {\r\n this.panner.maxDistance = maxDistance;\r\n }\r\n return this.panner.maxDistance;\r\n };\r\n\r\n /**\r\n * How quickly the volume is reduced as the source moves away from the listener\r\n * @method rollof\r\n * @for p5.Panner3D\r\n * @param {Number} rolloffFactor\r\n * @return {Number} updated value\r\n */\r\n p5.Panner3D.prototype.rolloff = function(rolloffFactor){\r\n if (typeof rolloffFactor === 'number') {\r\n this.panner.rolloffFactor = rolloffFactor;\r\n }\r\n return this.panner.rolloffFactor;\r\n };\r\n\r\n p5.Panner3D.dispose = function() {\r\n Effect.prototype.dispose.apply(this);\r\n if (this.panner) {\r\n this.panner.disconnect();\r\n delete this.panner;\r\n }\r\n };\r\n\r\n return p5.Panner3D;\r\n\r\n});\r\n","'use strict'\r\n\r\ndefine(function (require) {\r\n var p5sound = require('master');\r\n var Effect = require('effect');\r\n\r\n// /**\r\n// * listener is a class that can construct both a Spatial Panner\r\n// * and a Spatial Listener. The panner is based on the \r\n// * Web Audio Spatial Panner Node\r\n// * https://www.w3.org/TR/webaudio/#the-listenernode-interface\r\n// * This panner is a spatial processing node that allows audio to be positioned\r\n// * and oriented in 3D space. \r\n// *\r\n// * The Listener modifies the properties of the Audio Context Listener. \r\n// * Both objects types use the same methods. The default is a spatial panner.\r\n// *\r\n// * p5.Panner3D - Constructs a Spatial Panner \r\n// * p5.Listener3D - Constructs a Spatial Listener \r\n// *\r\n// * @class listener\r\n// * @constructor\r\n// * @return {Object} p5.Listener3D Object\r\n// *\r\n// * @param {Web Audio Node} listener Web Audio Spatial Panning Node\r\n// * @param {AudioParam} listener.panningModel \"equal power\" or \"HRTF\"\r\n// * @param {AudioParam} listener.distanceModel \"linear\", \"inverse\", or \"exponential\"\r\n// * @param {String} [type] [Specify construction of a spatial panner or listener]\r\n// */\r\n \r\n\tp5.Listener3D = function(type) {\r\n this.ac = p5sound.audiocontext;\r\n this.listener = this.ac.listener;\r\n\t}; \r\n\r\n// /**\r\n// * Connect an audio sorce\r\n// * @param {Object} src Input source\r\n// */\r\n p5.Listener3D.prototype.process = function(src) {\r\n src.connect(this.input);\r\n }\r\n// /**\r\n// * Set the X,Y,Z position of the Panner\r\n// * @param {[Number]} xVal\r\n// * @param {[Number]} yVal\r\n// * @param {[Number]} zVal\r\n// * @param {[Number]} time\r\n// * @return {[Array]} [Updated x, y, z values as an array]\r\n// */\r\n p5.Listener3D.prototype.position = function(xVal, yVal, zVal, time) {\r\n this.positionX(xVal,time);\r\n this.positionY(yVal,time);\r\n this.positionZ(zVal,time);\r\n return [this.listener.positionX.value, \r\n this.listener.positionY.value,\r\n this.listener.positionZ.value];\r\n };\r\n\r\n// /**\r\n// * Getter and setter methods for position coordinates\r\n// * @return {Number} [updated coordinate value]\r\n// */\r\n p5.Listener3D.prototype.positionX = function(xVal, time) {\r\n var t = time || 0;\r\n if (typeof xVal === 'number') {\r\n this.listener.positionX.value = xVal;\r\n this.listener.positionX.cancelScheduledValues(this.ac.currentTime + 0.01 + t);\r\n this.listener.positionX.linearRampToValueAtTime(xVal, this.ac.currentTime + 0.02 + t);\r\n } else if (xVal) {\r\n xVal.connect(this.listener.positionX);\r\n }\r\n return this.listener.positionX.value;\r\n };\r\n p5.Listener3D.prototype.positionY = function(yVal, time) {\r\n var t = time || 0;\r\n if (typeof yVal === 'number') {\r\n this.listener.positionY.value = yVal;\r\n this.listener.positionY.cancelScheduledValues(this.ac.currentTime + 0.01 + t);\r\n this.listener.positionY.linearRampToValueAtTime(yVal, this.ac.currentTime + 0.02 + t);\r\n } else if (yVal) {\r\n yVal.connect(this.listener.positionY);\r\n }\r\n return this.listener.positionY.value;\r\n };\r\n p5.Listener3D.prototype.positionZ = function(zVal, time) {\r\n var t = time || 0;\r\n if (typeof zVal === 'number') {\r\n this.listener.positionZ.value = zVal;\r\n this.listener.positionZ.cancelScheduledValues(this.ac.currentTime + 0.01 + t);\r\n this.listener.positionZ.linearRampToValueAtTime(zVal, this.ac.currentTime + 0.02 + t);\r\n } else if (zVal) {\r\n zVal.connect(this.listener.positionZ);\r\n }\r\n return this.listener.positionZ.value;\r\n };\r\n\r\n// cannot define method when class definition is commented\r\n// /**\r\n// * Overrides the listener orient() method because Listener has slightly\r\n// * different params. In human terms, Forward vectors are the direction the \r\n// * nose is pointing. Up vectors are the direction of the top of the head.\r\n// *\r\n// * @method orient\r\n// * @param {Number} xValF Forward vector X direction\r\n// * @param {Number} yValF Forward vector Y direction\r\n// * @param {Number} zValF Forward vector Z direction\r\n// * @param {Number} xValU Up vector X direction\r\n// * @param {Number} yValU Up vector Y direction\r\n// * @param {Number} zValU Up vector Z direction\r\n// * @param {Number} time \r\n// * @return {Array} All orienation params\r\n// */\r\n p5.Listener3D.prototype.orient = function(xValF, yValF, zValF, \r\n xValU, yValU, zValU, time) {\r\n\r\n if (arguments.length === 3 || arguments.length === 4) {\r\n time = arguments[3];\r\n this.orientForward(xValF, yValF, zValF, time);\r\n } else if (arguments.length === 6 || arguments === 7) {\r\n this.orientForward(xValF, yValF, zValF);\r\n this.orientUp(xValU, yValU, zValU, time);\r\n }\r\n \r\n return [this.listener.forwardX.value, \r\n this.listener.forwardY.value,\r\n this.listener.forwardZ.value,\r\n this.listener.upX.value,\r\n this.listener.upY.value,\r\n this.listener.upZ.value];\r\n };\r\n\r\n\r\n p5.Listener3D.prototype.orientForward = function(xValF, yValF, zValF, time) {\r\n this.forwardX(xValF,time);\r\n this.forwardY(yValF,time);\r\n this.forwardZ(zValF,time);\r\n\r\n return [this.listener.forwardX, \r\n this.listener.forwardY,\r\n this.listener.forwardZ];\r\n };\r\n\r\n p5.Listener3D.prototype.orientUp = function(xValU, yValU, zValU, time) {\r\n this.upX(xValU,time);\r\n this.upY(yValU,time);\r\n this.upZ(zValU,time);\r\n\r\n return [this.listener.upX, \r\n this.listener.upY,\r\n this.listener.upZ];\r\n };\r\n// /**\r\n// * Getter and setter methods for orient coordinates\r\n// * @return {Number} [updated coordinate value]\r\n// */\r\n p5.Listener3D.prototype.forwardX = function(xVal, time) {\r\n var t = time || 0;\r\n if (typeof xVal === 'number') {\r\n this.listener.forwardX.value = xVal;\r\n this.listener.forwardX.cancelScheduledValues(this.ac.currentTime + 0.01 + t);\r\n this.listener.forwardX.linearRampToValueAtTime(xVal, this.ac.currentTime + 0.02 + t);\r\n } else if (xVal) {\r\n xVal.connect(this.listener.forwardX);\r\n }\r\n return this.listener.forwardX.value;\r\n };\r\n p5.Listener3D.prototype.forwardY = function(yVal, time) {\r\n var t = time || 0;\r\n if (typeof yVal === 'number') {\r\n this.listener.forwardY.value = yVal;\r\n this.listener.forwardY.cancelScheduledValues(this.ac.currentTime + 0.01 + t);\r\n this.listener.forwardY.linearRampToValueAtTime(yVal, this.ac.currentTime + 0.02 + t);\r\n } else if (yVal) {\r\n yVal.connect(this.listener.forwardY);\r\n }\r\n return this.listener.forwardY.value;\r\n };\r\n p5.Listener3D.prototype.forwardZ = function(zVal, time) {\r\n var t = time || 0;\r\n if (typeof zVal === 'number') {\r\n this.listener.forwardZ.value = zVal;\r\n this.listener.forwardZ.cancelScheduledValues(this.ac.currentTime + 0.01 + t);\r\n this.listener.forwardZ.linearRampToValueAtTime(zVal, this.ac.currentTime + 0.02 + t);\r\n } else if (zVal) {\r\n zVal.connect(this.listener.forwardZ);\r\n }\r\n return this.listener.forwardZ.value;\r\n };\r\n p5.Listener3D.prototype.upX = function(xVal, time) {\r\n var t = time || 0;\r\n if (typeof xVal === 'number') {\r\n this.listener.upX.value = xVal;\r\n this.listener.upX.cancelScheduledValues(this.ac.currentTime + 0.01 + t);\r\n this.listener.upX.linearRampToValueAtTime(xVal, this.ac.currentTime + 0.02 + t);\r\n } else if (xVal) {\r\n xVal.connect(this.listener.upX);\r\n }\r\n return this.listener.upX.value;\r\n };\r\n p5.Listener3D.prototype.upY = function(yVal, time) {\r\n var t = time || 0;\r\n if (typeof yVal === 'number') {\r\n this.listener.upY.value = yVal;\r\n this.listener.upY.cancelScheduledValues(this.ac.currentTime + 0.01 + t);\r\n this.listener.upY.linearRampToValueAtTime(yVal, this.ac.currentTime + 0.02 + t);\r\n } else if (yVal) {\r\n yVal.connect(this.listener.upY);\r\n }\r\n return this.listener.upY.value;\r\n };\r\n p5.Listener3D.prototype.upZ = function(zVal, time) {\r\n var t = time || 0;\r\n if (typeof zVal === 'number') {\r\n this.listener.upZ.value = zVal;\r\n this.listener.upZ.cancelScheduledValues(this.ac.currentTime + 0.01 + t);\r\n this.listener.upZ.linearRampToValueAtTime(zVal, this.ac.currentTime + 0.02 + t);\r\n } else if (zVal) {\r\n zVal.connect(this.listener.upZ);\r\n }\r\n return this.listener.upZ.value;\r\n };\r\n \r\n return p5.Listener3D;\r\n\r\n});","'use strict';\r\n\r\ndefine(function (require) {\r\n var Filter = require('filter');\r\n var Effect = require('effect');\r\n\r\n /**\r\n * Delay is an echo effect. It processes an existing sound source,\r\n * and outputs a delayed version of that sound. The p5.Delay can\r\n * produce different effects depending on the delayTime, feedback,\r\n * filter, and type. In the example below, a feedback of 0.5 (the\r\n * defaul value) will produce a looping delay that decreases in\r\n * volume by 50% each repeat. A filter will cut out the high\r\n * frequencies so that the delay does not sound as piercing as the\r\n * original source.\r\n *\r\n *\r\n * This class extends p5.Effect.\r\n * Methods amp(), chain(),\r\n * drywet(), connect(), and\r\n * disconnect() are available.\r\n * @class p5.Delay\r\n * @extends p5.Effect\r\n * @constructor\r\n * @example\r\n *
\r\n * var noise, env, delay;\r\n *\r\n * function setup() {\r\n * background(0);\r\n * noStroke();\r\n * fill(255);\r\n * textAlign(CENTER);\r\n * text('click to play', width/2, height/2);\r\n *\r\n * noise = new p5.Noise('brown');\r\n * noise.amp(0);\r\n * noise.start();\r\n *\r\n * delay = new p5.Delay();\r\n *\r\n * // delay.process() accepts 4 parameters:\r\n * // source, delayTime, feedback, filter frequency\r\n * // play with these numbers!!\r\n * delay.process(noise, .12, .7, 2300);\r\n *\r\n * // play the noise with an envelope,\r\n * // a series of fades ( time / value pairs )\r\n * env = new p5.Envelope(.01, 0.2, .2, .1);\r\n * }\r\n *\r\n * // mouseClick triggers envelope\r\n * function mouseClicked() {\r\n * // is mouse over canvas?\r\n * if (mouseX > 0 && mouseX < width && mouseY > 0 && mouseY < height) {\r\n * env.play(noise);\r\n * }\r\n * }\r\n *
\r\n */\r\n p5.Delay = function() {\r\n \tEffect.call(this);\r\n\r\n this._split = this.ac.createChannelSplitter(2);\r\n this._merge = this.ac.createChannelMerger(2);\r\n\r\n this._leftGain = this.ac.createGain();\r\n this._rightGain = this.ac.createGain();\r\n\r\n /**\r\n * The p5.Delay is built with two\r\n * \r\n * Web Audio Delay Nodes, one for each stereo channel.\r\n *\r\n * @property {DelayNode} leftDelay\r\n */\r\n this.leftDelay = this.ac.createDelay();\r\n /**\r\n * The p5.Delay is built with two\r\n * \r\n * Web Audio Delay Nodes, one for each stereo channel.\r\n *\r\n * @property {DelayNode} rightDelay\r\n */\r\n this.rightDelay = this.ac.createDelay();\r\n\r\n this._leftFilter = new Filter();\r\n this._rightFilter = new Filter();\r\n this._leftFilter.disconnect();\r\n this._rightFilter.disconnect();\r\n\r\n this._leftFilter.biquad.frequency.setValueAtTime(1200, this.ac.currentTime);\r\n this._rightFilter.biquad.frequency.setValueAtTime(1200, this.ac.currentTime);\r\n this._leftFilter.biquad.Q.setValueAtTime(0.3, this.ac.currentTime);\r\n this._rightFilter.biquad.Q.setValueAtTime(0.3, this.ac.currentTime);\r\n\r\n // graph routing\r\n this.input.connect(this._split);\r\n this.leftDelay.connect(this._leftGain);\r\n this.rightDelay.connect(this._rightGain);\r\n this._leftGain.connect(this._leftFilter.input);\r\n this._rightGain.connect(this._rightFilter.input);\r\n this._merge.connect(this.wet);\r\n\r\n\r\n this._leftFilter.biquad.gain.setValueAtTime(1, this.ac.currentTime);\r\n this._rightFilter.biquad.gain.setValueAtTime(1, this.ac.currentTime);\r\n\r\n // default routing\r\n this.setType(0);\r\n\r\n this._maxDelay = this.leftDelay.delayTime.maxValue;\r\n\r\n // set initial feedback to 0.5\r\n this.feedback(0.5);\r\n\r\n\r\n };\r\n\r\n p5.Delay.prototype = Object.create(Effect.prototype);\r\n /**\r\n * Add delay to an audio signal according to a set\r\n * of delay parameters.\r\n *\r\n * @method process\r\n * @for p5.Delay\r\n * @param {Object} Signal An object that outputs audio\r\n * @param {Number} [delayTime] Time (in seconds) of the delay/echo.\r\n * Some browsers limit delayTime to\r\n * 1 second.\r\n * @param {Number} [feedback] sends the delay back through itself\r\n * in a loop that decreases in volume\r\n * each time.\r\n * @param {Number} [lowPass] Cutoff frequency. Only frequencies\r\n * below the lowPass will be part of the\r\n * delay.\r\n */\r\n p5.Delay.prototype.process = function(src, _delayTime, _feedback, _filter) {\r\n var feedback = _feedback || 0;\r\n var delayTime = _delayTime || 0;\r\n if (feedback >= 1.0) {\r\n throw new Error('Feedback value will force a positive feedback loop.');\r\n }\r\n if (delayTime >= this._maxDelay) {\r\n throw new Error('Delay Time exceeds maximum delay time of ' + this._maxDelay + ' second.');\r\n }\r\n\r\n src.connect(this.input);\r\n this.leftDelay.delayTime.setValueAtTime(delayTime, this.ac.currentTime);\r\n this.rightDelay.delayTime.setValueAtTime(delayTime, this.ac.currentTime);\r\n this._leftGain.gain.value = feedback;\r\n this._rightGain.gain.value = feedback;\r\n\r\n if (_filter) {\r\n this._leftFilter.freq(_filter);\r\n this._rightFilter.freq(_filter);\r\n }\r\n };\r\n\r\n /**\r\n * Set the delay (echo) time, in seconds. Usually this value will be\r\n * a floating point number between 0.0 and 1.0.\r\n *\r\n * @method delayTime\r\n * @for p5.Delay\r\n * @param {Number} delayTime Time (in seconds) of the delay\r\n */\r\n p5.Delay.prototype.delayTime = function(t) {\r\n // if t is an audio node...\r\n if (typeof t !== 'number') {\r\n t.connect(this.leftDelay.delayTime);\r\n t.connect(this.rightDelay.delayTime);\r\n }\r\n\r\n else {\r\n this.leftDelay.delayTime.cancelScheduledValues(this.ac.currentTime);\r\n this.rightDelay.delayTime.cancelScheduledValues(this.ac.currentTime);\r\n this.leftDelay.delayTime.linearRampToValueAtTime(t, this.ac.currentTime);\r\n this.rightDelay.delayTime.linearRampToValueAtTime(t, this.ac.currentTime);\r\n }\r\n };\r\n\r\n /**\r\n * Feedback occurs when Delay sends its signal back through its input\r\n * in a loop. The feedback amount determines how much signal to send each\r\n * time through the loop. A feedback greater than 1.0 is not desirable because\r\n * it will increase the overall output each time through the loop,\r\n * creating an infinite feedback loop. The default value is 0.5\r\n *\r\n * @method feedback\r\n * @for p5.Delay\r\n * @param {Number|Object} feedback 0.0 to 1.0, or an object such as an\r\n * Oscillator that can be used to\r\n * modulate this param\r\n * @returns {Number} Feedback value\r\n *\r\n */\r\n p5.Delay.prototype.feedback = function(f) {\r\n // if f is an audio node...\r\n if (f && typeof f !== 'number') {\r\n f.connect(this._leftGain.gain);\r\n f.connect(this._rightGain.gain);\r\n }\r\n else if (f >= 1.0) {\r\n throw new Error('Feedback value will force a positive feedback loop.');\r\n }\r\n else if (typeof f === 'number') {\r\n this._leftGain.gain.value = f;\r\n this._rightGain.gain.value = f;\r\n }\r\n\r\n // return value of feedback\r\n return this._leftGain.gain.value;\r\n };\r\n\r\n /**\r\n * Set a lowpass filter frequency for the delay. A lowpass filter\r\n * will cut off any frequencies higher than the filter frequency.\r\n *\r\n * @method filter\r\n * @for p5.Delay\r\n * @param {Number|Object} cutoffFreq A lowpass filter will cut off any\r\n * frequencies higher than the filter frequency.\r\n * @param {Number|Object} res Resonance of the filter frequency\r\n * cutoff, or an object (i.e. a p5.Oscillator)\r\n * that can be used to modulate this parameter.\r\n * High numbers (i.e. 15) will produce a resonance,\r\n * low numbers (i.e. .2) will produce a slope.\r\n */\r\n p5.Delay.prototype.filter = function(freq, q) {\r\n this._leftFilter.set(freq, q);\r\n this._rightFilter.set(freq, q);\r\n };\r\n\r\n\r\n /**\r\n * Choose a preset type of delay. 'pingPong' bounces the signal\r\n * from the left to the right channel to produce a stereo effect.\r\n * Any other parameter will revert to the default delay setting.\r\n *\r\n * @method setType\r\n * @for p5.Delay\r\n * @param {String|Number} type 'pingPong' (1) or 'default' (0)\r\n */\r\n p5.Delay.prototype.setType = function(t) {\r\n if (t === 1) {\r\n t = 'pingPong';\r\n }\r\n this._split.disconnect();\r\n this._leftFilter.disconnect();\r\n this._rightFilter.disconnect();\r\n this._split.connect(this.leftDelay, 0);\r\n this._split.connect(this.rightDelay, 1);\r\n switch(t) {\r\n case 'pingPong':\r\n this._rightFilter.setType( this._leftFilter.biquad.type );\r\n this._leftFilter.output.connect(this._merge, 0, 0);\r\n this._rightFilter.output.connect(this._merge, 0, 1);\r\n this._leftFilter.output.connect(this.rightDelay);\r\n this._rightFilter.output.connect(this.leftDelay);\r\n break;\r\n default:\r\n this._leftFilter.output.connect(this._merge, 0, 0);\r\n this._rightFilter.output.connect(this._merge, 0, 1);\r\n this._leftFilter.output.connect(this.leftDelay);\r\n this._rightFilter.output.connect(this.rightDelay);\r\n }\r\n };\r\n\r\n // DocBlocks for methods inherited from p5.Effect\r\n /**\r\n * Set the output level of the delay effect.\r\n *\r\n * @method amp\r\n * @for p5.Delay\r\n * @param {Number} volume amplitude between 0 and 1.0\r\n * @param {Number} [rampTime] create a fade that lasts rampTime\r\n * @param {Number} [timeFromNow] schedule this event to happen\r\n * seconds from now\r\n */\r\n /**\r\n * Send output to a p5.sound or web audio object\r\n *\r\n * @method connect\r\n * @for p5.Delay\r\n * @param {Object} unit\r\n */\r\n /**\r\n * Disconnect all output.\r\n *\r\n * @method disconnect\r\n * @for p5.Delay\r\n */\r\n\r\n p5.Delay.prototype.dispose = function() {\r\n\r\n Effect.prototype.dispose.apply(this);\r\n\r\n this._split.disconnect();\r\n this._leftFilter.dispose();\r\n this._rightFilter.dispose();\r\n this._merge.disconnect();\r\n this._leftGain.disconnect();\r\n this._rightGain.disconnect();\r\n this.leftDelay.disconnect();\r\n this.rightDelay.disconnect();\r\n\r\n this._split = undefined;\r\n this._leftFilter = undefined;\r\n this._rightFilter = undefined;\r\n this._merge = undefined;\r\n this._leftGain = undefined;\r\n this._rightGain = undefined;\r\n this.leftDelay = undefined;\r\n this.rightDelay = undefined;\r\n };\r\n\r\n});\r\n","'use strict';\r\n\r\ndefine(function (require) {\r\n var CustomError = require('errorHandler');\r\n var Effect = require('effect');\r\n\r\n /**\r\n * Reverb adds depth to a sound through a large number of decaying\r\n * echoes. It creates the perception that sound is occurring in a\r\n * physical space. The p5.Reverb has paramters for Time (how long does the\r\n * reverb last) and decayRate (how much the sound decays with each echo)\r\n * that can be set with the .set() or .process() methods. The p5.Convolver\r\n * extends p5.Reverb allowing you to recreate the sound of actual physical\r\n * spaces through convolution.\r\n *\r\n * This class extends p5.Effect.\r\n * Methods amp(), chain(),\r\n * drywet(), connect(), and\r\n * disconnect() are available.\r\n *\r\n * @class p5.Reverb\r\n * @extends p5.Effect\r\n * @constructor\r\n * @example\r\n *
\r\n * var soundFile, reverb;\r\n * function preload() {\r\n * soundFile = loadSound('assets/Damscray_DancingTiger.mp3');\r\n * }\r\n *\r\n * function setup() {\r\n * reverb = new p5.Reverb();\r\n * soundFile.disconnect(); // so we'll only hear reverb...\r\n *\r\n * // connect soundFile to reverb, process w/\r\n * // 3 second reverbTime, decayRate of 2%\r\n * reverb.process(soundFile, 3, 2);\r\n * soundFile.play();\r\n * }\r\n *
\r\n */\r\n\r\n\r\n p5.Reverb = function() {\r\n Effect.call(this);\r\n\r\n this._initConvolverNode();\r\n\r\n // otherwise, Safari distorts\r\n this.input.gain.value = 0.5;\r\n\r\n // default params\r\n this._seconds = 3;\r\n this._decay = 2;\r\n this._reverse = false;\r\n\r\n this._buildImpulse();\r\n\r\n };\r\n\r\n p5.Reverb.prototype = Object.create(Effect.prototype);\r\n\r\n p5.Reverb.prototype._initConvolverNode = function() {\r\n this.convolverNode = this.ac.createConvolver();\r\n this.input.connect(this.convolverNode);\r\n this.convolverNode.connect(this.wet);\r\n };\r\n\r\n p5.Reverb.prototype._teardownConvolverNode = function() {\r\n if (this.convolverNode) {\r\n this.convolverNode.disconnect();\r\n delete this.convolverNode;\r\n }\r\n };\r\n\r\n p5.Reverb.prototype._setBuffer = function(audioBuffer) {\r\n this._teardownConvolverNode();\r\n this._initConvolverNode();\r\n this.convolverNode.buffer = audioBuffer;\r\n };\r\n /**\r\n * Connect a source to the reverb, and assign reverb parameters.\r\n *\r\n * @method process\r\n * @for p5.Reverb\r\n * @param {Object} src p5.sound / Web Audio object with a sound\r\n * output.\r\n * @param {Number} [seconds] Duration of the reverb, in seconds.\r\n * Min: 0, Max: 10. Defaults to 3.\r\n * @param {Number} [decayRate] Percentage of decay with each echo.\r\n * Min: 0, Max: 100. Defaults to 2.\r\n * @param {Boolean} [reverse] Play the reverb backwards or forwards.\r\n */\r\n p5.Reverb.prototype.process = function(src, seconds, decayRate, reverse) {\r\n src.connect(this.input);\r\n var rebuild = false;\r\n if (seconds) {\r\n this._seconds = seconds;\r\n rebuild = true;\r\n }\r\n if (decayRate) {\r\n this._decay = decayRate;\r\n }\r\n if (reverse) {\r\n this._reverse = reverse;\r\n }\r\n if (rebuild) {\r\n this._buildImpulse();\r\n }\r\n };\r\n\r\n /**\r\n * Set the reverb settings. Similar to .process(), but without\r\n * assigning a new input.\r\n *\r\n * @method set\r\n * @for p5.Reverb\r\n * @param {Number} [seconds] Duration of the reverb, in seconds.\r\n * Min: 0, Max: 10. Defaults to 3.\r\n * @param {Number} [decayRate] Percentage of decay with each echo.\r\n * Min: 0, Max: 100. Defaults to 2.\r\n * @param {Boolean} [reverse] Play the reverb backwards or forwards.\r\n */\r\n p5.Reverb.prototype.set = function(seconds, decayRate, reverse) {\r\n var rebuild = false;\r\n if (seconds) {\r\n this._seconds = seconds;\r\n rebuild = true;\r\n }\r\n if (decayRate) {\r\n this._decay = decayRate;\r\n }\r\n if (reverse) {\r\n this._reverse = reverse;\r\n }\r\n if (rebuild) {\r\n this._buildImpulse();\r\n }\r\n };\r\n\r\n // DocBlocks for methods inherited from p5.Effect\r\n /**\r\n * Set the output level of the reverb effect.\r\n *\r\n * @method amp\r\n * @for p5.Reverb\r\n * @param {Number} volume amplitude between 0 and 1.0\r\n * @param {Number} [rampTime] create a fade that lasts rampTime\r\n * @param {Number} [timeFromNow] schedule this event to happen\r\n * seconds from now\r\n */\r\n /**\r\n * Send output to a p5.sound or web audio object\r\n *\r\n * @method connect\r\n * @for p5.Reverb\r\n * @param {Object} unit\r\n */\r\n /**\r\n * Disconnect all output.\r\n *\r\n * @method disconnect\r\n * @for p5.Reverb\r\n */\r\n\r\n /**\r\n * Inspired by Simple Reverb by Jordan Santell\r\n * https://github.com/web-audio-components/simple-reverb/blob/master/index.js\r\n *\r\n * Utility function for building an impulse response\r\n * based on the module parameters.\r\n *\r\n * @private\r\n */\r\n p5.Reverb.prototype._buildImpulse = function() {\r\n var rate = this.ac.sampleRate;\r\n var length = rate*this._seconds;\r\n var decay = this._decay;\r\n var impulse = this.ac.createBuffer(2, length, rate);\r\n var impulseL = impulse.getChannelData(0);\r\n var impulseR = impulse.getChannelData(1);\r\n var n, i;\r\n for (i = 0; i < length; i++) {\r\n n = this._reverse ? length - i : i;\r\n impulseL[i] = (Math.random() * 2 - 1) * Math.pow(1 - n / length, decay);\r\n impulseR[i] = (Math.random() * 2 - 1) * Math.pow(1 - n / length, decay);\r\n }\r\n this._setBuffer(impulse);\r\n };\r\n\r\n p5.Reverb.prototype.dispose = function() {\r\n Effect.prototype.dispose.apply(this);\r\n this._teardownConvolverNode();\r\n };\r\n\r\n // =======================================================================\r\n // *** p5.Convolver ***\r\n // =======================================================================\r\n\r\n /**\r\n *
p5.Convolver extends p5.Reverb. It can emulate the sound of real\r\n * physical spaces through a process called \r\n * convolution.
\r\n *\r\n *
Convolution multiplies any audio input by an \"impulse response\"\r\n * to simulate the dispersion of sound over time. The impulse response is\r\n * generated from an audio file that you provide. One way to\r\n * generate an impulse response is to pop a balloon in a reverberant space\r\n * and record the echo. Convolution can also be used to experiment with\r\n * sound.
\r\n *\r\n *
Use the method createConvolution(path) to instantiate a\r\n * p5.Convolver with a path to your impulse response audio file.
\r\n *\r\n * @class p5.Convolver\r\n * @extends p5.Effect\r\n * @constructor\r\n * @param {String} path path to a sound file\r\n * @param {Function} [callback] function to call when loading succeeds\r\n * @param {Function} [errorCallback] function to call if loading fails.\r\n * This function will receive an error or\r\n * XMLHttpRequest object with information\r\n * about what went wrong.\r\n * @example\r\n *
\r\n * var cVerb, sound;\r\n * function preload() {\r\n * // We have both MP3 and OGG versions of all sound assets\r\n * soundFormats('ogg', 'mp3');\r\n *\r\n * // Try replacing 'bx-spring' with other soundfiles like\r\n * // 'concrete-tunnel' 'small-plate' 'drum' 'beatbox'\r\n * cVerb = createConvolver('assets/bx-spring.mp3');\r\n *\r\n * // Try replacing 'Damscray_DancingTiger' with\r\n * // 'beat', 'doorbell', lucky_dragons_-_power_melody'\r\n * sound = loadSound('assets/Damscray_DancingTiger.mp3');\r\n * }\r\n *\r\n * function setup() {\r\n * // disconnect from master output...\r\n * sound.disconnect();\r\n *\r\n * // ...and process with cVerb\r\n * // so that we only hear the convolution\r\n * cVerb.process(sound);\r\n *\r\n * sound.play();\r\n * }\r\n *
\r\n */\r\n p5.Convolver = function(path, callback, errorCallback) {\r\n \t p5.Reverb.call(this);\r\n\r\n /**\r\n * Internally, the p5.Convolver uses the a\r\n * \r\n * Web Audio Convolver Node.\r\n *\r\n * @property {ConvolverNode} convolverNode\r\n */\r\n this._initConvolverNode();\r\n\r\n // otherwise, Safari distorts\r\n this.input.gain.value = 0.5;\r\n\r\n if (path) {\r\n this.impulses = [];\r\n this._loadBuffer(path, callback, errorCallback);\r\n }\r\n else {\r\n // parameters\r\n this._seconds = 3;\r\n this._decay = 2;\r\n this._reverse = false;\r\n\r\n this._buildImpulse();\r\n }\r\n\r\n };\r\n\r\n p5.Convolver.prototype = Object.create(p5.Reverb.prototype);\r\n\r\n p5.prototype.registerPreloadMethod('createConvolver', p5.prototype);\r\n\r\n /**\r\n * Create a p5.Convolver. Accepts a path to a soundfile\r\n * that will be used to generate an impulse response.\r\n *\r\n * @method createConvolver\r\n * @for p5\r\n * @param {String} path path to a sound file\r\n * @param {Function} [callback] function to call if loading is successful.\r\n * The object will be passed in as the argument\r\n * to the callback function.\r\n * @param {Function} [errorCallback] function to call if loading is not successful.\r\n * A custom error will be passed in as the argument\r\n * to the callback function.\r\n * @return {p5.Convolver}\r\n * @example\r\n *
\r\n * var cVerb, sound;\r\n * function preload() {\r\n * // We have both MP3 and OGG versions of all sound assets\r\n * soundFormats('ogg', 'mp3');\r\n *\r\n * // Try replacing 'bx-spring' with other soundfiles like\r\n * // 'concrete-tunnel' 'small-plate' 'drum' 'beatbox'\r\n * cVerb = createConvolver('assets/bx-spring.mp3');\r\n *\r\n * // Try replacing 'Damscray_DancingTiger' with\r\n * // 'beat', 'doorbell', lucky_dragons_-_power_melody'\r\n * sound = loadSound('assets/Damscray_DancingTiger.mp3');\r\n * }\r\n *\r\n * function setup() {\r\n * // disconnect from master output...\r\n * sound.disconnect();\r\n *\r\n * // ...and process with cVerb\r\n * // so that we only hear the convolution\r\n * cVerb.process(sound);\r\n *\r\n * sound.play();\r\n * }\r\n *
\r\n */\r\n p5.prototype.createConvolver = function(path, callback, errorCallback) {\r\n // if loading locally without a server\r\n if (window.location.origin.indexOf('file://') > -1 && window.cordova === 'undefined') {\r\n alert('This sketch may require a server to load external files. Please see http://bit.ly/1qcInwS');\r\n }\r\n var self = this;\r\n var cReverb = new p5.Convolver(path, function(buffer) {\r\n if (typeof callback === 'function') {\r\n callback(buffer);\r\n }\r\n\r\n if (typeof self._decrementPreload === 'function') {\r\n self._decrementPreload();\r\n }\r\n }, errorCallback);\r\n cReverb.impulses = [];\r\n return cReverb;\r\n };\r\n\r\n /**\r\n * Private method to load a buffer as an Impulse Response,\r\n * assign it to the convolverNode, and add to the Array of .impulses.\r\n *\r\n * @param {String} path\r\n * @param {Function} callback\r\n * @param {Function} errorCallback\r\n * @private\r\n */\r\n p5.Convolver.prototype._loadBuffer = function(path, callback, errorCallback) {\r\n var path = p5.prototype._checkFileFormats(path);\r\n var self = this;\r\n var errorTrace = new Error().stack;\r\n var ac = p5.prototype.getAudioContext();\r\n\r\n var request = new XMLHttpRequest();\r\n request.open('GET', path, true);\r\n request.responseType = 'arraybuffer';\r\n\r\n request.onload = function() {\r\n if (request.status === 200) {\r\n // on success loading file:\r\n ac.decodeAudioData(request.response,\r\n function(buff) {\r\n var buffer = {};\r\n var chunks = path.split('/');\r\n buffer.name = chunks[chunks.length - 1];\r\n buffer.audioBuffer = buff;\r\n self.impulses.push(buffer);\r\n self._setBuffer(buffer.audioBuffer);\r\n if (callback) {\r\n callback(buffer);\r\n }\r\n },\r\n // error decoding buffer. \"e\" is undefined in Chrome 11/22/2015\r\n function() {\r\n var err = new CustomError('decodeAudioData', errorTrace, self.url);\r\n var msg = 'AudioContext error at decodeAudioData for ' + self.url;\r\n if (errorCallback) {\r\n err.msg = msg;\r\n errorCallback(err);\r\n } else {\r\n console.error(msg +'\\n The error stack trace includes: \\n' + err.stack);\r\n }\r\n }\r\n );\r\n }\r\n // if request status != 200, it failed\r\n else {\r\n var err = new CustomError('loadConvolver', errorTrace, self.url);\r\n var msg = 'Unable to load ' + self.url +\r\n '. The request status was: ' + request.status + ' (' + request.statusText + ')';\r\n\r\n if (errorCallback) {\r\n err.message = msg;\r\n errorCallback(err);\r\n } else {\r\n console.error(msg +'\\n The error stack trace includes: \\n' + err.stack);\r\n }\r\n }\r\n };\r\n\r\n // if there is another error, aside from 404...\r\n request.onerror = function() {\r\n var err = new CustomError('loadConvolver', errorTrace, self.url);\r\n var msg = 'There was no response from the server at ' + self.url + '. Check the url and internet connectivity.';\r\n\r\n if (errorCallback) {\r\n err.message = msg;\r\n errorCallback(err);\r\n } else {\r\n console.error(msg +'\\n The error stack trace includes: \\n' + err.stack);\r\n }\r\n };\r\n request.send();\r\n };\r\n\r\n p5.Convolver.prototype.set = null;\r\n\r\n /**\r\n * Connect a source to the reverb, and assign reverb parameters.\r\n *\r\n * @method process\r\n * @for p5.Convolver\r\n * @param {Object} src p5.sound / Web Audio object with a sound\r\n * output.\r\n * @example\r\n *
\r\n * var cVerb, sound;\r\n * function preload() {\r\n * soundFormats('ogg', 'mp3');\r\n *\r\n * cVerb = createConvolver('assets/concrete-tunnel.mp3');\r\n *\r\n * sound = loadSound('assets/beat.mp3');\r\n * }\r\n *\r\n * function setup() {\r\n * // disconnect from master output...\r\n * sound.disconnect();\r\n *\r\n * // ...and process with (i.e. connect to) cVerb\r\n * // so that we only hear the convolution\r\n * cVerb.process(sound);\r\n *\r\n * sound.play();\r\n * }\r\n *
\r\n */\r\n p5.Convolver.prototype.process = function(src) {\r\n src.connect(this.input);\r\n };\r\n\r\n /**\r\n * If you load multiple impulse files using the .addImpulse method,\r\n * they will be stored as Objects in this Array. Toggle between them\r\n * with the toggleImpulse(id) method.\r\n *\r\n * @property {Array} impulses\r\n * @for p5.Convolver\r\n */\r\n p5.Convolver.prototype.impulses = [];\r\n\r\n /**\r\n * Load and assign a new Impulse Response to the p5.Convolver.\r\n * The impulse is added to the .impulses array. Previous\r\n * impulses can be accessed with the .toggleImpulse(id)\r\n * method.\r\n *\r\n * @method addImpulse\r\n * @for p5.Convolver\r\n * @param {String} path path to a sound file\r\n * @param {Function} callback function (optional)\r\n * @param {Function} errorCallback function (optional)\r\n */\r\n p5.Convolver.prototype.addImpulse = function(path, callback, errorCallback) {\r\n // if loading locally without a server\r\n if (window.location.origin.indexOf('file://') > -1 && window.cordova === 'undefined') {\r\n alert('This sketch may require a server to load external files. Please see http://bit.ly/1qcInwS');\r\n }\r\n this._loadBuffer(path, callback, errorCallback);\r\n };\r\n\r\n /**\r\n * Similar to .addImpulse, except that the .impulses\r\n * Array is reset to save memory. A new .impulses\r\n * array is created with this impulse as the only item.\r\n *\r\n * @method resetImpulse\r\n * @for p5.Convolver\r\n * @param {String} path path to a sound file\r\n * @param {Function} callback function (optional)\r\n * @param {Function} errorCallback function (optional)\r\n */\r\n p5.Convolver.prototype.resetImpulse = function(path, callback, errorCallback) {\r\n // if loading locally without a server\r\n if (window.location.origin.indexOf('file://') > -1 && window.cordova === 'undefined') {\r\n alert('This sketch may require a server to load external files. Please see http://bit.ly/1qcInwS');\r\n }\r\n this.impulses = [];\r\n this._loadBuffer(path, callback, errorCallback);\r\n };\r\n\r\n /**\r\n * If you have used .addImpulse() to add multiple impulses\r\n * to a p5.Convolver, then you can use this method to toggle between\r\n * the items in the .impulses Array. Accepts a parameter\r\n * to identify which impulse you wish to use, identified either by its\r\n * original filename (String) or by its position in the .impulses\r\n * Array (Number). \r\n * You can access the objects in the .impulses Array directly. Each\r\n * Object has two attributes: an .audioBuffer (type:\r\n * Web Audio \r\n * AudioBuffer) and a .name, a String that corresponds\r\n * with the original filename.\r\n *\r\n * @method toggleImpulse\r\n * @for p5.Convolver\r\n * @param {String|Number} id Identify the impulse by its original filename\r\n * (String), or by its position in the\r\n * .impulses Array (Number).\r\n */\r\n p5.Convolver.prototype.toggleImpulse = function(id) {\r\n if (typeof id === 'number' && id < this.impulses.length) {\r\n this._setBuffer(this.impulses[id].audioBuffer);\r\n }\r\n if (typeof id === 'string') {\r\n for (var i = 0; i < this.impulses.length; i++) {\r\n if (this.impulses[i].name === id) {\r\n this._setBuffer(this.impulses[i].audioBuffer);\r\n break;\r\n }\r\n }\r\n }\r\n };\r\n\r\n p5.Convolver.prototype.dispose = function() {\r\n p5.Reverb.prototype.dispose.apply(this);\r\n\r\n // remove all the Impulse Response buffers\r\n for (var i in this.impulses) {\r\n if (this.impulses[i]) {\r\n this.impulses[i] = null;\r\n }\r\n }\r\n };\r\n\r\n});\r\n","'use strict';\r\n\r\ndefine(function (require) {\r\n var p5sound = require('master');\r\n\r\n // requires the Tone.js library's Clock (MIT license, Yotam Mann)\r\n // https://github.com/TONEnoTONE/Tone.js/\r\n var Clock = require('Tone/core/Clock');\r\n\r\n p5.Metro = function() {\r\n this.clock = new Clock({\r\n 'callback': this.ontick.bind(this)\r\n });\r\n this.syncedParts = [];\r\n this.bpm = 120; // gets overridden by p5.Part\r\n this._init();\r\n\r\n this.prevTick = 0;\r\n this.tatumTime = 0;\r\n\r\n this.tickCallback = function() {};\r\n };\r\n\r\n p5.Metro.prototype.ontick = function(tickTime) {\r\n var elapsedTime = tickTime - this.prevTick;\r\n var secondsFromNow = tickTime - p5sound.audiocontext.currentTime;\r\n if (elapsedTime - this.tatumTime <= -0.02) {\r\n return;\r\n } else {\r\n // console.log('ok', this.syncedParts[0].phrases[0].name);\r\n this.prevTick = tickTime;\r\n\r\n // for all of the active things on the metro:\r\n var self = this;\r\n this.syncedParts.forEach(function(thisPart) {\r\n if (!thisPart.isPlaying) return;\r\n thisPart.incrementStep(secondsFromNow);\r\n // each synced source keeps track of its own beat number\r\n thisPart.phrases.forEach(function(thisPhrase) {\r\n var phraseArray = thisPhrase.sequence;\r\n var bNum = self.metroTicks % phraseArray.length;\r\n if (phraseArray[bNum] !== 0 && (self.metroTicks < phraseArray.length || !thisPhrase.looping) ) {\r\n thisPhrase.callback(secondsFromNow, phraseArray[bNum]);\r\n }\r\n });\r\n });\r\n this.metroTicks += 1;\r\n this.tickCallback(secondsFromNow);\r\n }\r\n };\r\n\r\n p5.Metro.prototype.setBPM = function(bpm, rampTime) {\r\n var beatTime = 60 / (bpm*this.tatums);\r\n var now = p5sound.audiocontext.currentTime;\r\n this.tatumTime = beatTime;\r\n\r\n var rampTime = rampTime || 0;\r\n this.clock.frequency.setValueAtTime(this.clock.frequency.value, now);\r\n this.clock.frequency.linearRampToValueAtTime(bpm, now + rampTime);\r\n this.bpm = bpm;\r\n };\r\n\r\n p5.Metro.prototype.getBPM = function() {\r\n return this.clock.getRate() / this.tatums * 60;\r\n };\r\n\r\n p5.Metro.prototype._init = function() {\r\n this.metroTicks = 0;\r\n // this.setBPM(120);\r\n };\r\n\r\n // clear existing synced parts, add only this one\r\n p5.Metro.prototype.resetSync = function(part) {\r\n this.syncedParts = [part];\r\n };\r\n\r\n // push a new synced part to the array\r\n p5.Metro.prototype.pushSync = function(part) {\r\n this.syncedParts.push(part);\r\n };\r\n\r\n p5.Metro.prototype.start = function(timeFromNow) {\r\n var t = timeFromNow || 0;\r\n var now = p5sound.audiocontext.currentTime;\r\n this.clock.start(now + t);\r\n this.setBPM(this.bpm);\r\n };\r\n\r\n p5.Metro.prototype.stop = function(timeFromNow) {\r\n var t = timeFromNow || 0;\r\n var now = p5sound.audiocontext.currentTime;\r\n this.clock.stop(now + t);\r\n };\r\n\r\n p5.Metro.prototype.beatLength = function(tatums) {\r\n this.tatums = 1/tatums / 4; // lowest possible division of a beat\r\n };\r\n\r\n});\r\n","define([\"Tone/core/Tone\", \"Tone/core/Timeline\", \"Tone/type/Type\"], function (Tone) {\n\n\t\"use strict\";\n\n\t/**\n\t * @class A Timeline State. Provides the methods: setStateAtTime(\"state\", time)\n\t * and getValueAtTime(time).\n\t *\n\t * @extends {Tone.Timeline}\n\t * @param {String} initial The initial state of the TimelineState. \n\t * Defaults to undefined\n\t */\n\tTone.TimelineState = function(initial){\n\n\t\tTone.Timeline.call(this);\n\n\t\t/**\n\t\t * The initial state\n\t\t * @private\n\t\t * @type {String}\n\t\t */\n\t\tthis._initial = initial;\n\t};\n\n\tTone.extend(Tone.TimelineState, Tone.Timeline);\n\n\t/**\n\t * Returns the scheduled state scheduled before or at\n\t * the given time.\n\t * @param {Number} time The time to query.\n\t * @return {String} The name of the state input in setStateAtTime.\n\t */\n\tTone.TimelineState.prototype.getValueAtTime = function(time){\n\t\tvar event = this.get(time);\n\t\tif (event !== null){\n\t\t\treturn event.state;\n\t\t} else {\n\t\t\treturn this._initial;\n\t\t}\n\t};\n\n\t/**\n\t * Returns the scheduled state scheduled before or at\n\t * the given time.\n\t * @param {String} state The name of the state to set.\n\t * @param {Number} time The time to query.\n\t */\n\tTone.TimelineState.prototype.setStateAtTime = function(state, time){\n\t\tthis.add({\n\t\t\t\"state\" : state,\n\t\t\t\"time\" : time\n\t\t});\n\t};\n\n\treturn Tone.TimelineState;\n});","'use strict';\r\n\r\ndefine(function(require) {\r\n var p5sound = require('master');\r\n\r\n var BPM = 120;\r\n\r\n /**\r\n * Set the global tempo, in beats per minute, for all\r\n * p5.Parts. This method will impact all active p5.Parts.\r\n *\r\n * @method setBPM\r\n * @for p5\r\n * @param {Number} BPM Beats Per Minute\r\n * @param {Number} rampTime Seconds from now\r\n */\r\n p5.prototype.setBPM = function(bpm, rampTime) {\r\n BPM = bpm;\r\n for (var i in p5sound.parts) {\r\n if (p5sound.parts[i]) {\r\n p5sound.parts[i].setBPM(bpm, rampTime);\r\n }\r\n }\r\n };\r\n\r\n /**\r\n *
A phrase is a pattern of musical events over time, i.e.\r\n * a series of notes and rests.
\r\n *\r\n *
Phrases must be added to a p5.Part for playback, and\r\n * each part can play multiple phrases at the same time.\r\n * For example, one Phrase might be a kick drum, another\r\n * could be a snare, and another could be the bassline.
\r\n *\r\n *
The first parameter is a name so that the phrase can be\r\n * modified or deleted later. The callback is a a function that\r\n * this phrase will call at every step—for example it might be\r\n * called playNote(value){}. The array determines\r\n * which value is passed into the callback at each step of the\r\n * phrase. It can be numbers, an object with multiple numbers,\r\n * or a zero (0) indicates a rest so the callback won't be called).
\r\n *\r\n * @class p5.Phrase\r\n * @constructor\r\n * @param {String} name Name so that you can access the Phrase.\r\n * @param {Function} callback The name of a function that this phrase\r\n * will call. Typically it will play a sound,\r\n * and accept two parameters: a time at which\r\n * to play the sound (in seconds from now),\r\n * and a value from the sequence array. The\r\n * time should be passed into the play() or\r\n * start() method to ensure precision.\r\n * @param {Array} sequence Array of values to pass into the callback\r\n * at each step of the phrase.\r\n * @example\r\n *
\r\n */\r\n p5.Phrase = function(name, callback, sequence) {\r\n this.phraseStep = 0;\r\n this.name = name;\r\n this.callback = callback;\r\n /**\r\n * Array of values to pass into the callback\r\n * at each step of the phrase. Depending on the callback\r\n * function's requirements, these values may be numbers,\r\n * strings, or an object with multiple parameters.\r\n * Zero (0) indicates a rest.\r\n *\r\n * @property {Array} sequence\r\n */\r\n this.sequence = sequence;\r\n };\r\n\r\n /**\r\n *
A p5.Part plays back one or more p5.Phrases. Instantiate a part\r\n * with steps and tatums. By default, each step represents a 1/16th note.
\r\n *\r\n *
See p5.Phrase for more about musical timing.
\r\n *\r\n * @class p5.Part\r\n * @constructor\r\n * @param {Number} [steps] Steps in the part\r\n * @param {Number} [tatums] Divisions of a beat, e.g. use 1/4, or 0.25 for a quater note (default is 1/16, a sixteenth note)\r\n * @example\r\n *
\r\n * var box, drum, myPart;\r\n * var boxPat = [1,0,0,2,0,2,0,0];\r\n * var drumPat = [0,1,1,0,2,0,1,0];\r\n * var msg = 'click to play';\r\n *\r\n * function preload() {\r\n * box = loadSound('assets/beatbox.mp3');\r\n * drum = loadSound('assets/drum.mp3');\r\n * }\r\n *\r\n * function setup() {\r\n * noStroke();\r\n * fill(255);\r\n * textAlign(CENTER);\r\n * masterVolume(0.1);\r\n *\r\n * var boxPhrase = new p5.Phrase('box', playBox, boxPat);\r\n * var drumPhrase = new p5.Phrase('drum', playDrum, drumPat);\r\n * myPart = new p5.Part();\r\n * myPart.addPhrase(boxPhrase);\r\n * myPart.addPhrase(drumPhrase);\r\n * myPart.setBPM(60);\r\n * masterVolume(0.1);\r\n * }\r\n *\r\n * function draw() {\r\n * background(0);\r\n * text(msg, width/2, height/2);\r\n * }\r\n *\r\n * function playBox(time, playbackRate) {\r\n * box.rate(playbackRate);\r\n * box.play(time);\r\n * }\r\n *\r\n * function playDrum(time, playbackRate) {\r\n * drum.rate(playbackRate);\r\n * drum.play(time);\r\n * }\r\n *\r\n * function mouseClicked() {\r\n * if (mouseX > 0 && mouseX < width && mouseY > 0 && mouseY < height) {\r\n * myPart.start();\r\n * msg = 'playing part';\r\n * }\r\n * }\r\n *
\r\n */\r\n p5.Part = function(steps, bLength) {\r\n this.length = steps || 0; // how many beats\r\n this.partStep = 0;\r\n this.phrases = [];\r\n this.isPlaying = false;\r\n this.noLoop();\r\n this.tatums = bLength || 0.0625; // defaults to quarter note\r\n\r\n this.metro = new p5.Metro();\r\n this.metro._init();\r\n this.metro.beatLength(this.tatums);\r\n this.metro.setBPM(BPM);\r\n p5sound.parts.push(this);\r\n this.callback = function() {};\r\n };\r\n\r\n /**\r\n * Set the tempo of this part, in Beats Per Minute.\r\n *\r\n * @method setBPM\r\n * @for p5.Part\r\n * @param {Number} BPM Beats Per Minute\r\n * @param {Number} [rampTime] Seconds from now\r\n */\r\n p5.Part.prototype.setBPM = function(tempo, rampTime) {\r\n this.metro.setBPM(tempo, rampTime);\r\n };\r\n\r\n /**\r\n * Returns the tempo, in Beats Per Minute, of this part.\r\n *\r\n * @method getBPM\r\n * @for p5.Part\r\n * @return {Number}\r\n */\r\n p5.Part.prototype.getBPM = function() {\r\n return this.metro.getBPM();\r\n };\r\n\r\n /**\r\n * Start playback of this part. It will play\r\n * through all of its phrases at a speed\r\n * determined by setBPM.\r\n *\r\n * @method start\r\n * @for p5.Part\r\n * @param {Number} [time] seconds from now\r\n */\r\n p5.Part.prototype.start = function(time) {\r\n if (!this.isPlaying) {\r\n this.isPlaying = true;\r\n this.metro.resetSync(this);\r\n var t = time || 0;\r\n this.metro.start(t);\r\n }\r\n };\r\n\r\n /**\r\n * Loop playback of this part. It will begin\r\n * looping through all of its phrases at a speed\r\n * determined by setBPM.\r\n *\r\n * @method loop\r\n * @for p5.Part\r\n * @param {Number} [time] seconds from now\r\n */\r\n p5.Part.prototype.loop = function(time) {\r\n this.looping = true;\r\n // rest onended function\r\n this.onended = function() {\r\n this.partStep = 0;\r\n };\r\n var t = time || 0;\r\n this.start(t);\r\n };\r\n\r\n /**\r\n * Tell the part to stop looping.\r\n *\r\n * @method noLoop\r\n * @for p5.Part\r\n */\r\n p5.Part.prototype.noLoop = function() {\r\n this.looping = false;\r\n // rest onended function\r\n this.onended = function() {\r\n this.stop();\r\n };\r\n };\r\n\r\n /**\r\n * Stop the part and cue it to step 0. Playback will resume from the begining of the Part when it is played again.\r\n *\r\n * @method stop\r\n * @for p5.Part\r\n * @param {Number} [time] seconds from now\r\n */\r\n p5.Part.prototype.stop = function(time) {\r\n this.partStep = 0;\r\n this.pause(time);\r\n };\r\n\r\n /**\r\n * Pause the part. Playback will resume\r\n * from the current step.\r\n *\r\n * @method pause\r\n * @for p5.Part\r\n * @param {Number} time seconds from now\r\n */\r\n p5.Part.prototype.pause = function(time) {\r\n this.isPlaying = false;\r\n var t = time || 0;\r\n this.metro.stop(t);\r\n };\r\n\r\n /**\r\n * Add a p5.Phrase to this Part.\r\n *\r\n * @method addPhrase\r\n * @for p5.Part\r\n * @param {p5.Phrase} phrase reference to a p5.Phrase\r\n */\r\n p5.Part.prototype.addPhrase = function(name, callback, array) {\r\n var p;\r\n if (arguments.length === 3) {\r\n p = new p5.Phrase(name, callback, array);\r\n } else if (arguments[0] instanceof p5.Phrase) {\r\n p = arguments[0];\r\n } else {\r\n throw 'invalid input. addPhrase accepts name, callback, array or a p5.Phrase';\r\n }\r\n this.phrases.push(p);\r\n // reset the length if phrase is longer than part's existing length\r\n if (p.sequence.length > this.length) {\r\n this.length = p.sequence.length;\r\n }\r\n };\r\n\r\n /**\r\n * Remove a phrase from this part, based on the name it was\r\n * given when it was created.\r\n *\r\n * @method removePhrase\r\n * @for p5.Part\r\n * @param {String} phraseName\r\n */\r\n p5.Part.prototype.removePhrase = function(name) {\r\n for (var i in this.phrases) {\r\n if (this.phrases[i].name === name) {\r\n this.phrases.splice(i, 1);\r\n }\r\n }\r\n };\r\n\r\n /**\r\n * Get a phrase from this part, based on the name it was\r\n * given when it was created. Now you can modify its array.\r\n *\r\n * @method getPhrase\r\n * @for p5.Part\r\n * @param {String} phraseName\r\n */\r\n p5.Part.prototype.getPhrase = function(name) {\r\n for (var i in this.phrases) {\r\n if (this.phrases[i].name === name) {\r\n return this.phrases[i];\r\n }\r\n }\r\n };\r\n\r\n /**\r\n * Find all sequences with the specified name, and replace their patterns with the specified array.\r\n *\r\n * @method replaceSequence\r\n * @for p5.Part\r\n * @param {String} phraseName\r\n * @param {Array} sequence Array of values to pass into the callback\r\n * at each step of the phrase.\r\n */\r\n p5.Part.prototype.replaceSequence = function(name, array) {\r\n for (var i in this.phrases) {\r\n if (this.phrases[i].name === name) {\r\n this.phrases[i].sequence = array;\r\n }\r\n }\r\n };\r\n\r\n p5.Part.prototype.incrementStep = function(time) {\r\n if (this.partStep < this.length - 1) {\r\n this.callback(time);\r\n this.partStep += 1;\r\n } else {\r\n if (!this.looping && this.partStep === this.length - 1) {\r\n console.log('done');\r\n // this.callback(time);\r\n this.onended();\r\n }\r\n }\r\n };\r\n\r\n /**\r\n * Set the function that will be called at every step. This will clear the previous function.\r\n *\r\n * @method onStep\r\n * @for p5.Part\r\n * @param {Function} callback The name of the callback\r\n * you want to fire\r\n * on every beat/tatum.\r\n */\r\n p5.Part.prototype.onStep = function(callback) {\r\n this.callback = callback;\r\n };\r\n\r\n\r\n // ===============\r\n // p5.Score\r\n // ===============\r\n\r\n /**\r\n * A Score consists of a series of Parts. The parts will\r\n * be played back in order. For example, you could have an\r\n * A part, a B part, and a C part, and play them back in this order\r\n * new p5.Score(a, a, b, a, c)\r\n *\r\n * @class p5.Score\r\n * @constructor\r\n * @param {p5.Part} [...parts] One or multiple parts, to be played in sequence.\r\n */\r\n p5.Score = function() {\r\n // for all of the arguments\r\n this.parts = [];\r\n this.currentPart = 0;\r\n\r\n var thisScore = this;\r\n for (var i in arguments) {\r\n if (arguments[i] && this.parts[i]) {\r\n this.parts[i] = arguments[i];\r\n this.parts[i].nextPart = this.parts[i + 1];\r\n this.parts[i].onended = function() {\r\n thisScore.resetPart(i);\r\n playNextPart(thisScore);\r\n };\r\n }\r\n }\r\n this.looping = false;\r\n };\r\n\r\n p5.Score.prototype.onended = function() {\r\n if (this.looping) {\r\n // this.resetParts();\r\n this.parts[0].start();\r\n } else {\r\n this.parts[this.parts.length - 1].onended = function() {\r\n this.stop();\r\n this.resetParts();\r\n };\r\n }\r\n this.currentPart = 0;\r\n };\r\n\r\n /**\r\n * Start playback of the score.\r\n *\r\n * @method start\r\n * @for p5.Score\r\n */\r\n p5.Score.prototype.start = function() {\r\n this.parts[this.currentPart].start();\r\n this.scoreStep = 0;\r\n };\r\n\r\n /**\r\n * Stop playback of the score.\r\n *\r\n * @method stop\r\n * @for p5.Score\r\n */\r\n p5.Score.prototype.stop = function() {\r\n this.parts[this.currentPart].stop();\r\n this.currentPart = 0;\r\n this.scoreStep = 0;\r\n };\r\n\r\n /**\r\n * Pause playback of the score.\r\n *\r\n * @method pause\r\n * @for p5.Score\r\n */\r\n p5.Score.prototype.pause = function() {\r\n this.parts[this.currentPart].stop();\r\n };\r\n\r\n /**\r\n * Loop playback of the score.\r\n *\r\n * @method loop\r\n * @for p5.Score\r\n */\r\n p5.Score.prototype.loop = function() {\r\n this.looping = true;\r\n this.start();\r\n };\r\n\r\n /**\r\n * Stop looping playback of the score. If it\r\n * is currently playing, this will go into effect\r\n * after the current round of playback completes.\r\n *\r\n * @method noLoop\r\n * @for p5.Score\r\n */\r\n p5.Score.prototype.noLoop = function() {\r\n this.looping = false;\r\n };\r\n\r\n p5.Score.prototype.resetParts = function() {\r\n var self = this;\r\n this.parts.forEach(function(part) {\r\n self.resetParts[part];\r\n });\r\n };\r\n\r\n p5.Score.prototype.resetPart = function(i) {\r\n this.parts[i].stop();\r\n this.parts[i].partStep = 0;\r\n for (var p in this.parts[i].phrases) {\r\n if (this.parts[i]) {\r\n this.parts[i].phrases[p].phraseStep = 0;\r\n }\r\n }\r\n };\r\n\r\n /**\r\n * Set the tempo for all parts in the score\r\n *\r\n * @method setBPM\r\n * @for p5.Score\r\n * @param {Number} BPM Beats Per Minute\r\n * @param {Number} rampTime Seconds from now\r\n */\r\n p5.Score.prototype.setBPM = function(bpm, rampTime) {\r\n for (var i in this.parts) {\r\n if (this.parts[i]) {\r\n this.parts[i].setBPM(bpm, rampTime);\r\n }\r\n }\r\n };\r\n\r\n function playNextPart(aScore) {\r\n aScore.currentPart++;\r\n if (aScore.currentPart >= aScore.parts.length) {\r\n aScore.scoreStep = 0;\r\n aScore.onended();\r\n } else {\r\n aScore.scoreStep = 0;\r\n aScore.parts[aScore.currentPart - 1].stop();\r\n aScore.parts[aScore.currentPart].start();\r\n }\r\n }\r\n\r\n});\r\n","'use strict';\r\n\r\ndefine(function (require) {\r\n var p5sound = require('master');\r\n var Clock = require('Tone/core/Clock');\r\n\r\n /**\r\n * SoundLoop\r\n *\r\n * @class p5.SoundLoop\r\n * @constructor\r\n *\r\n * @param {Function} callback this function will be called on each iteration of theloop\r\n * @param {Number|String} [interval] amount of time or beats for each iteration of the loop\r\n * defaults to 1\r\n *\r\n * @example\r\n *
\r\n * var click;\r\n * var looper1;\r\n *\r\n * function preload() {\r\n * click = loadSound('assets/drum.mp3');\r\n * }\r\n *\r\n * function setup() {\r\n * //the looper's callback is passed the timeFromNow\r\n * //this value should be used as a reference point from\r\n * //which to schedule sounds\r\n * looper1 = new p5.SoundLoop(function(timeFromNow){\r\n * click.play(timeFromNow);\r\n * background(255 * (looper1.iterations % 2));\r\n * }, 2);\r\n *\r\n * //stop after 10 iteratios;\r\n * looper1.maxIterations = 10;\r\n * //start the loop\r\n * looper1.start();\r\n * }\r\n *
\r\n */\r\n p5.SoundLoop = function(callback, interval) {\r\n this.callback = callback;\r\n /**\r\n * musicalTimeMode uses Tone.Time convention\r\n\t * true if string, false if number\r\n * @property {Boolean} musicalTimeMode\r\n */\r\n this.musicalTimeMode = typeof this._interval === 'number' ? false : true;\r\n\r\n this._interval = interval || 1;\r\n\r\n /**\r\n * musicalTimeMode variables\r\n * modify these only when the interval is specified in musicalTime format as a string\r\n */\r\n this._timeSignature = 4;\r\n this._bpm = 60;\r\n\r\n this.isPlaying = false;\r\n\r\n /**\r\n * Set a limit to the number of loops to play. defaults to Infinity\r\n * @property {Number} maxIterations\r\n */\r\n this.maxIterations = Infinity;\r\n var self = this;\r\n\r\n this.clock = new Clock({\r\n 'callback' : function(time) {\r\n var timeFromNow = time - p5sound.audiocontext.currentTime;\r\n /**\r\n * Do not initiate the callback if timeFromNow is < 0\r\n * This ususually occurs for a few milliseconds when the page\r\n * is not fully loaded\r\n *\r\n * The callback should only be called until maxIterations is reached\r\n */\r\n if (timeFromNow > 0 && self.iterations <= self.maxIterations) {\r\n self.callback(timeFromNow);}\r\n },\r\n 'frequency' : this._calcFreq()\r\n });\r\n };\r\n\r\n /**\r\n * Start the loop\r\n * @method start\r\n * @for p5.SoundLoop\r\n * @param {Number} [timeFromNow] schedule a starting time\r\n */\r\n p5.SoundLoop.prototype.start = function(timeFromNow) {\r\n var t = timeFromNow || 0;\r\n var now = p5sound.audiocontext.currentTime;\r\n if (!this.isPlaying) {\r\n this.clock.start(now + t);\r\n this.isPlaying = true;\r\n }\r\n };\r\n\r\n /**\r\n * Stop the loop\r\n * @method stop\r\n * @for p5.SoundLoop\r\n * @param {Number} [timeFromNow] schedule a stopping time\r\n */\r\n p5.SoundLoop.prototype.stop = function(timeFromNow) {\r\n var t = timeFromNow || 0;\r\n var now = p5sound.audiocontext.currentTime;\r\n if (this.isPlaying) {\r\n this.clock.stop(now + t);\r\n this.isPlaying = false;\r\n }\r\n };\r\n /**\r\n * Pause the loop\r\n * @method pause\r\n * @for p5.SoundLoop\r\n * @param {Number} [timeFromNow] schedule a pausing time\r\n */\r\n p5.SoundLoop.prototype.pause = function(timeFromNow) {\r\n var t = timeFromNow || 0;\r\n var now = p5sound.audiocontext.currentTime;\r\n if (this.isPlaying) {\r\n this.clock.pause(now + t);\r\n this.isPlaying = false;\r\n }\r\n };\r\n\r\n\r\n /**\r\n * Synchronize loops. Use this method to start two more more loops in synchronization\r\n * or to start a loop in synchronization with a loop that is already playing\r\n * This method will schedule the implicit loop in sync with the explicit master loop\r\n * i.e. loopToStart.syncedStart(loopToSyncWith)\r\n *\r\n * @method syncedStart\r\n * @for p5.SoundLoop\r\n * @param {Object} otherLoop a p5.SoundLoop to sync with\r\n * @param {Number} [timeFromNow] Start the loops in sync after timeFromNow seconds\r\n */\r\n p5.SoundLoop.prototype.syncedStart = function(otherLoop, timeFromNow) {\r\n var t = timeFromNow || 0;\r\n var now = p5sound.audiocontext.currentTime;\r\n\r\n if (!otherLoop.isPlaying) {\r\n otherLoop.clock.start(now + t);\r\n otherLoop.isPlaying = true;\r\n this.clock.start(now + t);\r\n this.isPlaying = true;\r\n } else if (otherLoop.isPlaying) {\r\n var time = otherLoop.clock._nextTick - p5sound.audiocontext.currentTime;\r\n this.clock.start(now + time);\r\n this.isPlaying = true;\r\n }\r\n };\r\n\r\n\r\n /**\r\n * Updates frequency value, reflected in next callback\r\n * @private\r\n * @for p5.SoundLoop\r\n * @method _update\r\n */\r\n p5.SoundLoop.prototype._update = function() {\r\n this.clock.frequency.value = this._calcFreq();\r\n };\r\n\r\n /**\r\n * Calculate the frequency of the clock's callback based on bpm, interval, and timesignature\r\n * @private\r\n * @for p5.SoundLoop\r\n * @method _calcFreq\r\n * @return {Number} new clock frequency value\r\n */\r\n p5.SoundLoop.prototype._calcFreq = function() {\r\n //Seconds mode, bpm / timesignature has no effect\r\n if (typeof this._interval === 'number') {\r\n this.musicalTimeMode = false;\r\n return 1 / this._interval;\r\n }\r\n //Musical timing mode, calculate interval based bpm, interval,and time signature\r\n else if (typeof this._interval === 'string') {\r\n this.musicalTimeMode = true;\r\n return this._bpm / 60 / this._convertNotation(this._interval) * (this._timeSignature / 4);\r\n }\r\n };\r\n\r\n /**\r\n * Convert notation from musical time format to seconds\r\n * Uses Tone.Time convention\r\n * @private\r\n * @for p5.SoundLoop\r\n * @method _convertNotation\r\n * @param {String} value value to be converted\r\n * @return {Number} converted value in seconds\r\n */\r\n p5.SoundLoop.prototype._convertNotation = function(value) {\r\n var type = value.slice(-1);\r\n value = Number(value.slice(0,-1));\r\n switch (type) {\r\n case 'm':\r\n return this._measure(value);\r\n case 'n':\r\n return this._note(value);\r\n default:\r\n console.warn('Specified interval is not formatted correctly. See Tone.js '+\r\n 'timing reference for more info: https://github.com/Tonejs/Tone.js/wiki/Time');\r\n }\r\n };\r\n\r\n /**\r\n * Helper conversion methods of measure and note\r\n * @private\r\n * @for p5.SoundLoop\r\n * @method _measure\r\n */\r\n p5.SoundLoop.prototype._measure = function(value) {\r\n return value * this._timeSignature;\r\n };\r\n\r\n /**\r\n * @private\r\n * @method _note\r\n * @for p5.SoundLoop\r\n */\r\n p5.SoundLoop.prototype._note = function(value) {\r\n return this._timeSignature / value ;\r\n };\r\n\r\n\r\n /**\r\n * Getters and Setters, setting any paramter will result in a change in the clock's\r\n * frequency, that will be reflected after the next callback\r\n * beats per minute (defaults to 60)\r\n * @property {Number} bpm\r\n * @for p5.SoundLoop\r\n */\r\n Object.defineProperty(p5.SoundLoop.prototype, 'bpm', {\r\n get : function() {\r\n return this._bpm;\r\n },\r\n set : function(bpm) {\r\n if (!this.musicalTimeMode) {\r\n console.warn('Changing the BPM in \"seconds\" mode has no effect. '+\r\n 'BPM is only relevant in musicalTimeMode '+\r\n 'when the interval is specified as a string '+\r\n '(\"2n\", \"4n\", \"1m\"...etc)');\r\n }\r\n this._bpm = bpm;\r\n this._update();\r\n }\r\n });\r\n\r\n /**\r\n * number of quarter notes in a measure (defaults to 4)\r\n * @property {Number} timeSignature\r\n * @for p5.SoundLoop\r\n */\r\n Object.defineProperty(p5.SoundLoop.prototype, 'timeSignature', {\r\n get : function() {\r\n return this._timeSignature;\r\n },\r\n set : function(timeSig) {\r\n if (!this.musicalTimeMode) {\r\n console.warn('Changing the timeSignature in \"seconds\" mode has no effect. '+\r\n 'BPM is only relevant in musicalTimeMode '+\r\n 'when the interval is specified as a string '+\r\n '(\"2n\", \"4n\", \"1m\"...etc)');\r\n }\r\n this._timeSignature = timeSig;\r\n this._update();\r\n }\r\n });\r\n\r\n /**\r\n * length of the loops interval\r\n * @property {Number|String} interval\r\n * @for p5.SoundLoop\r\n */\r\n Object.defineProperty(p5.SoundLoop.prototype, 'interval', {\r\n get : function() {\r\n return this._interval;\r\n },\r\n set : function(interval) {\r\n this.musicalTimeMode = typeof interval === 'Number'? false : true;\r\n this._interval = interval;\r\n this._update();\r\n }\r\n });\r\n\r\n /**\r\n * how many times the callback has been called so far\r\n * @property {Number} iterations\r\n * @for p5.SoundLoop\r\n * @readonly\r\n */\r\n Object.defineProperty(p5.SoundLoop.prototype, 'iterations', {\r\n get : function() {\r\n return this.clock.ticks;\r\n }\r\n });\r\n\r\n return p5.SoundLoop;\r\n});\r\n","define(function (require) {\r\n\t'use strict';\r\n\r\n\tvar p5sound = require('master');\r\n\tvar Effect = require('effect');\r\n var CustomError = require('errorHandler');\r\n\r\n /**\r\n * Compressor is an audio effect class that performs dynamics compression\r\n * on an audio input source. This is a very commonly used technique in music\r\n * and sound production. Compression creates an overall louder, richer,\r\n * and fuller sound by lowering the volume of louds and raising that of softs.\r\n * Compression can be used to avoid clipping (sound distortion due to\r\n * peaks in volume) and is especially useful when many sounds are played\r\n * at once. Compression can be used on indivudal sound sources in addition\r\n * to the master output.\r\n *\r\n * This class extends p5.Effect.\r\n * Methods amp(), chain(),\r\n * drywet(), connect(), and\r\n * disconnect() are available.\r\n *\r\n * @class p5.Compressor\r\n * @constructor\r\n * @extends p5.Effect\r\n *\r\n *\r\n */\r\n\tp5.Compressor = function() {\r\n\t\tEffect.call(this);\r\n\r\n /**\r\n * The p5.Compressor is built with a Web Audio Dynamics Compressor Node\r\n * \r\n * @property {AudioNode} compressor\r\n */\r\n\r\n\r\n\t\tthis.compressor = this.ac.createDynamicsCompressor();\r\n\r\n this.input.connect(this.compressor);\r\n this.compressor.connect(this.wet);\r\n\t};\r\n\r\n\tp5.Compressor.prototype = Object.create(Effect.prototype);\r\n\r\n /**\r\n * Performs the same function as .connect, but also accepts\r\n * optional parameters to set compressor's audioParams\r\n * @method process\r\n * @for p5.Compressor\r\n *\r\n * @param {Object} src Sound source to be connected\r\n *\r\n * @param {Number} [attack] The amount of time (in seconds) to reduce the gain by 10dB,\r\n * default = .003, range 0 - 1\r\n * @param {Number} [knee] A decibel value representing the range above the\r\n * threshold where the curve smoothly transitions to the \"ratio\" portion.\r\n * default = 30, range 0 - 40\r\n * @param {Number} [ratio] The amount of dB change in input for a 1 dB change in output\r\n * default = 12, range 1 - 20\r\n * @param {Number} [threshold] The decibel value above which the compression will start taking effect\r\n * default = -24, range -100 - 0\r\n * @param {Number} [release] The amount of time (in seconds) to increase the gain by 10dB\r\n * default = .25, range 0 - 1\r\n */\r\n\tp5.Compressor.prototype.process = function(src, attack, knee,\r\n ratio, threshold, release) {\r\n\t\tsrc.connect(this.input);\r\n\t\tthis.set(attack, knee, ratio, threshold, release);\r\n\t};\r\n\r\n /**\r\n * Set the paramters of a compressor.\r\n * @method set\r\n * @for p5.Compressor\r\n * @param {Number} attack The amount of time (in seconds) to reduce the gain by 10dB,\r\n * default = .003, range 0 - 1\r\n * @param {Number} knee A decibel value representing the range above the\r\n * threshold where the curve smoothly transitions to the \"ratio\" portion.\r\n * default = 30, range 0 - 40\r\n * @param {Number} ratio The amount of dB change in input for a 1 dB change in output\r\n * default = 12, range 1 - 20\r\n * @param {Number} threshold The decibel value above which the compression will start taking effect\r\n * default = -24, range -100 - 0\r\n * @param {Number} release The amount of time (in seconds) to increase the gain by 10dB\r\n * default = .25, range 0 - 1\r\n */\r\n p5.Compressor.prototype.set = function (attack, knee,\r\n ratio, threshold, release) {\r\n\r\n if (typeof attack !== 'undefined') {this.attack(attack);}\r\n if (typeof knee !== 'undefined') {this.knee(knee);}\r\n if (typeof ratio !== 'undefined') {this.ratio(ratio);}\r\n if (typeof threshold !== 'undefined') {this.threshold(threshold);}\r\n if (typeof release !== 'undefined') {this.release(release);}\r\n };\r\n\r\n\r\n /**\r\n * Get current attack or set value w/ time ramp\r\n *\r\n *\r\n * @method attack\r\n * @for p5.Compressor\r\n * @param {Number} [attack] Attack is the amount of time (in seconds) to reduce the gain by 10dB,\r\n * default = .003, range 0 - 1\r\n * @param {Number} [time] Assign time value to schedule the change in value\r\n */\r\n p5.Compressor.prototype.attack = function (attack, time){\r\n var t = time || 0;\r\n if (typeof attack == 'number'){\r\n this.compressor.attack.value = attack;\r\n this.compressor.attack.cancelScheduledValues(this.ac.currentTime + 0.01 + t);\r\n this.compressor.attack.linearRampToValueAtTime(attack, this.ac.currentTime + 0.02 + t);\r\n } else if (typeof attack !== 'undefined') {\r\n attack.connect(this.compressor.attack);\r\n }\r\n return this.compressor.attack.value;\r\n };\r\n\r\n\r\n /**\r\n * Get current knee or set value w/ time ramp\r\n *\r\n * @method knee\r\n * @for p5.Compressor\r\n * @param {Number} [knee] A decibel value representing the range above the\r\n * threshold where the curve smoothly transitions to the \"ratio\" portion.\r\n * default = 30, range 0 - 40\r\n * @param {Number} [time] Assign time value to schedule the change in value\r\n */\r\n p5.Compressor.prototype.knee = function (knee, time){\r\n var t = time || 0;\r\n if (typeof knee == 'number'){\r\n this.compressor.knee.value = knee;\r\n this.compressor.knee.cancelScheduledValues(this.ac.currentTime + 0.01 + t);\r\n this.compressor.knee.linearRampToValueAtTime(knee, this.ac.currentTime + 0.02 + t);\r\n } else if (typeof knee !== 'undefined') {\r\n knee.connect(this.compressor.knee);\r\n }\r\n return this.compressor.knee.value;\r\n };\r\n\r\n\r\n /**\r\n * Get current ratio or set value w/ time ramp\r\n * @method ratio\r\n * @for p5.Compressor\r\n * @param {Number} [ratio] The amount of dB change in input for a 1 dB change in output\r\n * default = 12, range 1 - 20\r\n * @param {Number} [time] Assign time value to schedule the change in value\r\n */\r\n p5.Compressor.prototype.ratio = function (ratio, time){\r\n var t = time || 0;\r\n if (typeof ratio == 'number'){\r\n this.compressor.ratio.value = ratio;\r\n this.compressor.ratio.cancelScheduledValues(this.ac.currentTime + 0.01 + t);\r\n this.compressor.ratio.linearRampToValueAtTime(ratio, this.ac.currentTime + 0.02 + t);\r\n } else if (typeof ratio !== 'undefined') {\r\n ratio.connect(this.compressor.ratio);\r\n }\r\n return this.compressor.ratio.value;\r\n };\r\n\r\n\r\n /**\r\n * Get current threshold or set value w/ time ramp\r\n * @method threshold\r\n * @for p5.Compressor\r\n * @param {Number} threshold The decibel value above which the compression will start taking effect\r\n * default = -24, range -100 - 0\r\n * @param {Number} [time] Assign time value to schedule the change in value\r\n */\r\n p5.Compressor.prototype.threshold = function (threshold, time){\r\n var t = time || 0;\r\n if (typeof threshold == 'number'){\r\n this.compressor.threshold.value = threshold;\r\n this.compressor.threshold.cancelScheduledValues(this.ac.currentTime + 0.01 + t);\r\n this.compressor.threshold.linearRampToValueAtTime(threshold, this.ac.currentTime + 0.02 + t);\r\n } else if (typeof threshold !== 'undefined') {\r\n threshold.connect(this.compressor.threshold);\r\n }\r\n return this.compressor.threshold.value;\r\n };\r\n\r\n\r\n /**\r\n * Get current release or set value w/ time ramp\r\n * @method release\r\n * @for p5.Compressor\r\n * @param {Number} release The amount of time (in seconds) to increase the gain by 10dB\r\n * default = .25, range 0 - 1\r\n *\r\n * @param {Number} [time] Assign time value to schedule the change in value\r\n */\r\n p5.Compressor.prototype.release = function (release, time){\r\n var t = time || 0;\r\n if (typeof release == 'number'){\r\n this.compressor.release.value = release;\r\n this.compressor.release.cancelScheduledValues(this.ac.currentTime + 0.01 + t);\r\n this.compressor.release.linearRampToValueAtTime(release, this.ac.currentTime + 0.02 + t);\r\n } else if (typeof number !== 'undefined') {\r\n release.connect(this.compressor.release);\r\n }\r\n return this.compressor.release.value;\r\n };\r\n\r\n /**\r\n * Return the current reduction value\r\n *\r\n * @method reduction\r\n * @for p5.Compressor\r\n * @return {Number} Value of the amount of gain reduction that is applied to the signal\r\n */\r\n p5.Compressor.prototype.reduction =function() {\r\n return this.compressor.reduction.value;\r\n };\r\n\r\n\r\n\tp5.Compressor.prototype.dispose = function() {\r\n Effect.prototype.dispose.apply(this);\r\n if (this.compressor) {\r\n this.compressor.disconnect();\r\n delete this.compressor;\r\n }\r\n\t};\r\n\r\n return p5.Compressor;\r\n});\r\n","'use strict';\r\n\r\ndefine(function (require) {\r\n\r\n // inspiration: recorder.js, Tone.js & typedarray.org\r\n\r\n var p5sound = require('master');\r\n var convertToWav = require('helpers').convertToWav;\r\n var processorNames = require('./audioWorklet/processorNames');\r\n var ac = p5sound.audiocontext;\r\n\r\n /**\r\n *
Record sounds for playback and/or to save as a .wav file.\r\n * The p5.SoundRecorder records all sound output from your sketch,\r\n * or can be assigned a specific source with setInput().
\r\n *
The record() method accepts a p5.SoundFile as a parameter.\r\n * When playback is stopped (either after the given amount of time,\r\n * or with the stop() method), the p5.SoundRecorder will send its\r\n * recording to that p5.SoundFile for playback.
\r\n * var mic, recorder, soundFile;\r\n * var state = 0;\r\n *\r\n * function setup() {\r\n * background(200);\r\n * // create an audio in\r\n * mic = new p5.AudioIn();\r\n *\r\n * // prompts user to enable their browser mic\r\n * mic.start();\r\n *\r\n * // create a sound recorder\r\n * recorder = new p5.SoundRecorder();\r\n *\r\n * // connect the mic to the recorder\r\n * recorder.setInput(mic);\r\n *\r\n * // this sound file will be used to\r\n * // playback & save the recording\r\n * soundFile = new p5.SoundFile();\r\n *\r\n * text('keyPress to record', 20, 20);\r\n * }\r\n *\r\n * function keyPressed() {\r\n * // make sure user enabled the mic\r\n * if (state === 0 && mic.enabled) {\r\n *\r\n * // record to our p5.SoundFile\r\n * recorder.record(soundFile);\r\n *\r\n * background(255,0,0);\r\n * text('Recording!', 20, 20);\r\n * state++;\r\n * }\r\n * else if (state === 1) {\r\n * background(0,255,0);\r\n *\r\n * // stop recorder and\r\n * // send result to soundFile\r\n * recorder.stop();\r\n *\r\n * text('Stopped', 20, 20);\r\n * state++;\r\n * }\r\n *\r\n * else if (state === 2) {\r\n * soundFile.play(); // play the result!\r\n * save(soundFile, 'mySound.wav');\r\n * state++;\r\n * }\r\n * }\r\n *
\r\n */\r\n p5.SoundRecorder = function() {\r\n this.input = ac.createGain();\r\n this.output = ac.createGain();\r\n\r\n this._inputChannels = 2;\r\n this._outputChannels = 2; // stereo output, even if input is mono\r\n\r\n this._workletNode = new AudioWorkletNode(ac, processorNames.recorderProcessor, {\r\n outputChannelCount: [this._outputChannels],\r\n processorOptions: { numInputChannels: this._inputChannels }\r\n });\r\n\r\n this._workletNode.port.onmessage = function(event) {\r\n if (event.data.name === 'buffers') {\r\n const buffers = [\r\n new Float32Array(event.data.leftBuffer),\r\n new Float32Array(event.data.rightBuffer)\r\n ];\r\n this._callback(buffers);\r\n }\r\n }.bind(this);\r\n\r\n /**\r\n * callback invoked when the recording is over\r\n * @private\r\n * @type Function(Float32Array)\r\n */\r\n this._callback = function() {};\r\n\r\n // connections\r\n this._workletNode.connect(p5.soundOut._silentNode);\r\n this.setInput();\r\n\r\n // add this p5.SoundFile to the soundArray\r\n p5sound.soundArray.push(this);\r\n };\r\n\r\n /**\r\n * Connect a specific device to the p5.SoundRecorder.\r\n * If no parameter is given, p5.SoundRecorer will record\r\n * all audible p5.sound from your sketch.\r\n *\r\n * @method setInput\r\n * @for p5.SoundRecorder\r\n * @param {Object} [unit] p5.sound object or a web audio unit\r\n * that outputs sound\r\n */\r\n p5.SoundRecorder.prototype.setInput = function(unit) {\r\n this.input.disconnect();\r\n this.input = null;\r\n this.input = ac.createGain();\r\n this.input.connect(this._workletNode);\r\n this.input.connect(this.output);\r\n if (unit) {\r\n unit.connect(this.input);\r\n } else {\r\n p5.soundOut.output.connect(this.input);\r\n }\r\n };\r\n\r\n /**\r\n * Start recording. To access the recording, provide\r\n * a p5.SoundFile as the first parameter. The p5.SoundRecorder\r\n * will send its recording to that p5.SoundFile for playback once\r\n * recording is complete. Optional parameters include duration\r\n * (in seconds) of the recording, and a callback function that\r\n * will be called once the complete recording has been\r\n * transfered to the p5.SoundFile.\r\n *\r\n * @method record\r\n * @for p5.SoundRecorder\r\n * @param {p5.SoundFile} soundFile p5.SoundFile\r\n * @param {Number} [duration] Time (in seconds)\r\n * @param {Function} [callback] The name of a function that will be\r\n * called once the recording completes\r\n */\r\n p5.SoundRecorder.prototype.record = function(sFile, duration, callback) {\r\n this._workletNode.port.postMessage({ name: 'start', duration: duration });\r\n\r\n if (sFile && callback) {\r\n this._callback = function(buffer) {\r\n sFile.setBuffer(buffer);\r\n callback();\r\n };\r\n }\r\n else if (sFile) {\r\n this._callback = function(buffer) {\r\n sFile.setBuffer(buffer);\r\n };\r\n }\r\n };\r\n\r\n /**\r\n * Stop the recording. Once the recording is stopped,\r\n * the results will be sent to the p5.SoundFile that\r\n * was given on .record(), and if a callback function\r\n * was provided on record, that function will be called.\r\n *\r\n * @method stop\r\n * @for p5.SoundRecorder\r\n */\r\n p5.SoundRecorder.prototype.stop = function() {\r\n this._workletNode.port.postMessage({ name: 'stop' });\r\n };\r\n\r\n p5.SoundRecorder.prototype.dispose = function() {\r\n // remove reference from soundArray\r\n var index = p5sound.soundArray.indexOf(this);\r\n p5sound.soundArray.splice(index, 1);\r\n\r\n this._callback = function() {};\r\n if (this.input) {\r\n this.input.disconnect();\r\n }\r\n this.input = null;\r\n this._workletNode = null;\r\n };\r\n\r\n\r\n /**\r\n * Save a p5.SoundFile as a .wav file. The browser will prompt the user\r\n * to download the file to their device.\r\n * For uploading audio to a server, use\r\n * `p5.SoundFile.saveBlob`.\r\n *\r\n * @for p5\r\n * @method saveSound\r\n * @param {p5.SoundFile} soundFile p5.SoundFile that you wish to save\r\n * @param {String} fileName name of the resulting .wav file.\r\n */\r\n // add to p5.prototype as this is used by the p5 `save()` method.\r\n p5.prototype.saveSound = function (soundFile, fileName) {\r\n const dataView = convertToWav(soundFile.buffer);\r\n p5.prototype.writeFile([dataView], fileName, 'wav');\r\n };\r\n});\r\n","'use strict';\r\n\r\ndefine(function () {\r\n /**\r\n *
PeakDetect works in conjunction with p5.FFT to\r\n * look for onsets in some or all of the frequency spectrum.\r\n *
\r\n *
\r\n * To use p5.PeakDetect, call update in the draw loop\r\n * and pass in a p5.FFT object.\r\n *
\r\n *
\r\n * You can listen for a specific part of the frequency spectrum by\r\n * setting the range between freq1 and freq2.\r\n *
\r\n *\r\n *
threshold is the threshold for detecting a peak,\r\n * scaled between 0 and 1. It is logarithmic, so 0.1 is half as loud\r\n * as 1.0.
\r\n *\r\n *
\r\n * The update method is meant to be run in the draw loop, and\r\n * frames determines how many loops must pass before\r\n * another peak can be detected.\r\n * For example, if the frameRate() = 60, you could detect the beat of a\r\n * 120 beat-per-minute song with this equation:\r\n * framesPerPeak = 60 / (estimatedBPM / 60 );\r\n *
\r\n *\r\n *
\r\n * Based on example contribtued by @b2renger, and a simple beat detection\r\n * explanation by Felix Turner.\r\n *
\r\n *\r\n * @class p5.PeakDetect\r\n * @constructor\r\n * @param {Number} [freq1] lowFrequency - defaults to 20Hz\r\n * @param {Number} [freq2] highFrequency - defaults to 20000 Hz\r\n * @param {Number} [threshold] Threshold for detecting a beat between 0 and 1\r\n * scaled logarithmically where 0.1 is 1/2 the loudness\r\n * of 1.0. Defaults to 0.35.\r\n * @param {Number} [framesPerPeak] Defaults to 20.\r\n * @example\r\n *
\r\n */\r\n p5.PeakDetect = function(freq1, freq2, threshold, _framesPerPeak) {\r\n // framesPerPeak determines how often to look for a beat.\r\n // If a beat is provided, try to look for a beat based on bpm\r\n this.framesPerPeak = _framesPerPeak || 20;\r\n this.framesSinceLastPeak = 0;\r\n this.decayRate = 0.95;\r\n\r\n this.threshold = threshold || 0.35;\r\n this.cutoff = 0;\r\n\r\n // how much to increase the cutoff\r\n // TO DO: document this / figure out how to make it accessible\r\n this.cutoffMult = 1.5;\r\n\r\n this.energy = 0;\r\n this.penergy = 0;\r\n\r\n // TO DO: document this property / figure out how to make it accessible\r\n this.currentValue = 0;\r\n\r\n /**\r\n * isDetected is set to true when a peak is detected.\r\n *\r\n * @attribute isDetected {Boolean}\r\n * @default false\r\n */\r\n this.isDetected = false;\r\n\r\n this.f1 = freq1 || 40;\r\n this.f2 = freq2 || 20000;\r\n\r\n // function to call when a peak is detected\r\n this._onPeak = function() {};\r\n };\r\n\r\n\r\n /**\r\n * The update method is run in the draw loop.\r\n *\r\n * Accepts an FFT object. You must call .analyze()\r\n * on the FFT object prior to updating the peakDetect\r\n * because it relies on a completed FFT analysis.\r\n *\r\n * @method update\r\n * @param {p5.FFT} fftObject A p5.FFT object\r\n */\r\n p5.PeakDetect.prototype.update = function(fftObject) {\r\n var nrg = this.energy = fftObject.getEnergy(this.f1,this.f2)/255;\r\n if (nrg > this.cutoff && nrg > this.threshold && nrg-this.penergy > 0) {\r\n\r\n // trigger callback\r\n this._onPeak();\r\n this.isDetected = true;\r\n\r\n // debounce\r\n this.cutoff = nrg * this.cutoffMult;\r\n this.framesSinceLastPeak = 0;\r\n } else {\r\n this.isDetected = false;\r\n if (this.framesSinceLastPeak <= this.framesPerPeak) {\r\n this.framesSinceLastPeak++;\r\n } else {\r\n this.cutoff *= this.decayRate;\r\n this.cutoff = Math.max(this.cutoff, this.threshold);\r\n }\r\n }\r\n\r\n this.currentValue = nrg;\r\n this.penergy = nrg;\r\n };\r\n\r\n /**\r\n * onPeak accepts two arguments: a function to call when\r\n * a peak is detected. The value of the peak,\r\n * between 0.0 and 1.0, is passed to the callback.\r\n *\r\n * @method onPeak\r\n * @param {Function} callback Name of a function that will\r\n * be called when a peak is\r\n * detected.\r\n * @param {Object} [val] Optional value to pass\r\n * into the function when\r\n * a peak is detected.\r\n * @example\r\n *
\r\n * var cnv, soundFile, fft, peakDetect;\r\n * var ellipseWidth = 0;\r\n *\r\n * function preload() {\r\n * soundFile = loadSound('assets/beat.mp3');\r\n * }\r\n *\r\n * function setup() {\r\n * cnv = createCanvas(100,100);\r\n * textAlign(CENTER);\r\n *\r\n * fft = new p5.FFT();\r\n * peakDetect = new p5.PeakDetect();\r\n *\r\n * setupSound();\r\n *\r\n * // when a beat is detected, call triggerBeat()\r\n * peakDetect.onPeak(triggerBeat);\r\n * }\r\n *\r\n * function draw() {\r\n * background(0);\r\n * fill(255);\r\n * text('click to play', width/2, height/2);\r\n *\r\n * fft.analyze();\r\n * peakDetect.update(fft);\r\n *\r\n * ellipseWidth *= 0.95;\r\n * ellipse(width/2, height/2, ellipseWidth, ellipseWidth);\r\n * }\r\n *\r\n * // this function is called by peakDetect.onPeak\r\n * function triggerBeat() {\r\n * ellipseWidth = 50;\r\n * }\r\n *\r\n * // mouseclick starts/stops sound\r\n * function setupSound() {\r\n * cnv.mouseClicked( function() {\r\n * if (soundFile.isPlaying() ) {\r\n * soundFile.stop();\r\n * } else {\r\n * soundFile.play();\r\n * }\r\n * });\r\n * }\r\n *
\r\n */\r\n p5.PeakDetect.prototype.onPeak = function(callback, val) {\r\n var self = this;\r\n\r\n self._onPeak = function() {\r\n callback(self.energy, val);\r\n };\r\n };\r\n\r\n});\r\n","'use strict';\r\n\r\ndefine(function (require) {\r\n var p5sound = require('master');\r\n\r\n /**\r\n * A gain node is usefull to set the relative volume of sound.\r\n * It's typically used to build mixers.\r\n *\r\n * @class p5.Gain\r\n * @constructor\r\n * @example\r\n *
\r\n *\r\n * // load two soundfile and crossfade beetween them\r\n * var sound1,sound2;\r\n * var gain1, gain2, gain3;\r\n *\r\n * function preload(){\r\n * soundFormats('ogg', 'mp3');\r\n * sound1 = loadSound('assets/Damscray_-_Dancing_Tiger_01');\r\n * sound2 = loadSound('assets/beat.mp3');\r\n * }\r\n *\r\n * function setup() {\r\n * createCanvas(400,200);\r\n *\r\n * // create a 'master' gain to which we will connect both soundfiles\r\n * gain3 = new p5.Gain();\r\n * gain3.connect();\r\n *\r\n * // setup first sound for playing\r\n * sound1.rate(1);\r\n * sound1.loop();\r\n * sound1.disconnect(); // diconnect from p5 output\r\n *\r\n * gain1 = new p5.Gain(); // setup a gain node\r\n * gain1.setInput(sound1); // connect the first sound to its input\r\n * gain1.connect(gain3); // connect its output to the 'master'\r\n *\r\n * sound2.rate(1);\r\n * sound2.disconnect();\r\n * sound2.loop();\r\n *\r\n * gain2 = new p5.Gain();\r\n * gain2.setInput(sound2);\r\n * gain2.connect(gain3);\r\n *\r\n * }\r\n *\r\n * function draw(){\r\n * background(180);\r\n *\r\n * // calculate the horizontal distance beetween the mouse and the right of the screen\r\n * var d = dist(mouseX,0,width,0);\r\n *\r\n * // map the horizontal position of the mouse to values useable for volume control of sound1\r\n * var vol1 = map(mouseX,0,width,0,1);\r\n * var vol2 = 1-vol1; // when sound1 is loud, sound2 is quiet and vice versa\r\n *\r\n * gain1.amp(vol1,0.5,0);\r\n * gain2.amp(vol2,0.5,0);\r\n *\r\n * // map the vertical position of the mouse to values useable for 'master volume control'\r\n * var vol3 = map(mouseY,0,height,0,1);\r\n * gain3.amp(vol3,0.5,0);\r\n * }\r\n *
\r\n *\r\n */\r\n\r\n p5.Gain = function() {\r\n this.ac = p5sound.audiocontext;\r\n\r\n this.input = this.ac.createGain();\r\n this.output = this.ac.createGain();\r\n\r\n // otherwise, Safari distorts\r\n this.input.gain.value = 0.5;\r\n this.input.connect(this.output);\r\n\r\n // add to the soundArray\r\n p5sound.soundArray.push(this);\r\n };\r\n\r\n /**\r\n * Connect a source to the gain node.\r\n *\r\n * @method setInput\r\n * @for p5.Gain\r\n * @param {Object} src p5.sound / Web Audio object with a sound\r\n * output.\r\n */\r\n\r\n\r\n p5.Gain.prototype.setInput = function(src) {\r\n src.connect(this.input);\r\n };\r\n\r\n /**\r\n * Send output to a p5.sound or web audio object\r\n *\r\n * @method connect\r\n * @for p5.Gain\r\n * @param {Object} unit\r\n */\r\n p5.Gain.prototype.connect = function(unit) {\r\n var u = unit || p5.soundOut.input;\r\n this.output.connect(u.input ? u.input : u);\r\n };\r\n\r\n /**\r\n * Disconnect all output.\r\n *\r\n * @method disconnect\r\n * @for p5.Gain\r\n */\r\n p5.Gain.prototype.disconnect = function() {\r\n if (this.output) {\r\n this.output.disconnect();\r\n }\r\n };\r\n\r\n /**\r\n * Set the output level of the gain node.\r\n *\r\n * @method amp\r\n * @for p5.Gain\r\n * @param {Number} volume amplitude between 0 and 1.0\r\n * @param {Number} [rampTime] create a fade that lasts rampTime\r\n * @param {Number} [timeFromNow] schedule this event to happen\r\n * seconds from now\r\n */\r\n p5.Gain.prototype.amp = function(vol, rampTime, tFromNow) {\r\n var rampTime = rampTime || 0;\r\n var tFromNow = tFromNow || 0;\r\n var now = p5sound.audiocontext.currentTime;\r\n var currentVol = this.output.gain.value;\r\n this.output.gain.cancelScheduledValues(now);\r\n this.output.gain.linearRampToValueAtTime(currentVol, now + tFromNow);\r\n this.output.gain.linearRampToValueAtTime(vol, now + tFromNow + rampTime);\r\n };\r\n\r\n p5.Gain.prototype.dispose = function() {\r\n // remove reference from soundArray\r\n var index = p5sound.soundArray.indexOf(this);\r\n p5sound.soundArray.splice(index, 1);\r\n if (this.output) {\r\n this.output.disconnect();\r\n delete this.output;\r\n }\r\n if (this.input) {\r\n this.input.disconnect();\r\n delete this.input;\r\n }\r\n };\r\n\r\n});\r\n","'use strict';\r\n\r\ndefine(function (require) {\r\n\r\n var Effect = require('effect');\r\n\r\n /*\r\n * Adapted from [Kevin Ennis on StackOverflow](http://stackoverflow.com/questions/22312841/waveshaper-node-in-webaudio-how-to-emulate-distortion)\r\n */\r\n function makeDistortionCurve(amount) {\r\n var k = typeof amount === 'number' ? amount : 50;\r\n var numSamples = 44100;\r\n var curve = new Float32Array(numSamples);\r\n var deg = Math.PI / 180;\r\n var i = 0;\r\n var x;\r\n for ( ; i < numSamples; ++i ) {\r\n x = i * 2 / numSamples - 1;\r\n curve[i] = ( 3 + k ) * x * 20 * deg / ( Math.PI + k * Math.abs(x) );\r\n }\r\n return curve;\r\n }\r\n\r\n /**\r\n * A Distortion effect created with a Waveshaper Node,\r\n * with an approach adapted from\r\n * [Kevin Ennis](http://stackoverflow.com/questions/22312841/waveshaper-node-in-webaudio-how-to-emulate-distortion)\r\n *\r\n * This class extends p5.Effect.\r\n * Methods amp(), chain(),\r\n * drywet(), connect(), and\r\n * disconnect() are available.\r\n *\r\n * @class p5.Distortion\r\n * @extends p5.Effect\r\n * @constructor\r\n * @param {Number} [amount=0.25] Unbounded distortion amount.\r\n * Normal values range from 0-1.\r\n * @param {String} [oversample='none'] 'none', '2x', or '4x'.\r\n *\r\n */\r\n p5.Distortion = function(amount, oversample) {\r\n Effect.call(this);\r\n\r\n if (typeof amount === 'undefined') {\r\n amount = 0.25;\r\n } if (typeof amount !== 'number') {\r\n throw new Error('amount must be a number');\r\n } if (typeof oversample === 'undefined') {\r\n oversample = '2x';\r\n } if (typeof oversample !== 'string') {\r\n throw new Error('oversample must be a String');\r\n }\r\n\r\n var curveAmount = p5.prototype.map(amount, 0.0, 1.0, 0, 2000);\r\n\r\n /**\r\n * The p5.Distortion is built with a\r\n * \r\n * Web Audio WaveShaper Node.\r\n *\r\n * @property {AudioNode} WaveShaperNode\r\n */\r\n this.waveShaperNode = this.ac.createWaveShaper();\r\n\r\n this.amount = curveAmount;\r\n this.waveShaperNode.curve = makeDistortionCurve(curveAmount);\r\n this.waveShaperNode.oversample = oversample;\r\n\r\n this.input.connect(this.waveShaperNode);\r\n\r\n this.waveShaperNode.connect(this.wet);\r\n };\r\n\r\n p5.Distortion.prototype = Object.create(Effect.prototype);\r\n\r\n\r\n /**\r\n * Process a sound source, optionally specify amount and oversample values.\r\n *\r\n * @method process\r\n * @for p5.Distortion\r\n * @param {Number} [amount=0.25] Unbounded distortion amount.\r\n * Normal values range from 0-1.\r\n * @param {String} [oversample='none'] 'none', '2x', or '4x'.\r\n */\r\n p5.Distortion.prototype.process = function(src, amount, oversample) {\r\n src.connect(this.input);\r\n this.set(amount, oversample);\r\n };\r\n\r\n /**\r\n * Set the amount and oversample of the waveshaper distortion.\r\n *\r\n * @method set\r\n * @for p5.Distortion\r\n * @param {Number} [amount=0.25] Unbounded distortion amount.\r\n * Normal values range from 0-1.\r\n * @param {String} [oversample='none'] 'none', '2x', or '4x'.\r\n */\r\n p5.Distortion.prototype.set = function(amount, oversample) {\r\n if (amount) {\r\n var curveAmount = p5.prototype.map(amount, 0.0, 1.0, 0, 2000);\r\n this.amount = curveAmount;\r\n this.waveShaperNode.curve = makeDistortionCurve(curveAmount);\r\n }\r\n if (oversample) {\r\n this.waveShaperNode.oversample = oversample;\r\n }\r\n };\r\n\r\n /**\r\n * Return the distortion amount, typically between 0-1.\r\n *\r\n * @method getAmount\r\n * @for p5.Distortion\r\n * @return {Number} Unbounded distortion amount.\r\n * Normal values range from 0-1.\r\n */\r\n p5.Distortion.prototype.getAmount = function() {\r\n return this.amount;\r\n };\r\n\r\n /**\r\n * Return the oversampling.\r\n *\r\n * @method getOversample\r\n * @for p5.Distortion\r\n * @return {String} Oversample can either be 'none', '2x', or '4x'.\r\n */\r\n p5.Distortion.prototype.getOversample = function() {\r\n return this.waveShaperNode.oversample;\r\n };\r\n\r\n\r\n p5.Distortion.prototype.dispose = function() {\r\n Effect.prototype.dispose.apply(this);\r\n if (this.waveShaperNode) {\r\n this.waveShaperNode.disconnect();\r\n this.waveShaperNode = null;\r\n }\r\n };\r\n});\r\n","export default \"function _typeof(obj) { if (typeof Symbol === \\\"function\\\" && typeof Symbol.iterator === \\\"symbol\\\") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === \\\"function\\\" && obj.constructor === Symbol && obj !== Symbol.prototype ? \\\"symbol\\\" : typeof obj; }; } return _typeof(obj); }\\n\\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\\\"Cannot call a class as a function\\\"); } }\\n\\nfunction _possibleConstructorReturn(self, call) { if (call && (_typeof(call) === \\\"object\\\" || typeof call === \\\"function\\\")) { return call; } return _assertThisInitialized(self); }\\n\\nfunction _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError(\\\"this hasn't been initialised - super() hasn't been called\\\"); } return self; }\\n\\nfunction _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if (\\\"value\\\" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }\\n\\nfunction _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }\\n\\nfunction _inherits(subClass, superClass) { if (typeof superClass !== \\\"function\\\" && superClass !== null) { throw new TypeError(\\\"Super expression must either be null or a function\\\"); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, writable: true, configurable: true } }); if (superClass) _setPrototypeOf(subClass, superClass); }\\n\\nfunction _wrapNativeSuper(Class) { var _cache = typeof Map === \\\"function\\\" ? new Map() : undefined; _wrapNativeSuper = function _wrapNativeSuper(Class) { if (Class === null || !_isNativeFunction(Class)) return Class; if (typeof Class !== \\\"function\\\") { throw new TypeError(\\\"Super expression must either be null or a function\\\"); } if (typeof _cache !== \\\"undefined\\\") { if (_cache.has(Class)) return _cache.get(Class); _cache.set(Class, Wrapper); } function Wrapper() { return _construct(Class, arguments, _getPrototypeOf(this).constructor); } Wrapper.prototype = Object.create(Class.prototype, { constructor: { value: Wrapper, enumerable: false, writable: true, configurable: true } }); return _setPrototypeOf(Wrapper, Class); }; return _wrapNativeSuper(Class); }\\n\\nfunction isNativeReflectConstruct() { if (typeof Reflect === \\\"undefined\\\" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === \\\"function\\\") return true; try { Date.prototype.toString.call(Reflect.construct(Date, [], function () {})); return true; } catch (e) { return false; } }\\n\\nfunction _construct(Parent, args, Class) { if (isNativeReflectConstruct()) { _construct = Reflect.construct; } else { _construct = function _construct(Parent, args, Class) { var a = [null]; a.push.apply(a, args); var Constructor = Function.bind.apply(Parent, a); var instance = new Constructor(); if (Class) _setPrototypeOf(instance, Class.prototype); return instance; }; } return _construct.apply(null, arguments); }\\n\\nfunction _isNativeFunction(fn) { return Function.toString.call(fn).indexOf(\\\"[native code]\\\") !== -1; }\\n\\nfunction _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); }\\n\\nfunction _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); }; return _getPrototypeOf(o); }\\n\\n// import processor name via preval.require so that it's available as a value at compile time\\nvar processorNames = {\\n \\\"recorderProcessor\\\": \\\"recorder-processor\\\",\\n \\\"soundFileProcessor\\\": \\\"sound-file-processor\\\",\\n \\\"amplitudeProcessor\\\": \\\"amplitude-processor\\\"\\n}; // TO DO make this stereo / dependent on # of audio channels\\n\\nvar AmplitudeProcessor =\\n/*#__PURE__*/\\nfunction (_AudioWorkletProcesso) {\\n _inherits(AmplitudeProcessor, _AudioWorkletProcesso);\\n\\n _createClass(AmplitudeProcessor, null, [{\\n key: \\\"parameterDescriptors\\\",\\n get: function get() {\\n return [{\\n name: 'smoothing',\\n defaultValue: 0,\\n minValue: 0,\\n maxValue: 1,\\n automationRate: 'k-rate'\\n }];\\n }\\n }]);\\n\\n function AmplitudeProcessor(options) {\\n var _this;\\n\\n _classCallCheck(this, AmplitudeProcessor);\\n\\n _this = _possibleConstructorReturn(this, _getPrototypeOf(AmplitudeProcessor).call(this));\\n var processorOptions = options.processorOptions || {};\\n _this.normalize = processorOptions.normalize || false;\\n _this.stereoVol = [0, 0];\\n _this.stereoVolNorm = [0, 0];\\n _this.volMax = 0.001;\\n\\n _this.port.onmessage = function (event) {\\n var data = event.data;\\n\\n if (data.name === 'toggleNormalize') {\\n _this.normalize = data.normalize;\\n }\\n };\\n\\n return _this;\\n }\\n\\n _createClass(AmplitudeProcessor, [{\\n key: \\\"process\\\",\\n value: function process(inputs, outputs, parameters) {\\n var input = inputs[0];\\n var output = outputs[0];\\n var smoothing = parameters.smoothing;\\n\\n for (var channel = 0; channel < input.length; ++channel) {\\n var inputBuffer = input[channel];\\n var bufLength = inputBuffer.length;\\n var sum = 0;\\n\\n for (var i = 0; i < bufLength; i++) {\\n var x = inputBuffer[i];\\n\\n if (this.normalize) {\\n sum += Math.max(Math.min(x / this.volMax, 1), -1) * Math.max(Math.min(x / this.volMax, 1), -1);\\n } else {\\n sum += x * x;\\n }\\n } // ... then take the square root of the sum.\\n\\n\\n var rms = Math.sqrt(sum / bufLength);\\n this.stereoVol[channel] = Math.max(rms, this.stereoVol[channel] * smoothing);\\n this.volMax = Math.max(this.stereoVol[channel], this.volMax);\\n } // calculate stero normalized volume and add volume from all channels together\\n\\n\\n var volSum = 0;\\n\\n for (var index = 0; index < this.stereoVol.length; index++) {\\n this.stereoVolNorm[index] = Math.max(Math.min(this.stereoVol[index] / this.volMax, 1), 0);\\n volSum += this.stereoVol[index];\\n } // volume is average of channels\\n\\n\\n var volume = volSum / this.stereoVol.length; // normalized value\\n\\n var volNorm = Math.max(Math.min(volume / this.volMax, 1), 0);\\n this.port.postMessage({\\n name: 'amplitude',\\n volume: volume,\\n volNorm: volNorm,\\n stereoVol: this.stereoVol,\\n stereoVolNorm: this.stereoVolNorm\\n }); // pass input through to output\\n\\n for (var _channel = 0; _channel < output.length; ++_channel) {\\n output[_channel].set(input[_channel]);\\n }\\n\\n return true;\\n }\\n }]);\\n\\n return AmplitudeProcessor;\\n}(_wrapNativeSuper(AudioWorkletProcessor));\\n\\nregisterProcessor(processorNames.amplitudeProcessor, AmplitudeProcessor);\""],"sourceRoot":""}
\ No newline at end of file
+{"version":3,"sources":["webpack:///webpack/bootstrap","webpack:///../node_modules/tone/Tone/core/Tone.js","webpack:///./master.js","webpack:///../node_modules/tone/Tone/signal/Signal.js","webpack:///../node_modules/tone/Tone/signal/Multiply.js","webpack:///./effect.js","webpack:///../node_modules/tone/Tone/signal/WaveShaper.js","webpack:///./helpers.js","webpack:///../node_modules/tone/Tone/signal/Add.js","webpack:///../node_modules/tone/Tone/type/Type.js","webpack:///../node_modules/tone/Tone/core/Gain.js","webpack:///./errorHandler.js","webpack:///../node_modules/tone/Tone/core/Context.js","webpack:///./audioWorklet/processorNames.js","webpack:///../node_modules/tone/Tone/signal/Scale.js","webpack:///../node_modules/tone/Tone/signal/TimelineSignal.js","webpack:///./filter.js","webpack:///../node_modules/tone/Tone/signal/Subtract.js","webpack:///./audiocontext.js","webpack:///../node_modules/tone/Tone/core/Emitter.js","webpack:///../node_modules/tone/Tone/signal/SignalBase.js","webpack:///../node_modules/tone/Tone/type/Time.js","webpack:///../node_modules/tone/Tone/type/TimeBase.js","webpack:///../node_modules/tone/Tone/core/Param.js","webpack:///./oscillator.js","webpack:///../node_modules/tone/Tone/core/Timeline.js","webpack:///../node_modules/tone/Tone/signal/Negate.js","webpack:///../node_modules/tone/Tone/signal/GreaterThanZero.js","webpack:///../node_modules/tone/Tone/core/Clock.js","webpack:///./monosynth.js","webpack:///./audioVoice.js","webpack:///./polysynth.js","webpack:///./app.js","webpack:///../node_modules/audioworklet-polyfill/dist/audioworklet-polyfill.js","webpack:///./shims.js","webpack:///../node_modules/webpack/buildin/global.js","webpack:///../node_modules/startaudiocontext/StartAudioContext.js","webpack:///./audioWorklet/index.js","webpack:///./audioWorklet/recorderProcessor.js","webpack:///./audioWorklet/soundFileProcessor.js","webpack:///./audioWorklet/amplitudeProcessor.js","webpack:///./panner.js","webpack:///./soundfile.js","webpack:///./amplitude.js","webpack:///./fft.js","webpack:///./signal.js","webpack:///../node_modules/tone/Tone/type/Frequency.js","webpack:///../node_modules/tone/Tone/type/TransportTime.js","webpack:///./envelope.js","webpack:///./pulse.js","webpack:///./noise.js","webpack:///./audioin.js","webpack:///../node_modules/tone/Tone/component/CrossFade.js","webpack:///../node_modules/tone/Tone/signal/Expr.js","webpack:///../node_modules/tone/Tone/signal/GreaterThan.js","webpack:///../node_modules/tone/Tone/signal/Abs.js","webpack:///../node_modules/tone/Tone/signal/Modulo.js","webpack:///../node_modules/tone/Tone/signal/Pow.js","webpack:///../node_modules/tone/Tone/signal/AudioToGain.js","webpack:///../node_modules/tone/Tone/signal/EqualPowerGain.js","webpack:///./eq.js","webpack:///./eqFilter.js","webpack:///./panner3d.js","webpack:///./listener3d.js","webpack:///./delay.js","webpack:///./reverb.js","webpack:///./metro.js","webpack:///../node_modules/tone/Tone/core/TimelineState.js","webpack:///./looper.js","webpack:///./soundLoop.js","webpack:///./compressor.js","webpack:///./soundRecorder.js","webpack:///./peakDetect.js","webpack:///./gain.js","webpack:///./distortion.js"],"names":["define","Tone","inputs","outputs","this","isUndef","input","context","createGain","Array","output","audioContext","prototype","set","params","value","rampTime","isObject","isString","tmpObj","paramLoop","attr","parent","indexOf","attrSplit","split","i","length","splice","innerParam","join","param","Signal","Param","rampTo","AudioParam","get","_collectDefaults","constructor","ret","subRet","j","subAttr","isFunction","constr","defaults","Object","keys","_super","superDefs","push","toString","className","isLetter","match","sameConstructor","defineProperty","isArray","dispose","AudioNode","disconnect","connect","unit","outputNum","inputNum","defaultArg","destination","isNumber","apply","arguments","connectSeries","currentUnit","toUnit","chain","fan","given","fallback","givenProp","fallbackProp","optionsObject","values","options","val","arg","call","isBoolean","noOp","_readOnly","property","writable","enumerable","_writable","State","Started","Stopped","Paused","equalPowerScale","percent","piFactor","Math","PI","sin","dbToGain","db","pow","gainToDb","gain","log","LN10","intervalToFrequencyRatio","interval","now","extend","child","TempConstructor","Context","emit","setContext","ctx","sampleRate","hasAudioContext","window","hasOwnProperty","hasPromises","hasWorkers","version","TONE_SILENCE_VERSION_LOGGING","console","audiocontext","Master","limiter","createDynamicsCompressor","threshold","ratio","knee","meter","fftMeter","soundArray","parts","extensions","p5sound","p5","getMasterVolume","masterVolume","vol","tFromNow","currentTime","currentVol","cancelScheduledValues","linearRampToValueAtTime","soundOut","_silentNode","_gain","_param","getConstant","units","Type","Default","convert","SignalBase","Multiply","createInsOuts","_mult","Gain","require","CrossFade","Effect","ac","_drywet","wet","a","b","amp","drywet","fade","u","index","undefined","WaveShaper","mapping","bufferLen","_shaper","createWaveShaper","_curve","curve","isFinite","Float32Array","setMap","len","normalized","oversample","oversampling","RangeError","freqToMidi","f","mathlog2","m","round","midiToFreq","noteToFreq","note","wholeNotes","A","B","C","D","E","F","G","toUpperCase","octave","slice","soundFormats","toLowerCase","disposeSound","registerMethod","_checkFileFormats","paths","path","extTest","pop","isFileSupported","pathSplit","pathCore","extension","supported","p","_mathChain","o","math","thisChain","nextChain","type","mathOps","convertToWav","audioBuffer","leftChannel","rightChannel","getChannelData","numberOfChannels","interleaved","interleave","buffer","ArrayBuffer","view","DataView","writeUTFBytes","setUint32","setUint16","lng","volume","setInt16","result","inputIndex","offset","string","setUint8","charCodeAt","Add","_sum","Time","Frequency","TransportTime","Ticks","NormalRange","AudioRange","Decibels","Interval","BPM","Positive","Cents","Degrees","MIDI","BarsBeatsSixteenths","Samples","Hertz","Note","Milliseconds","Seconds","Notation","toSeconds","time","TimeBase","toFrequency","freq","valueOf","toTicks","Transport","ticks","GainNode","AudioContext","createGainNode","_gainNode","CustomError","name","errorTrace","failedPath","err","Error","tempStack","splitStack","originalStack","stack","filter","ln","toneConnect","outNum","inNum","nativeConnect","e","nativeDisconnect","webkitAudioContext","prop","Emitter","_context","_defineProperty","_latencyHint","_lookAhead","_updateInterval","_computedUpdateInterval","_worker","_createWorker","_constants","mixin","bind","URL","webkitURL","blob","Blob","toFixed","blobUrl","createObjectURL","worker","Worker","addEventListener","_lastUpdate","diff","max","createBuffer","arr","constant","createBufferSource","channelCount","channelCountMode","loop","start","lA","blockTime","postMessage","hint","lookAhead","latencyHint","updateInterval","warn","module","exports","recorderProcessor","soundFileProcessor","amplitudeProcessor","Scale","outputMin","outputMax","_outputMin","_outputMax","_scale","_add","_setRange","min","TimelineSignal","_events","Timeline","_initial","_fromUnits","Linear","Exponential","Target","Curve","Set","getValueAtTime","_toUnits","convertedVal","setValueAtTime","startTime","add","endTime","exponentialRampToValueAtTime","beforeEvent","_searchBefore","_minOutput","setValue","sampleTime","setTargetAtTime","timeConstant","setValueCurveAtTime","duration","scaling","floats","segmentTime","after","cancel","setRampPoint","before","_searchAfter","linearRampToValueBetween","finish","exponentialRampToValueBetween","getAfter","previouVal","previous","getBefore","_exponentialApproach","_curveInterpolate","_linearInterpolate","_exponentialInterpolate","t0","v0","v1","t","exp","t1","progress","lowerIndex","floor","upperIndex","ceil","lowerVal","upperVal","Filter","biquad","createBiquadFilter","setType","_on","_untoggledType","create","process","src","res","frequency","Q","toggle","LowPass","HighPass","BandPass","Subtract","_neg","Negate","global","StartAudioContext","getAudioContext","userStartAudio","elements","callback","elt","Element","map","on","event","events","eventName","off","ev","eventList","args","object","functions","func","emitterFunc","node","outputNumber","inputNumber","overridden","_plusNow","_unaryExpressions","quantize","regexp","method","rh","nextSubdivision","lh","subdiv","_expr","expr","subdivision","addNow","_defaultExpr","_noOp","copy","toNotation","retNotation","_toNotationHelper","retTripletNotation","testNotations","_notationToUnits","notationTime","multiple","notation","primaryExprs","_primaryExpressions","notationExprs","n","toBarsBeatsSixteenths","quarterTime","_beatsToUnits","quarters","measures","_timeSignature","sixteenths","parseFloat","PPQ","toSamples","toMilliseconds","_defaultUnits","exprString","_parseExprString","clone","instance","parseInt","_ticksToUnits","hz","_frequencyToUnits","tr","q","s","total","_secondsToUnits","samples","default","_binaryExpressions","+","precedence","-","*","/","neg","_syntaxGlue","(",")","_tokenize","position","tokens","token","getNextToken","trim","substr","expressions","group","opName","op","reg","SyntaxError","next","peek","_matchGroup","prec","test","_parseBinary","lexer","_parseUnary","_parsePrimary","matching","beats","bpm","seconds","timeSignature","_pushExpr","sub","mult","div","_lfo","lfo","LFO","currentVal","exponentialRampToValue","linearRampToValue","Mult","Oscillator","started","phaseAmount","oscillator","createOscillator","_freqMods","panPosition","connection","panner","Panner","stop","abs","freqNode","self","getAmp","isNaN","phase","getFreq","getType","oscMods","pan","pval","getPan","osc2","delayAmt","dNode","createDelay","delayTime","sigChain","mathObj","chainSource","num","scale","inMin","inMax","outMin","outMax","mapOutMin","mapOutMax","SinOsc","TriOsc","SawOsc","SqrOsc","_timeline","_toRemove","_iterating","memory","Infinity","_search","remove","shift","cancelBefore","beginning","end","midPoint","nextEvent","_iterate","lowerBound","upperBound","forEach","forEachBefore","forEachAfter","forEachFrom","forEachAtTime","_multiply","GreaterThanZero","_thresh","Clock","_nextTick","_lastState","_state","TimelineState","_boundLoop","_loop","state","setStateAtTime","pause","loopInterval","lag","currentState","tickTime","getStateAtTime","AudioVoice","DEFAULT_SUSTAIN","MonoSynth","env","Envelope","setRange","setExp","setADSR","setInput","play","velocity","secondsFromNow","susTime","triggerAttack","triggerRelease","vel","ramp","attack","decay","sustain","release","defineProperties","aTime","dTime","sPercent","rTime","sustime","PolySynth","audioVoice","maxVoices","audiovoices","notes","_newest","_oldest","_voicesInUse","_allocateVoices","noteAttack","noteRelease","noteADSR","d","r","timeFromNow","voice","_note","_velocity","acTime","currentVoice","oldestNote","previousVal","_updateAfter","maxRange","nextTime","p5SOUND","fixSetTarget","setTargetValueAtTime","createDelayNode","createScriptProcessor","createJavaScriptNode","createPeriodicWave","createWaveTable","internal_createGain","internal_createDelay","maxDelayTime","internal_createBufferSource","when","noteGrainOn","noteOn","internal_start","noteOff","internal_stop","playbackRate","internal_createDynamicsCompressor","reduction","internal_createBiquadFilter","detune","internal_createOscillator","setPeriodicWave","setWaveTable","OfflineAudioContext","webkitOfflineAudioContext","navigator","getUserMedia","webkitGetUserMedia","mozGetUserMedia","msGetUserMedia","el","document","createElement","isSupported","canPlayType","isOGGSupported","isMP3Supported","isWAVSupported","isAACSupported","isAIFSupported","moduleSources","loadAudioWorkletModules","Promise","all","moduleSrc","objectURL","audioWorklet","addModule","preload","_preloadCount","onWorkletModulesLoad","_decrementPreload","then","createStereoPanner","stereoPanner","inputChannels","obj","numInputChannels","left","right","channelInterpretation","splitter","createChannelSplitter","createChannelMerger","v","rightVal","cos","leftVal","numChannels","processorNames","SoundFile","onload","onerror","whileLoading","url","File","FileReader","FileList","file","_onended","_looping","_playing","_paused","_pauseTime","_cues","_cueIDCounter","_lastPos","_counterNode","_workletNode","bufferSourceNodes","bufferSourceNode","reversed","pauseTime","mode","startMillis","load","_whileLoading","_clearOnEnd","registerPreloadMethod","loadSound","location","origin","cordova","alert","errorCallback","request","XMLHttpRequest","evt","_updateProgress","open","responseType","status","decodeAudioData","response","buff","msg","error","statusText","message","send","reader","readAsArrayBuffer","lengthComputable","percentComplete","loaded","isLoaded","rate","_cueStart","cueStart","cueEnd","setVolume","isPlaying","_initSourceNode","_initCounterNode","_arrayIndex","loopStart","loopEnd","port","playMode","str","pTime","setLoop","bool","isLooping","isPaused","stopAll","_time","_rampTime","_tFromNow","getVolume","reverse","reverseBuffer","setPitch","newPlaybackRate","getPlaybackRate","jump","cueTime","cTime","dur","channels","frames","getPeaks","width","sampleSize","sampleStep","peaks","c","chan","currentPos","curVol","onended","warning","getLevel","setPath","setBuffer","buf","size","newBuffer","channelNum","channel","_createCounterBuffer","audioBuf","arrayBuffer","cNode","AudioWorkletNode","onmessage","data","_onTimeUpdate","processPeaks","_initThreshold","_minThreshold","_minPeaks","bufLen","allPeaks","initialThreshold","minThreshold","minPeaks","offlineContext","source","startRendering","oncomplete","filteredBuffer","renderedBuffer","bufferData","getPeaksAtThreshold","intervalCounts","countIntervalsBetweenNearbyPeaks","groups","groupNeighborsByTempo","topTempos","sort","intA","intB","count","tempo","bpmVariance","tempoPeaks","getPeaksAtTopTempo","Peak","sampleIndex","amplitude","tempos","intervals","peaksObj","peak","peaksArray","startPeak","endPeak","startPos","endPos","foundInterval","some","intervalCount","tempoCounts","theoreticalTempo","mapTempo","foundTempo","tempoCount","peaksAtTopTempo","key","intervalBPM","peakTime","dif","Cue","id","addCue","cue","removeCue","cueLength","clearCues","playbackTime","callbackTime","_prevTime","save","fileName","dataView","saveSound","getBlob","thisBufferSourceNode","target","soundFile","removeEventListener","Amplitude","smoothing","bufferSize","outputChannelCount","processorOptions","normalize","volNorm","stereoVol","stereoVolNorm","parameters","toggleNormalize","smooth","FFT","bins","analyser","createAnalyser","fftSize","configurable","smoothingTimeConstant","freqDomain","Uint8Array","frequencyBinCount","timeDomain","bass","lowMid","mid","highMid","treble","waveform","normalArray","_isSafari","timeToFloat","getFloatTimeDomainData","timeToInt","getByteTimeDomainData","scaled","analyze","freqToFloat","getFloatFrequencyData","freqToInt","getByteFrequencyData","getEnergy","frequency1","frequency2","nyquist","swap","lowIndex","highIndex","numFrequencies","toReturn","freq1","freq2","x","getCentroid","cumulative_sum","centroid_normalization","mean_freq_index","spec_centroid_freq","linAverages","N","spectrum","spectrumLength","spectrumStep","linearAverages","groupIndex","specIndex","logAverages","octaveBands","octaveIndex","specIndexFrequency","hi","getOctaveBands","fCtr0","lastFrequencyBand","lo","ctr","newFrequencyBand","fft","_input","midi","midiToFrequency","pitch","noteNumber","noteToScaleIndex","transpose","harmonize","toMidi","frequencyToMidi","toNote","A4","LN2","scaleIndexToNote","cbb","cb","c#","cx","dbb","d#","dx","ebb","eb","e#","ex","fbb","fb","f#","fx","gbb","gb","g","g#","gx","abb","ab","a#","ax","bbb","bb","b#","bx","_secondsToTicks","l1","t2","l2","t3","l3","aLevel","dLevel","rLevel","_rampHighPercentage","_rampLowPercentage","control","_init","isExponential","sourceToClear","wasTriggered","_setRampAD","_rampAttackTime","checkExpInput","_rampDecayTime","TCDenominator","_rampAttackTC","_rampDecayTC","setRampPercentages","p1","p2","isExp","lastAttack","valToSet","v2","destination1","destination2","AudioIn","Reverb","Noise","Delay","Env","Pulse","w","dcOffset","createDCOffset","dcGain","mW","sig","SignalAdd","mods","currentFreq","freqMod","bufferSource","assignType","_brownNoise","_pinkNoise","_whiteNoise","whiteBuffer","noiseData","random","pinkBuffer","b0","b1","b2","b3","b4","b5","b6","white","brownBuffer","lastOut","noise","inputSources","stream","mediaStream","currentSource","enabled","MediaStreamTrack","mediaDevices","successCallback","audioSource","constraints","audio","echoCancellation","deviceId","createMediaStreamSource","getTracks","track","getSources","onSuccess","onError","resolve","reject","enumerateDevices","devices","device","kind","setSource","active","initialFade","_equalPowerA","EqualPowerGain","_equalPowerB","_invert","Expr","applyBinary","Constructor","_eval","applyUnary","getNumber","literalNumber","_replacements","inputCount","_parseInputs","_nodes","tree","_parseTree","_disposeNodes","_Expressions","signal","glue",",","Abs","mod","modulus","Modulo","Pow","a2g","AudioToGain","binary","unary","!","NOT","inputArray","inputMax","replace","matchSyntax","syn","matchGroup","groupName","parseExpression","parseUnary","operator","parsePrimary","parseArgumentList","parseFunctionCall","GreaterThan","_gtz","_abs","_subtract","_modSignal","_setWaveShaper","_exp","_expScaler","_expFunc","_norm","_eqPower","EQFilter","EQ","_eqsize","factor","bands","_newBand","Panner3D","createPanner","panningModel","distanceModel","xVal","yVal","zVal","positionX","positionY","positionZ","orient","orientX","orientY","orientZ","orientationX","orientationY","orientationZ","setFalloff","maxDistance","rolloffFactor","maxDist","rolloff","Listener3D","listener","xValF","yValF","zValF","xValU","yValU","zValU","orientForward","orientUp","forwardX","forwardY","forwardZ","upX","upY","upZ","_split","_merge","_leftGain","_rightGain","leftDelay","rightDelay","_leftFilter","_rightFilter","_maxDelay","maxValue","feedback","_delayTime","_feedback","_filter","_initConvolverNode","_seconds","_decay","_reverse","_buildImpulse","convolverNode","createConvolver","_teardownConvolverNode","_setBuffer","decayRate","rebuild","impulse","impulseL","impulseR","Convolver","impulses","_loadBuffer","cReverb","chunks","addImpulse","resetImpulse","toggleImpulse","Metro","clock","ontick","syncedParts","prevTick","tatumTime","tickCallback","elapsedTime","thisPart","incrementStep","phrases","thisPhrase","phraseArray","sequence","bNum","metroTicks","looping","setBPM","beatTime","tatums","getBPM","getRate","resetSync","part","pushSync","beatLength","initial","Phrase","phraseStep","Part","steps","bLength","partStep","noLoop","metro","addPhrase","array","removePhrase","getPhrase","replaceSequence","onStep","Score","currentPart","thisScore","nextPart","resetPart","playNextPart","resetParts","scoreStep","aScore","SoundLoop","musicalTimeMode","_interval","_bpm","maxIterations","iterations","_calcFreq","syncedStart","otherLoop","_update","_convertNotation","Number","_measure","timeSig","Compressor","compressor","number","SoundRecorder","_inputChannels","_outputChannels","buffers","leftBuffer","rightBuffer","_callback","record","sFile","writeFile","PeakDetect","_framesPerPeak","framesPerPeak","framesSinceLastPeak","cutoff","cutoffMult","energy","penergy","currentValue","isDetected","f1","f2","_onPeak","update","fftObject","nrg","onPeak","makeDistortionCurve","amount","k","numSamples","deg","Distortion","curveAmount","waveShaperNode","getAmount","getOversample"],"mappings":"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;;AAED;AACA;AACA;AACA,CAAC;AACD;AACA;AACA;;AAEA;AACA;AACA,4CAA4C;;AAE5C;;;;;;;ACnBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK,IAA0C;AAC/C,EAAE,iCAAO,EAAE,oCAAE,OAAO;AAAA;AAAA;AAAA,oGAAC;AACrB,GAAG,MAAM,EAIN;AACH,CAAC;;AAED;;AAEA;AACA;AACA,YAAY,QAAQ;AACpB;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA,YAAY,aAAa;AACzB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,aAAa,aAAa;AAC1B,aAAa;AACb;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,aAAa,aAAa;AAC1B,aAAa,SAAS;AACtB;AACA;;AAEA;AACA;AACA;AACA,IAAI;AACJ;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,GAAG;AACH;AACA;AACA;;AAEA;AACA;AACA,aAAa,4BAA4B;AACzC,YAAY,MAAM;AAClB;AACA;AACA;AACA,kBAAkB,oBAAoB;AACtC;AACA;AACA,GAAG;AACH;AACA,GAAG;AACH;AACA,GAAG;AACH;AACA;AACA;AACA,G;AACA;;AAEA;AACA,YAAY,aAAa;AACzB,YAAY,6BAA6B;AACzC;AACA;AACA;AACA;AACA,YAAY,UAAU;AACtB,aAAa,QAAQ;AACrB;AACA;AACA;;AAEA;AACA;AACA;AACA,GAAG;;AAEH;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,kBAAkB,yBAAyB;AAC3C;AACA;AACA;;AAEA;AACA;AACA;AACA,GAAG;;AAEH;AACA;;AAEA;AACA,CAAC,E;;;;;;A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","file":"p5.sound.js","sourcesContent":[" \t// The module cache\n \tvar installedModules = {};\n\n \t// The require function\n \tfunction __webpack_require__(moduleId) {\n\n \t\t// Check if module is in cache\n \t\tif(installedModules[moduleId]) {\n \t\t\treturn installedModules[moduleId].exports;\n \t\t}\n \t\t// Create a new module (and put it into the cache)\n \t\tvar module = installedModules[moduleId] = {\n \t\t\ti: moduleId,\n \t\t\tl: false,\n \t\t\texports: {}\n \t\t};\n\n \t\t// Execute the module function\n \t\tmodules[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n\n \t\t// Flag the module as loaded\n \t\tmodule.l = true;\n\n \t\t// Return the exports of the module\n \t\treturn module.exports;\n \t}\n\n\n \t// expose the modules object (__webpack_modules__)\n \t__webpack_require__.m = modules;\n\n \t// expose the module cache\n \t__webpack_require__.c = installedModules;\n\n \t// define getter function for harmony exports\n \t__webpack_require__.d = function(exports, name, getter) {\n \t\tif(!__webpack_require__.o(exports, name)) {\n \t\t\tObject.defineProperty(exports, name, { enumerable: true, get: getter });\n \t\t}\n \t};\n\n \t// define __esModule on exports\n \t__webpack_require__.r = function(exports) {\n \t\tif(typeof Symbol !== 'undefined' && Symbol.toStringTag) {\n \t\t\tObject.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });\n \t\t}\n \t\tObject.defineProperty(exports, '__esModule', { value: true });\n \t};\n\n \t// create a fake namespace object\n \t// mode & 1: value is a module id, require it\n \t// mode & 2: merge all properties of value into the ns\n \t// mode & 4: return value when already ns object\n \t// mode & 8|1: behave like require\n \t__webpack_require__.t = function(value, mode) {\n \t\tif(mode & 1) value = __webpack_require__(value);\n \t\tif(mode & 8) return value;\n \t\tif((mode & 4) && typeof value === 'object' && value && value.__esModule) return value;\n \t\tvar ns = Object.create(null);\n \t\t__webpack_require__.r(ns);\n \t\tObject.defineProperty(ns, 'default', { enumerable: true, value: value });\n \t\tif(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key));\n \t\treturn ns;\n \t};\n\n \t// getDefaultExport function for compatibility with non-harmony modules\n \t__webpack_require__.n = function(module) {\n \t\tvar getter = module && module.__esModule ?\n \t\t\tfunction getDefault() { return module['default']; } :\n \t\t\tfunction getModuleExports() { return module; };\n \t\t__webpack_require__.d(getter, 'a', getter);\n \t\treturn getter;\n \t};\n\n \t// Object.prototype.hasOwnProperty.call\n \t__webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };\n\n \t// __webpack_public_path__\n \t__webpack_require__.p = \"\";\n\n\n \t// Load entry module and return exports\n \treturn __webpack_require__(__webpack_require__.s = 31);\n","/**\n * Tone.js\n * @author Yotam Mann\n * @license http://opensource.org/licenses/MIT MIT License\n * @copyright 2014-2017 Yotam Mann\n */\ndefine(function(){\n\n\t\"use strict\";\n\n\t///////////////////////////////////////////////////////////////////////////\n\t//\tTONE\n\t///////////////////////////////////////////////////////////////////////////\n\n\t/**\n\t * @class Tone is the base class of all other classes. It provides \n\t * a lot of methods and functionality to all classes that extend\n\t * it. \n\t * \n\t * @constructor\n\t * @alias Tone\n\t * @param {number} [inputs=1] the number of input nodes\n\t * @param {number} [outputs=1] the number of output nodes\n\t */\n\tvar Tone = function(inputs, outputs){\n\n\t\t/**\n\t\t * the input node(s)\n\t\t * @type {GainNode|Array}\n\t\t */\n\t\tif (this.isUndef(inputs) || inputs === 1){\n\t\t\tthis.input = this.context.createGain();\n\t\t} else if (inputs > 1){\n\t\t\tthis.input = new Array(inputs);\n\t\t}\n\n\t\t/**\n\t\t * the output node(s)\n\t\t * @type {GainNode|Array}\n\t\t */\n\t\tif (this.isUndef(outputs) || outputs === 1){\n\t\t\tthis.output = this.context.createGain();\n\t\t} else if (outputs > 1){\n\t\t\tthis.output = new Array(inputs);\n\t\t}\n\t};\n\n\t/**\n\t * Set the parameters at once. Either pass in an\n\t * object mapping parameters to values, or to set a\n\t * single parameter, by passing in a string and value.\n\t * The last argument is an optional ramp time which \n\t * will ramp any signal values to their destination value\n\t * over the duration of the rampTime.\n\t * @param {Object|string} params\n\t * @param {number=} value\n\t * @param {Time=} rampTime\n\t * @returns {Tone} this\n\t * @example\n\t * //set values using an object\n\t * filter.set({\n\t * \t\"frequency\" : 300,\n\t * \t\"type\" : highpass\n\t * });\n\t * @example\n\t * filter.set(\"type\", \"highpass\");\n\t * @example\n\t * //ramp to the value 220 over 3 seconds. \n\t * oscillator.set({\n\t * \t\"frequency\" : 220\n\t * }, 3);\n\t */\n\tTone.prototype.set = function(params, value, rampTime){\n\t\tif (this.isObject(params)){\n\t\t\trampTime = value;\n\t\t} else if (this.isString(params)){\n\t\t\tvar tmpObj = {};\n\t\t\ttmpObj[params] = value;\n\t\t\tparams = tmpObj;\n\t\t}\n\n\t\tparamLoop:\n\t\tfor (var attr in params){\n\t\t\tvalue = params[attr];\n\t\t\tvar parent = this;\n\t\t\tif (attr.indexOf(\".\") !== -1){\n\t\t\t\tvar attrSplit = attr.split(\".\");\n\t\t\t\tfor (var i = 0; i < attrSplit.length - 1; i++){\n\t\t\t\t\tparent = parent[attrSplit[i]];\n\t\t\t\t\tif (parent instanceof Tone) {\n\t\t\t\t\t\tattrSplit.splice(0,i+1);\n\t\t\t\t\t\tvar innerParam = attrSplit.join(\".\");\n\t\t\t\t\t\tparent.set(innerParam, value);\n\t\t\t\t\t\tcontinue paramLoop;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tattr = attrSplit[attrSplit.length - 1];\n\t\t\t}\n\t\t\tvar param = parent[attr];\n\t\t\tif (this.isUndef(param)){\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tif ((Tone.Signal && param instanceof Tone.Signal) || \n\t\t\t\t\t(Tone.Param && param instanceof Tone.Param)){\n\t\t\t\tif (param.value !== value){\n\t\t\t\t\tif (this.isUndef(rampTime)){\n\t\t\t\t\t\tparam.value = value;\n\t\t\t\t\t} else {\n\t\t\t\t\t\tparam.rampTo(value, rampTime);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} else if (param instanceof AudioParam){\n\t\t\t\tif (param.value !== value){\n\t\t\t\t\tparam.value = value;\n\t\t\t\t}\t\t\t\t\n\t\t\t} else if (param instanceof Tone){\n\t\t\t\tparam.set(value);\n\t\t\t} else if (param !== value){\n\t\t\t\tparent[attr] = value;\n\t\t\t}\n\t\t}\n\t\treturn this;\n\t};\n\n\t/**\n\t * Get the object's attributes. Given no arguments get\n\t * will return all available object properties and their corresponding\n\t * values. Pass in a single attribute to retrieve or an array\n\t * of attributes. The attribute strings can also include a \".\"\n\t * to access deeper properties.\n\t * @example\n\t * osc.get();\n\t * //returns {\"type\" : \"sine\", \"frequency\" : 440, ...etc}\n\t * @example\n\t * osc.get(\"type\");\n\t * //returns { \"type\" : \"sine\"}\n\t * @example\n\t * //use dot notation to access deep properties\n\t * synth.get([\"envelope.attack\", \"envelope.release\"]);\n\t * //returns {\"envelope\" : {\"attack\" : 0.2, \"release\" : 0.4}}\n\t * @param {Array=|string|undefined} params the parameters to get, otherwise will return \n\t * \t\t\t\t\t all available.\n\t * @returns {Object}\n\t */\n\tTone.prototype.get = function(params){\n\t\tif (this.isUndef(params)){\n\t\t\tparams = this._collectDefaults(this.constructor);\n\t\t} else if (this.isString(params)){\n\t\t\tparams = [params];\n\t\t} \n\t\tvar ret = {};\n\t\tfor (var i = 0; i < params.length; i++){\n\t\t\tvar attr = params[i];\n\t\t\tvar parent = this;\n\t\t\tvar subRet = ret;\n\t\t\tif (attr.indexOf(\".\") !== -1){\n\t\t\t\tvar attrSplit = attr.split(\".\");\n\t\t\t\tfor (var j = 0; j < attrSplit.length - 1; j++){\n\t\t\t\t\tvar subAttr = attrSplit[j];\n\t\t\t\t\tsubRet[subAttr] = subRet[subAttr] || {};\n\t\t\t\t\tsubRet = subRet[subAttr];\n\t\t\t\t\tparent = parent[subAttr];\n\t\t\t\t}\n\t\t\t\tattr = attrSplit[attrSplit.length - 1];\n\t\t\t}\n\t\t\tvar param = parent[attr];\n\t\t\tif (this.isObject(params[attr])){\n\t\t\t\tsubRet[attr] = param.get();\n\t\t\t} else if (Tone.Signal && param instanceof Tone.Signal){\n\t\t\t\tsubRet[attr] = param.value;\n\t\t\t} else if (Tone.Param && param instanceof Tone.Param){\n\t\t\t\tsubRet[attr] = param.value;\n\t\t\t} else if (param instanceof AudioParam){\n\t\t\t\tsubRet[attr] = param.value;\n\t\t\t} else if (param instanceof Tone){\n\t\t\t\tsubRet[attr] = param.get();\n\t\t\t} else if (!this.isFunction(param) && !this.isUndef(param)){\n\t\t\t\tsubRet[attr] = param;\n\t\t\t} \n\t\t}\n\t\treturn ret;\n\t};\n\n\t/**\n\t * collect all of the default attributes in one\n\t * @private\n\t * @param {function} constr the constructor to find the defaults from\n\t * @return {Array} all of the attributes which belong to the class\n\t */\n\tTone.prototype._collectDefaults = function(constr){\n\t\tvar ret = [];\n\t\tif (!this.isUndef(constr.defaults)){\n\t\t\tret = Object.keys(constr.defaults);\n\t\t}\n\t\tif (!this.isUndef(constr._super)){\n\t\t\tvar superDefs = this._collectDefaults(constr._super);\n\t\t\t//filter out repeats\n\t\t\tfor (var i = 0; i < superDefs.length; i++){\n\t\t\t\tif (ret.indexOf(superDefs[i]) === -1){\n\t\t\t\t\tret.push(superDefs[i]);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\treturn ret;\n\t};\n\n\t/**\n\t * @returns {string} returns the name of the class as a string\n\t */\n\tTone.prototype.toString = function(){\n\t\tfor (var className in Tone){\n\t\t\tvar isLetter = className[0].match(/^[A-Z]$/);\n\t\t\tvar sameConstructor = Tone[className] === this.constructor;\n\t\t\tif (this.isFunction(Tone[className]) && isLetter && sameConstructor){\n\t\t\t\treturn className;\n\t\t\t}\n\t\t}\n\t\treturn \"Tone\";\n\t};\n\n\t///////////////////////////////////////////////////////////////////////////\n\t//\tCLASS VARS\n\t///////////////////////////////////////////////////////////////////////////\n\n\t/**\n\t * The number of inputs feeding into the AudioNode. \n\t * For source nodes, this will be 0.\n\t * @memberOf Tone#\n\t * @name numberOfInputs\n\t * @readOnly\n\t */\n\tObject.defineProperty(Tone.prototype, \"numberOfInputs\", {\n\t\tget : function(){\n\t\t\tif (this.input){\n\t\t\t\tif (this.isArray(this.input)){\n\t\t\t\t\treturn this.input.length;\n\t\t\t\t} else {\n\t\t\t\t\treturn 1;\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\treturn 0;\n\t\t\t}\n\t\t}\n\t});\n\n\t/**\n\t * The number of outputs coming out of the AudioNode. \n\t * For source nodes, this will be 0.\n\t * @memberOf Tone#\n\t * @name numberOfInputs\n\t * @readOnly\n\t */\n\tObject.defineProperty(Tone.prototype, \"numberOfOutputs\", {\n\t\tget : function(){\n\t\t\tif (this.output){\n\t\t\t\tif (this.isArray(this.output)){\n\t\t\t\t\treturn this.output.length;\n\t\t\t\t} else {\n\t\t\t\t\treturn 1;\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\treturn 0;\n\t\t\t}\n\t\t}\n\t});\n\t\n\t///////////////////////////////////////////////////////////////////////////\n\t//\tCONNECTIONS\n\t///////////////////////////////////////////////////////////////////////////\n\n\t/**\n\t * disconnect and dispose\n\t * @returns {Tone} this\n\t */\n\tTone.prototype.dispose = function(){\n\t\tif (!this.isUndef(this.input)){\n\t\t\tif (this.input instanceof AudioNode){\n\t\t\t\tthis.input.disconnect();\n\t\t\t} \n\t\t\tthis.input = null;\n\t\t}\n\t\tif (!this.isUndef(this.output)){\n\t\t\tif (this.output instanceof AudioNode){\n\t\t\t\tthis.output.disconnect();\n\t\t\t} \n\t\t\tthis.output = null;\n\t\t}\n\t\treturn this;\n\t};\n\n\t/**\n\t * connect the output of a ToneNode to an AudioParam, AudioNode, or ToneNode\n\t * @param {Tone | AudioParam | AudioNode} unit \n\t * @param {number} [outputNum=0] optionally which output to connect from\n\t * @param {number} [inputNum=0] optionally which input to connect to\n\t * @returns {Tone} this\n\t */\n\tTone.prototype.connect = function(unit, outputNum, inputNum){\n\t\tif (Array.isArray(this.output)){\n\t\t\toutputNum = this.defaultArg(outputNum, 0);\n\t\t\tthis.output[outputNum].connect(unit, 0, inputNum);\n\t\t} else {\n\t\t\tthis.output.connect(unit, outputNum, inputNum);\n\t\t}\n\t\treturn this;\n\t};\n\n\t/**\n\t * disconnect the output\n\t * @param {Number|AudioNode} output Either the output index to disconnect\n\t * if the output is an array, or the\n\t * node to disconnect from.\n\t * @returns {Tone} this\n\t */\n\tTone.prototype.disconnect = function(destination, outputNum, inputNum){\n\t\tif (this.isArray(this.output)){\n\t\t\tif (this.isNumber(destination)){\n\t\t\t\tthis.output[destination].disconnect();\n\t\t\t} else {\n\t\t\t\toutputNum = this.defaultArg(outputNum, 0);\n\t\t\t\tthis.output[outputNum].disconnect(destination, 0, inputNum);\n\t\t\t}\n\t\t} else {\n\t\t\tthis.output.disconnect.apply(this.output, arguments);\n\t\t}\n\t};\n\n\t/**\n\t * connect together all of the arguments in series\n\t * @param {...AudioParam|Tone|AudioNode} nodes\n\t * @returns {Tone} this\n\t */\n\tTone.prototype.connectSeries = function(){\n\t\tif (arguments.length > 1){\n\t\t\tvar currentUnit = arguments[0];\n\t\t\tfor (var i = 1; i < arguments.length; i++){\n\t\t\t\tvar toUnit = arguments[i];\n\t\t\t\tcurrentUnit.connect(toUnit);\n\t\t\t\tcurrentUnit = toUnit;\n\t\t\t}\n\t\t}\n\t\treturn this;\n\t};\n\n\t/**\n\t * Connect the output of this node to the rest of the nodes in series.\n\t * @example\n\t * //connect a node to an effect, panVol and then to the master output\n\t * node.chain(effect, panVol, Tone.Master);\n\t * @param {...AudioParam|Tone|AudioNode} nodes\n\t * @returns {Tone} this\n\t */\n\tTone.prototype.chain = function(){\n\t\tif (arguments.length > 0){\n\t\t\tvar currentUnit = this;\n\t\t\tfor (var i = 0; i < arguments.length; i++){\n\t\t\t\tvar toUnit = arguments[i];\n\t\t\t\tcurrentUnit.connect(toUnit);\n\t\t\t\tcurrentUnit = toUnit;\n\t\t\t}\n\t\t}\n\t\treturn this;\n\t};\n\n\t/**\n\t * connect the output of this node to the rest of the nodes in parallel.\n\t * @param {...AudioParam|Tone|AudioNode} nodes\n\t * @returns {Tone} this\n\t */\n\tTone.prototype.fan = function(){\n\t\tif (arguments.length > 0){\n\t\t\tfor (var i = 0; i < arguments.length; i++){\n\t\t\t\tthis.connect(arguments[i]);\n\t\t\t}\n\t\t}\n\t\treturn this;\n\t};\n\n\t//give native nodes chain and fan methods\n\tAudioNode.prototype.chain = Tone.prototype.chain;\n\tAudioNode.prototype.fan = Tone.prototype.fan;\n\n\t///////////////////////////////////////////////////////////////////////////\n\t//\tUTILITIES / HELPERS / MATHS\n\t///////////////////////////////////////////////////////////////////////////\n\n\t/**\n\t * If the `given` parameter is undefined, use the `fallback`. \n\t * If both `given` and `fallback` are object literals, it will\n\t * return a deep copy which includes all of the parameters from both \n\t * objects. If a parameter is undefined in given, it will return\n\t * the fallback property. \n\t *
\n\t * WARNING: if object is self referential, it will go into an an \n\t * infinite recursive loop.\n\t * \n\t * @param {*} given \n\t * @param {*} fallback \n\t * @return {*} \n\t */\n\tTone.prototype.defaultArg = function(given, fallback){\n\t\tif (this.isObject(given) && this.isObject(fallback)){\n\t\t\tvar ret = {};\n\t\t\t//make a deep copy of the given object\n\t\t\tfor (var givenProp in given) {\n\t\t\t\tret[givenProp] = this.defaultArg(fallback[givenProp], given[givenProp]);\n\t\t\t}\n\t\t\tfor (var fallbackProp in fallback) {\n\t\t\t\tret[fallbackProp] = this.defaultArg(given[fallbackProp], fallback[fallbackProp]);\n\t\t\t}\n\t\t\treturn ret;\n\t\t} else {\n\t\t\treturn this.isUndef(given) ? fallback : given;\n\t\t}\n\t};\n\n\t/**\n\t * returns the args as an options object with given arguments\n\t * mapped to the names provided. \n\t *\n\t * if the args given is an array containing only one object, it is assumed\n\t * that that's already the options object and will just return it. \n\t * \n\t * @param {Array} values the 'arguments' object of the function\n\t * @param {Array} keys the names of the arguments as they\n\t * should appear in the options object\n\t * @param {Object=} defaults optional defaults to mixin to the returned \n\t * options object \n\t * @return {Object} the options object with the names mapped to the arguments\n\t */\n\tTone.prototype.optionsObject = function(values, keys, defaults){\n\t\tvar options = {};\n\t\tif (values.length === 1 && this.isObject(values[0])){\n\t\t\toptions = values[0];\n\t\t} else {\n\t\t\tfor (var i = 0; i < keys.length; i++){\n\t\t\t\toptions[keys[i]] = values[i];\n\t\t\t}\n\t\t}\n\t\tif (!this.isUndef(defaults)){\n\t\t\treturn this.defaultArg(options, defaults);\n\t\t} else {\n\t\t\treturn options;\n\t\t}\n\t};\n\n\t///////////////////////////////////////////////////////////////////////////\n\t// TYPE CHECKING\n\t///////////////////////////////////////////////////////////////////////////\n\n\t/**\n\t * test if the arg is undefined\n\t * @param {*} arg the argument to test\n\t * @returns {boolean} true if the arg is undefined\n\t * @function\n\t */\n\tTone.prototype.isUndef = function(val){\n\t\treturn typeof val === \"undefined\";\n\t};\n\n\t/**\n\t * test if the arg is a function\n\t * @param {*} arg the argument to test\n\t * @returns {boolean} true if the arg is a function\n\t * @function\n\t */\n\tTone.prototype.isFunction = function(val){\n\t\treturn typeof val === \"function\";\n\t};\n\n\t/**\n\t * Test if the argument is a number.\n\t * @param {*} arg the argument to test\n\t * @returns {boolean} true if the arg is a number\n\t */\n\tTone.prototype.isNumber = function(arg){\n\t\treturn (typeof arg === \"number\");\n\t};\n\n\t/**\n\t * Test if the given argument is an object literal (i.e. `{}`);\n\t * @param {*} arg the argument to test\n\t * @returns {boolean} true if the arg is an object literal.\n\t */\n\tTone.prototype.isObject = function(arg){\n\t\treturn (Object.prototype.toString.call(arg) === \"[object Object]\" && arg.constructor === Object);\n\t};\n\n\t/**\n\t * Test if the argument is a boolean.\n\t * @param {*} arg the argument to test\n\t * @returns {boolean} true if the arg is a boolean\n\t */\n\tTone.prototype.isBoolean = function(arg){\n\t\treturn (typeof arg === \"boolean\");\n\t};\n\n\t/**\n\t * Test if the argument is an Array\n\t * @param {*} arg the argument to test\n\t * @returns {boolean} true if the arg is an array\n\t */\n\tTone.prototype.isArray = function(arg){\n\t\treturn (Array.isArray(arg));\n\t};\n\n\t/**\n\t * Test if the argument is a string.\n\t * @param {*} arg the argument to test\n\t * @returns {boolean} true if the arg is a string\n\t */\n\tTone.prototype.isString = function(arg){\n\t\treturn (typeof arg === \"string\");\n\t};\n\n \t/**\n\t * An empty function.\n\t * @static\n\t */\n\tTone.noOp = function(){};\n\n\t/**\n\t * Make the property not writable. Internal use only. \n\t * @private\n\t * @param {string} property the property to make not writable\n\t */\n\tTone.prototype._readOnly = function(property){\n\t\tif (Array.isArray(property)){\n\t\t\tfor (var i = 0; i < property.length; i++){\n\t\t\t\tthis._readOnly(property[i]);\n\t\t\t}\n\t\t} else {\n\t\t\tObject.defineProperty(this, property, { \n\t\t\t\twritable: false,\n\t\t\t\tenumerable : true,\n\t\t\t});\n\t\t}\n\t};\n\n\t/**\n\t * Make an attribute writeable. Interal use only. \n\t * @private\n\t * @param {string} property the property to make writable\n\t */\n\tTone.prototype._writable = function(property){\n\t\tif (Array.isArray(property)){\n\t\t\tfor (var i = 0; i < property.length; i++){\n\t\t\t\tthis._writable(property[i]);\n\t\t\t}\n\t\t} else {\n\t\t\tObject.defineProperty(this, property, { \n\t\t\t\twritable: true,\n\t\t\t});\n\t\t}\n\t};\n\n\t/**\n\t * Possible play states. \n\t * @enum {string}\n\t */\n\tTone.State = {\n\t\tStarted : \"started\",\n\t\tStopped : \"stopped\",\n\t\tPaused : \"paused\",\n \t};\n\n\t///////////////////////////////////////////////////////////////////////////\n\t// CONVERSIONS\n\t///////////////////////////////////////////////////////////////////////////\n\n\t/**\n\t * Equal power gain scale. Good for cross-fading.\n\t * @param {NormalRange} percent (0-1)\n\t * @return {Number} output gain (0-1)\n\t */\n\tTone.prototype.equalPowerScale = function(percent){\n\t\tvar piFactor = 0.5 * Math.PI;\n\t\treturn Math.sin(percent * piFactor);\n\t};\n\n\t/**\n\t * Convert decibels into gain.\n\t * @param {Decibels} db\n\t * @return {Number} \n\t */\n\tTone.prototype.dbToGain = function(db) {\n\t\treturn Math.pow(2, db / 6);\n\t};\n\n\t/**\n\t * Convert gain to decibels.\n\t * @param {Number} gain (0-1)\n\t * @return {Decibels} \n\t */\n\tTone.prototype.gainToDb = function(gain) {\n\t\treturn 20 * (Math.log(gain) / Math.LN10);\n\t};\n\n\t/**\n\t * Convert an interval (in semitones) to a frequency ratio.\n\t * @param {Interval} interval the number of semitones above the base note\n\t * @return {number} the frequency ratio\n\t * @example\n\t * tone.intervalToFrequencyRatio(0); // 1\n\t * tone.intervalToFrequencyRatio(12); // 2\n\t * tone.intervalToFrequencyRatio(-12); // 0.5\n\t */\n\tTone.prototype.intervalToFrequencyRatio = function(interval){\n\t\treturn Math.pow(2,(interval/12));\n\t};\n\n\t///////////////////////////////////////////////////////////////////////////\n\t//\tTIMING\n\t///////////////////////////////////////////////////////////////////////////\n\n\t/**\n\t * Return the current time of the AudioContext clock.\n\t * @return {Number} the currentTime from the AudioContext\n\t */\n\tTone.prototype.now = function(){\n\t\treturn Tone.context.now();\n\t};\n\n\t/**\n\t * Return the current time of the AudioContext clock.\n\t * @return {Number} the currentTime from the AudioContext\n\t * @static\n\t */\n\tTone.now = function(){\n\t\treturn Tone.context.now();\n\t};\n\n\t///////////////////////////////////////////////////////////////////////////\n\t//\tINHERITANCE\n\t///////////////////////////////////////////////////////////////////////////\n\n\t/**\n\t * have a child inherit all of Tone's (or a parent's) prototype\n\t * to inherit the parent's properties, make sure to call \n\t * Parent.call(this) in the child's constructor\n\t *\n\t * based on closure library's inherit function\n\t *\n\t * @static\n\t * @param {function} \tchild \n\t * @param {function=} parent (optional) parent to inherit from\n\t * if no parent is supplied, the child\n\t * will inherit from Tone\n\t */\n\tTone.extend = function(child, parent){\n\t\tif (Tone.prototype.isUndef(parent)){\n\t\t\tparent = Tone;\n\t\t}\n\t\tfunction TempConstructor(){}\n\t\tTempConstructor.prototype = parent.prototype;\n\t\tchild.prototype = new TempConstructor();\n\t\t/** @override */\n\t\tchild.prototype.constructor = child;\n\t\tchild._super = parent;\n\t};\n\n\t///////////////////////////////////////////////////////////////////////////\n\t//\tCONTEXT\n\t///////////////////////////////////////////////////////////////////////////\n\n\t/**\n\t * The private audio context shared by all Tone Nodes. \n\t * @private\n\t * @type {Tone.Context|undefined}\n\t */\n\tvar audioContext;\n\n\t/**\n\t * A static pointer to the audio context accessible as Tone.context. \n\t * @type {Tone.Context}\n\t * @name context\n\t * @memberOf Tone\n\t */\n\tObject.defineProperty(Tone, \"context\", {\n\t\tget : function(){\n\t\t\treturn audioContext;\n\t\t},\n\t\tset : function(context){\n\t\t\tif (Tone.Context && context instanceof Tone.Context){\n\t\t\t\taudioContext = context;\n\t\t\t} else {\n\t\t\t\taudioContext = new Tone.Context(context);\n\t\t\t}\n\t\t\t//initialize the new audio context\n\t\t\tif (Tone.Context){\n\t\t\t\tTone.Context.emit(\"init\", audioContext);\n\t\t\t}\n\t\t}\n\t});\n\n\t/**\n\t * The AudioContext\n\t * @type {Tone.Context}\n\t * @name context\n\t * @memberOf Tone#\n\t * @readOnly\n\t */\n\tObject.defineProperty(Tone.prototype, \"context\", {\n\t\tget : function(){\n\t\t\treturn Tone.context;\n\t\t}\n\t});\n\n\t/**\n\t * Tone automatically creates a context on init, but if you are working\n\t * with other libraries which also create an AudioContext, it can be\n\t * useful to set your own. If you are going to set your own context, \n\t * be sure to do it at the start of your code, before creating any objects.\n\t * @static\n\t * @param {AudioContext} ctx The new audio context to set\n\t */\n\tTone.setContext = function(ctx){\n\t\tTone.context = ctx;\n\t};\n\n\t/**\n\t * The number of seconds of 1 processing block (128 samples)\n\t * @type {Number}\n\t * @name blockTime\n\t * @memberOf Tone#\n\t * @readOnly\n\t */\n\tObject.defineProperty(Tone.prototype, \"blockTime\", {\n\t\tget : function(){\n\t\t\treturn 128 / this.context.sampleRate;\n\t\t}\n\t});\n\n\t/**\n\t * The duration in seconds of one sample.\n\t * @type {Number}\n\t * @name sampleTime\n\t * @memberOf Tone#\n\t * @readOnly\n\t */\n\tObject.defineProperty(Tone.prototype, \"sampleTime\", {\n\t\tget : function(){\n\t\t\treturn 1 / this.context.sampleRate;\n\t\t}\n\t});\n\n\t/**\n\t * Whether or not all the technologies that Tone.js relies on are supported by the current browser. \n\t * @type {Boolean}\n\t * @name supported\n\t * @memberOf Tone\n\t * @readOnly\n\t */\n\tObject.defineProperty(Tone, \"supported\", {\n\t\tget : function(){\n\t\t\tvar hasAudioContext = window.hasOwnProperty(\"AudioContext\") || window.hasOwnProperty(\"webkitAudioContext\");\n\t\t\tvar hasPromises = window.hasOwnProperty(\"Promise\");\n\t\t\tvar hasWorkers = window.hasOwnProperty(\"Worker\");\n\t\t\treturn hasAudioContext && hasPromises && hasWorkers;\n\t\t}\n\t});\n\n\tTone.version = \"r10\";\n\n\t// allow optional silencing of this log\n\tif (!window.TONE_SILENCE_VERSION_LOGGING) {\n\t\tconsole.log(\"%c * Tone.js \" + Tone.version + \" * \", \"background: #000; color: #fff\");\n\t}\n\n\treturn Tone;\n});\n","'use strict';\n\n\ndefine(['audiocontext'], function (audiocontext) {\n /**\n * Master contains AudioContext and the master sound output.\n * @for p5\n */\n var Master = function() {\n this.input = audiocontext.createGain();\n this.output = audiocontext.createGain();\n\n //put a hard limiter on the output\n this.limiter = audiocontext.createDynamicsCompressor();\n this.limiter.threshold.value = -3;\n this.limiter.ratio.value = 20;\n this.limiter.knee.value = 1;\n\n this.audiocontext = audiocontext;\n\n this.output.disconnect();\n\n // connect input to limiter\n this.input.connect(this.limiter);\n\n // connect limiter to output\n this.limiter.connect(this.output);\n\n // meter is just for global Amplitude / FFT analysis\n this.meter = audiocontext.createGain();\n this.fftMeter = audiocontext.createGain();\n this.output.connect(this.meter);\n this.output.connect(this.fftMeter);\n\n // connect output to destination\n this.output.connect(this.audiocontext.destination);\n\n // an array of all sounds in the sketch\n this.soundArray = [];\n // an array of all musical parts in the sketch\n this.parts = [];\n\n // file extensions to search for\n this.extensions = [];\n };\n\n // create a single instance of the p5Sound / master output for use within this sketch\n var p5sound = new Master();\n\n /**\n * Returns a number representing the master amplitude (volume) for sound\n * in this sketch.\n *\n * @method getMasterVolume\n * @return {Number} Master amplitude (volume) for sound in this sketch.\n * Should be between 0.0 (silence) and 1.0.\n */\n p5.prototype.getMasterVolume = function() {\n return p5sound.output.gain.value;\n };\n\n /**\n *
Scale the output of all sound in this sketch
\n * Scaled between 0.0 (silence) and 1.0 (full volume).\n * 1.0 is the maximum amplitude of a digital sound, so multiplying\n * by greater than 1.0 may cause digital distortion. To\n * fade, provide a rampTime parameter. For more\n * complex fades, see the Envelope class.\n *\n * Alternately, you can pass in a signal source such as an\n * oscillator to modulate the amplitude with an audio signal.\n *\n *
How This Works: When you load the p5.sound module, it\n * creates a single instance of p5sound. All sound objects in this\n * module output to p5sound before reaching your computer's output.\n * So if you change the amplitude of p5sound, it impacts all of the\n * sound in this module.
\n *\n *
If no value is provided, returns a Web Audio API Gain Node
\n *\n * @method masterVolume\n * @param {Number|Object} volume Volume (amplitude) between 0.0\n * and 1.0 or modulating signal/oscillator\n * @param {Number} [rampTime] Fade for t seconds\n * @param {Number} [timeFromNow] Schedule this event to happen at\n * t seconds in the future\n */\n p5.prototype.masterVolume = function(vol, rampTime, tFromNow) {\n if (typeof vol === 'number') {\n var rampTime = rampTime || 0;\n var tFromNow = tFromNow || 0;\n var now = p5sound.audiocontext.currentTime;\n var currentVol = p5sound.output.gain.value;\n p5sound.output.gain.cancelScheduledValues(now + tFromNow);\n p5sound.output.gain.linearRampToValueAtTime(currentVol, now + tFromNow);\n p5sound.output.gain.linearRampToValueAtTime(vol, now + tFromNow + rampTime);\n }\n else if (vol) {\n vol.connect(p5sound.output.gain);\n } else {\n // return the Gain Node\n return p5sound.output.gain;\n }\n };\n\n /**\n * `p5.soundOut` is the p5.sound master output. It sends output to\n * the destination of this window's web audio context. It contains\n * Web Audio API nodes including a dyanmicsCompressor (.limiter),\n * and Gain Nodes for .input and .output.\n *\n * @property {Object} soundOut\n */\n p5.prototype.soundOut = p5.soundOut = p5sound;\n\n /**\n * a silent connection to the DesinationNode\n * which will ensure that anything connected to it\n * will not be garbage collected\n *\n * @private\n */\n p5.soundOut._silentNode = p5sound.audiocontext.createGain();\n p5.soundOut._silentNode.gain.value = 0;\n p5.soundOut._silentNode.connect(p5sound.audiocontext.destination);\n\n\n return p5sound;\n});\n","define([\"Tone/core/Tone\", \"Tone/signal/WaveShaper\", \"Tone/type/Type\", \"Tone/core/Param\", \"Tone/core/Gain\"], function(Tone){\n\n\t\"use strict\";\n\n\t/**\n\t * @class A signal is an audio-rate value. Tone.Signal is a core component of the library.\n\t * Unlike a number, Signals can be scheduled with sample-level accuracy. Tone.Signal\n\t * has all of the methods available to native Web Audio \n\t * [AudioParam](http://webaudio.github.io/web-audio-api/#the-audioparam-interface)\n\t * as well as additional conveniences. Read more about working with signals \n\t * [here](https://github.com/Tonejs/Tone.js/wiki/Signals).\n\t *\n\t * @constructor\n\t * @extends {Tone.Param}\n\t * @param {Number|AudioParam} [value] Initial value of the signal. If an AudioParam\n\t * is passed in, that parameter will be wrapped\n\t * and controlled by the Signal. \n\t * @param {string} [units=Number] unit The units the signal is in. \n\t * @example\n\t * var signal = new Tone.Signal(10);\n\t */\n\tTone.Signal = function(){\n\n\t\tvar options = this.optionsObject(arguments, [\"value\", \"units\"], Tone.Signal.defaults);\n\n\t\t/**\n\t\t * The node where the constant signal value is scaled.\n\t\t * @type {GainNode}\n\t\t * @private\n\t\t */\n\t\tthis.output = this._gain = this.context.createGain();\n\n\t\toptions.param = this._gain.gain;\n\t\tTone.Param.call(this, options);\n\n\t\t/**\n\t\t * The node where the value is set.\n\t\t * @type {Tone.Param}\n\t\t * @private\n\t\t */\n\t\tthis.input = this._param = this._gain.gain;\n\n\t\t//connect the const output to the node output\n\t\tthis.context.getConstant(1).chain(this._gain);\n\t};\n\n\tTone.extend(Tone.Signal, Tone.Param);\n\n\t/**\n\t * The default values\n\t * @type {Object}\n\t * @static\n\t * @const\n\t */\n\tTone.Signal.defaults = {\n\t\t\"value\" : 0,\n\t\t\"units\" : Tone.Type.Default,\n\t\t\"convert\" : true,\n\t};\n\n\t/**\n\t * When signals connect to other signals or AudioParams, \n\t * they take over the output value of that signal or AudioParam. \n\t * For all other nodes, the behavior is the same as a default connect. \n\t *\n\t * @override\n\t * @param {AudioParam|AudioNode|Tone.Signal|Tone} node \n\t * @param {number} [outputNumber=0] The output number to connect from.\n\t * @param {number} [inputNumber=0] The input number to connect to.\n\t * @returns {Tone.SignalBase} this\n\t * @method\n\t */\n\tTone.Signal.prototype.connect = Tone.SignalBase.prototype.connect;\n\n\t/**\n\t * dispose and disconnect\n\t * @returns {Tone.Signal} this\n\t */\n\tTone.Signal.prototype.dispose = function(){\n\t\tTone.Param.prototype.dispose.call(this);\n\t\tthis._param = null;\n\t\tthis._gain.disconnect();\n\t\tthis._gain = null;\n\t\treturn this;\n\t};\n\n\treturn Tone.Signal;\n});","define([\"Tone/core/Tone\", \"Tone/signal/Signal\", \"Tone/core/Gain\"], function(Tone){\n\n\t\"use strict\";\n\n\t/**\n\t * @class Multiply two incoming signals. Or, if a number is given in the constructor, \n\t * multiplies the incoming signal by that value. \n\t *\n\t * @constructor\n\t * @extends {Tone.Signal}\n\t * @param {number=} value Constant value to multiple. If no value is provided,\n\t * it will return the product of the first and second inputs\n\t * @example\n\t * var mult = new Tone.Multiply();\n\t * var sigA = new Tone.Signal(3);\n\t * var sigB = new Tone.Signal(4);\n\t * sigA.connect(mult, 0, 0);\n\t * sigB.connect(mult, 0, 1);\n\t * //output of mult is 12.\n\t * @example\n\t * var mult = new Tone.Multiply(10);\n\t * var sig = new Tone.Signal(2).connect(mult);\n\t * //the output of mult is 20. \n\t */\n\tTone.Multiply = function(value){\n\n\t\tthis.createInsOuts(2, 0);\n\n\t\t/**\n\t\t * the input node is the same as the output node\n\t\t * it is also the GainNode which handles the scaling of incoming signal\n\t\t * \n\t\t * @type {GainNode}\n\t\t * @private\n\t\t */\n\t\tthis._mult = this.input[0] = this.output = new Tone.Gain();\n\n\t\t/**\n\t\t * the scaling parameter\n\t\t * @type {AudioParam}\n\t\t * @private\n\t\t */\n\t\tthis._param = this.input[1] = this.output.gain;\n\t\t\n\t\tthis._param.value = this.defaultArg(value, 0);\n\t};\n\n\tTone.extend(Tone.Multiply, Tone.Signal);\n\n\t/**\n\t * clean up\n\t * @returns {Tone.Multiply} this\n\t */\n\tTone.Multiply.prototype.dispose = function(){\n\t\tTone.prototype.dispose.call(this);\n\t\tthis._mult.dispose();\n\t\tthis._mult = null;\n\t\tthis._param = null;\n\t\treturn this;\n\t}; \n\n\treturn Tone.Multiply;\n});\n","'use strict';\ndefine(function (require) {\n\n var p5sound = require('master');\n var CrossFade = require('Tone/component/CrossFade');\n\n /**\n * Effect is a base class for audio effects in p5. \n * This module handles the nodes and methods that are\n * common and useful for current and future effects.\n *\n *\n * This class is extended by p5.Distortion,\n * p5.Compressor,\n * p5.Delay,\n * p5.Filter,\n * p5.Reverb.\n *\n * @class p5.Effect\n * @constructor\n *\n * @param {Object} [ac] Reference to the audio context of the p5 object\n * @param {AudioNode} [input] Gain Node effect wrapper\n * @param {AudioNode} [output] Gain Node effect wrapper\n * @param {Object} [_drywet] Tone.JS CrossFade node (defaults to value: 1)\n * @param {AudioNode} [wet] Effects that extend this class should connect\n * to the wet signal to this gain node, so that dry and wet\n * signals are mixed properly.\n */\n p5.Effect = function() {\n this.ac = p5sound.audiocontext;\n\n this.input = this.ac.createGain();\n this.output = this.ac.createGain();\n\n /**\n *\tThe p5.Effect class is built\n * \tusing Tone.js CrossFade\n * \t@private\n */\n\n this._drywet = new CrossFade(1);\n\n /**\n *\tIn classes that extend\n *\tp5.Effect, connect effect nodes\n *\tto the wet parameter\n */\n this.wet = this.ac.createGain();\n\n this.input.connect(this._drywet.a);\n this.wet.connect(this._drywet.b);\n this._drywet.connect(this.output);\n\n this.connect();\n\n //Add to the soundArray\n p5sound.soundArray.push(this);\n };\n\n /**\n * Set the output volume of the filter.\n *\n * @method amp\n * @for p5.Effect\n * @param {Number} [vol] amplitude between 0 and 1.0\n * @param {Number} [rampTime] create a fade that lasts until rampTime\n * @param {Number} [tFromNow] schedule this event to happen in tFromNow seconds\n */\n p5.Effect.prototype.amp = function(vol, rampTime, tFromNow){\n var rampTime = rampTime || 0;\n var tFromNow = tFromNow || 0;\n var now = p5sound.audiocontext.currentTime;\n var currentVol = this.output.gain.value;\n this.output.gain.cancelScheduledValues(now);\n this.output.gain.linearRampToValueAtTime(currentVol, now + tFromNow + .001);\n this.output.gain.linearRampToValueAtTime(vol, now + tFromNow + rampTime + .001);\n };\n\n /**\n * Link effects together in a chain\n * Example usage: filter.chain(reverb, delay, panner);\n * May be used with an open-ended number of arguments\n *\n * @method chain\n * @for p5.Effect\n * @param {Object} [arguments] Chain together multiple sound objects\n */\n p5.Effect.prototype.chain = function(){\n if (arguments.length>0){\n this.connect(arguments[0]);\n for(var i=1;i\n * var notes = [60, 64, 67, 72];\n * var i = 0;\n *\n * function setup() {\n * osc = new p5.Oscillator('Triangle');\n * osc.start();\n * frameRate(1);\n * }\n *\n * function draw() {\n * var freq = midiToFreq(notes[i]);\n * osc.freq(freq);\n * i++;\n * if (i >= notes.length){\n * i = 0;\n * }\n * }\n * \n */\n var midiToFreq = p5.prototype.midiToFreq = function(m) {\n return 440 * Math.pow(2, (m-69)/12.0);\n };\n\n // This method converts ANSI notes specified as a string \"C4\", \"Eb3\" to a frequency\n var noteToFreq = function(note) {\n if (typeof note !== 'string') {\n return note;\n }\n var wholeNotes = {A:21, B:23, C:24, D:26, E:28, F:29, G:31};\n var value = wholeNotes[ note[0].toUpperCase() ];\n var octave = ~~note.slice(-1);\n value += 12 * (octave -1);\n\n switch(note[1]) {\n case '#':\n value += 1;\n break;\n case 'b':\n value -= 1;\n break;\n default:\n break;\n }\n return midiToFreq(value);\n };\n\n /**\n * List the SoundFile formats that you will include. LoadSound\n * will search your directory for these extensions, and will pick\n * a format that is compatable with the client's web browser.\n * Here is a free online file\n * converter.\n *\n * @method soundFormats\n * @param {String} [...formats] i.e. 'mp3', 'wav', 'ogg'\n * @example\n *
\n * function preload() {\n * // set the global sound formats\n * soundFormats('mp3', 'ogg');\n *\n * // load either beatbox.mp3, or .ogg, depending on browser\n * mySound = loadSound('assets/beatbox.mp3');\n * }\n *\n * function setup() {\n * mySound.play();\n * }\n *
\n */\n p5.prototype.soundFormats = function() {\n // reset extensions array\n p5sound.extensions = [];\n // add extensions\n for (var i = 0; i < arguments.length; i++) {\n arguments[i] = arguments[i].toLowerCase();\n if (['mp3','wav','ogg', 'm4a', 'aac'].indexOf(arguments[i]) > -1) {\n p5sound.extensions.push(arguments[i]);\n } else {\n throw arguments[i] + ' is not a valid sound format!';\n }\n }\n };\n\n p5.prototype.disposeSound = function() {\n for (var i = 0; i < p5sound.soundArray.length; i++) {\n p5sound.soundArray[i].dispose();\n }\n };\n\n // register removeSound to dispose of p5sound SoundFiles, Convolvers,\n // Oscillators etc when sketch ends\n p5.prototype.registerMethod('remove', p5.prototype.disposeSound);\n\n p5.prototype._checkFileFormats = function(paths) {\n var path;\n // if path is a single string, check to see if extension is provided\n if (typeof paths === 'string') {\n path = paths;\n // see if extension is provided\n var extTest = path.split('.').pop();\n // if an extension is provided...\n if (['mp3','wav','ogg', 'm4a', 'aac'].indexOf(extTest) > -1) {\n if (p5.prototype.isFileSupported(extTest)) {\n path = path;\n }\n else {\n var pathSplit = path.split('.');\n var pathCore = pathSplit[pathSplit.length - 1];\n for (var i = 0; i 1) {\n rightChannel = audioBuffer.getChannelData(1);\n } else {\n rightChannel = leftChannel;\n }\n\n var interleaved = interleave(leftChannel, rightChannel);\n\n // create the buffer and view to create the .WAV file\n var buffer = new window.ArrayBuffer(44 + interleaved.length * 2);\n var view = new window.DataView(buffer);\n\n // write the WAV container,\n // check spec at: https://web.archive.org/web/20171215131933/http://tiny.systems/software/soundProgrammer/WavFormatDocs.pdf\n\n // RIFF chunk descriptor\n writeUTFBytes(view, 0, 'RIFF');\n view.setUint32(4, 36 + interleaved.length * 2, true);\n writeUTFBytes(view, 8, 'WAVE');\n // FMT sub-chunk\n writeUTFBytes(view, 12, 'fmt ');\n view.setUint32(16, 16, true);\n view.setUint16(20, 1, true);\n // stereo (2 channels)\n view.setUint16(22, 2, true);\n view.setUint32(24, p5sound.audiocontext.sampleRate, true);\n view.setUint32(28, p5sound.audiocontext.sampleRate * 4, true);\n view.setUint16(32, 4, true);\n view.setUint16(34, 16, true);\n // data sub-chunk\n writeUTFBytes(view, 36, 'data');\n view.setUint32(40, interleaved.length * 2, true);\n\n // write the PCM samples\n var lng = interleaved.length;\n var index = 44;\n var volume = 1;\n for (var i = 0; i < lng; i++) {\n view.setInt16(index, interleaved[i] * (0x7FFF * volume), true);\n index += 2;\n }\n\n return view;\n }\n\n // helper methods to save waves\n function interleave(leftChannel, rightChannel) {\n var length = leftChannel.length + rightChannel.length;\n var result = new Float32Array(length);\n\n var inputIndex = 0;\n\n for (var index = 0; index < length;) {\n result[index++] = leftChannel[inputIndex];\n result[index++] = rightChannel[inputIndex];\n inputIndex++;\n }\n return result;\n }\n\n function writeUTFBytes(view, offset, string) {\n var lng = string.length;\n for (var i = 0; i < lng; i++) {\n view.setUint8(offset + i, string.charCodeAt(i));\n }\n }\n\n return {\n convertToWav: convertToWav,\n midiToFreq: midiToFreq,\n noteToFreq: noteToFreq\n };\n\n});\n","define([\"Tone/core/Tone\", \"Tone/signal/Signal\", \"Tone/core/Gain\"], function(Tone){\n\n\t\"use strict\";\n\n\t/**\n\t * @class Add a signal and a number or two signals. When no value is\n\t * passed into the constructor, Tone.Add will sum input[0]\n\t * and input[1]. If a value is passed into the constructor, \n\t * the it will be added to the input.\n\t * \n\t * @constructor\n\t * @extends {Tone.Signal}\n\t * @param {number=} value If no value is provided, Tone.Add will sum the first\n\t * and second inputs. \n\t * @example\n\t * var signal = new Tone.Signal(2);\n\t * var add = new Tone.Add(2);\n\t * signal.connect(add);\n\t * //the output of add equals 4\n\t * @example\n\t * //if constructed with no arguments\n\t * //it will add the first and second inputs\n\t * var add = new Tone.Add();\n\t * var sig0 = new Tone.Signal(3).connect(add, 0, 0);\n\t * var sig1 = new Tone.Signal(4).connect(add, 0, 1);\n\t * //the output of add equals 7. \n\t */\n\tTone.Add = function(value){\n\n\t\tthis.createInsOuts(2, 0);\n\n\t\t/**\n\t\t * the summing node\n\t\t * @type {GainNode}\n\t\t * @private\n\t\t */\n\t\tthis._sum = this.input[0] = this.input[1] = this.output = new Tone.Gain();\n\n\t\t/**\n\t\t * @private\n\t\t * @type {Tone.Signal}\n\t\t */\n\t\tthis._param = this.input[1] = new Tone.Signal(value);\n\n\t\tthis._param.connect(this._sum);\n\t};\n\n\tTone.extend(Tone.Add, Tone.Signal);\n\t\n\t/**\n\t * Clean up.\n\t * @returns {Tone.Add} this\n\t */\n\tTone.Add.prototype.dispose = function(){\n\t\tTone.prototype.dispose.call(this);\n\t\tthis._sum.dispose();\n\t\tthis._sum = null;\n\t\tthis._param.dispose();\n\t\tthis._param = null;\n\t\treturn this;\n\t}; \n\n\treturn Tone.Add;\n});","define([\"Tone/core/Tone\", \"Tone/type/Time\", \"Tone/type/Frequency\", \"Tone/type/TransportTime\", \"Tone/core/Context\"],\nfunction (Tone) {\t\n\n\t///////////////////////////////////////////////////////////////////////////\n\t//\tTYPES\n\t///////////////////////////////////////////////////////////////////////////\n\n\t/**\n\t * Units which a value can take on.\n\t * @enum {String}\n\t */\n\tTone.Type = {\n\t\t/** \n\t\t * Default units\n\t\t * @typedef {Default}\n\t\t */\n\t\tDefault : \"number\",\n\t\t/**\n\t\t * Time can be described in a number of ways. Read more [Time](https://github.com/Tonejs/Tone.js/wiki/Time).\n\t\t *\n\t\t *
\n\t\t *
Numbers, which will be taken literally as the time (in seconds).
\n\t\t *
Notation, (\"4n\", \"8t\") describes time in BPM and time signature relative values.
\n\t\t *
TransportTime, (\"4:3:2\") will also provide tempo and time signature relative times \n\t\t * in the form BARS:QUARTERS:SIXTEENTHS.
\n\t\t *
Frequency, (\"8hz\") is converted to the length of the cycle in seconds.
\n\t\t *
Now-Relative, (\"+1\") prefix any of the above with \"+\" and it will be interpreted as \n\t\t * \"the current time plus whatever expression follows\".
\n\t\t *
Expressions, (\"3:0 + 2 - (1m / 7)\") any of the above can also be combined \n\t\t * into a mathematical expression which will be evaluated to compute the desired time.
\n\t\t *
No Argument, for methods which accept time, no argument will be interpreted as \n\t\t * \"now\" (i.e. the currentTime).
\n\t\t *
\n\t\t * \n\t\t * @typedef {Time}\n\t\t */\n\t\tTime : \"time\",\n\t\t/**\n\t\t * Frequency can be described similar to time, except ultimately the\n\t\t * values are converted to frequency instead of seconds. A number\n\t\t * is taken literally as the value in hertz. Additionally any of the \n\t\t * Time encodings can be used. Note names in the form\n\t\t * of NOTE OCTAVE (i.e. C4) are also accepted and converted to their\n\t\t * frequency value. \n\t\t * @typedef {Frequency}\n\t\t */\n\t\tFrequency : \"frequency\",\n\t\t/**\n\t\t * TransportTime describes a position along the Transport's timeline. It is\n\t\t * similar to Time in that it uses all the same encodings, but TransportTime specifically\n\t\t * pertains to the Transport's timeline, which is startable, stoppable, loopable, and seekable. \n\t\t * [Read more](https://github.com/Tonejs/Tone.js/wiki/TransportTime)\n\t\t * @typedef {TransportTime}\n\t\t */\n\t\tTransportTime : \"transportTime\",\n\t\t/** \n\t\t * Ticks are the basic subunit of the Transport. They are\n\t\t * the smallest unit of time that the Transport supports.\n\t\t * @typedef {Ticks}\n\t\t */\n\t\tTicks : \"ticks\",\n\t\t/** \n\t\t * Normal values are within the range [0, 1].\n\t\t * @typedef {NormalRange}\n\t\t */\n\t\tNormalRange : \"normalRange\",\n\t\t/** \n\t\t * AudioRange values are between [-1, 1].\n\t\t * @typedef {AudioRange}\n\t\t */\n\t\tAudioRange : \"audioRange\",\n\t\t/** \n\t\t * Decibels are a logarithmic unit of measurement which is useful for volume\n\t\t * because of the logarithmic way that we perceive loudness. 0 decibels \n\t\t * means no change in volume. -10db is approximately half as loud and 10db \n\t\t * is twice is loud. \n\t\t * @typedef {Decibels}\n\t\t */\n\t\tDecibels : \"db\",\n\t\t/** \n\t\t * Half-step note increments, i.e. 12 is an octave above the root. and 1 is a half-step up.\n\t\t * @typedef {Interval}\n\t\t */\n\t\tInterval : \"interval\",\n\t\t/** \n\t\t * Beats per minute. \n\t\t * @typedef {BPM}\n\t\t */\n\t\tBPM : \"bpm\",\n\t\t/** \n\t\t * The value must be greater than or equal to 0.\n\t\t * @typedef {Positive}\n\t\t */\n\t\tPositive : \"positive\",\n\t\t/** \n\t\t * A cent is a hundredth of a semitone. \n\t\t * @typedef {Cents}\n\t\t */\n\t\tCents : \"cents\",\n\t\t/** \n\t\t * Angle between 0 and 360. \n\t\t * @typedef {Degrees}\n\t\t */\n\t\tDegrees : \"degrees\",\n\t\t/** \n\t\t * A number representing a midi note.\n\t\t * @typedef {MIDI}\n\t\t */\n\t\tMIDI : \"midi\",\n\t\t/** \n\t\t * A colon-separated representation of time in the form of\n\t\t * Bars:Beats:Sixteenths. \n\t\t * @typedef {BarsBeatsSixteenths}\n\t\t */\n\t\tBarsBeatsSixteenths : \"barsBeatsSixteenths\",\n\t\t/** \n\t\t * Sampling is the reduction of a continuous signal to a discrete signal.\n\t\t * Audio is typically sampled 44100 times per second. \n\t\t * @typedef {Samples}\n\t\t */\n\t\tSamples : \"samples\",\n\t\t/** \n\t\t * Hertz are a frequency representation defined as one cycle per second.\n\t\t * @typedef {Hertz}\n\t\t */\n\t\tHertz : \"hertz\",\n\t\t/** \n\t\t * A frequency represented by a letter name, \n\t\t * accidental and octave. This system is known as\n\t\t * [Scientific Pitch Notation](https://en.wikipedia.org/wiki/Scientific_pitch_notation).\n\t\t * @typedef {Note}\n\t\t */\n\t\tNote : \"note\",\n\t\t/** \n\t\t * One millisecond is a thousandth of a second. \n\t\t * @typedef {Milliseconds}\n\t\t */\n\t\tMilliseconds : \"milliseconds\",\n\t\t/** \n\t\t * Seconds are the time unit of the AudioContext. In the end, \n\t\t * all values need to be evaluated to seconds. \n\t\t * @typedef {Seconds}\n\t\t */\n\t\tSeconds : \"seconds\",\n\t\t/** \n\t\t * A string representing a duration relative to a measure. \n\t\t *
\n\t\t * \t
\"4n\" = quarter note
\n\t\t * \t
\"2m\" = two measures
\n\t\t * \t
\"8t\" = eighth-note triplet
\n\t\t *
\n\t\t * @typedef {Notation}\n\t\t */\n\t\tNotation : \"notation\",\n\t};\n\n\t///////////////////////////////////////////////////////////////////////////\n\t// AUGMENT TONE's PROTOTYPE\n\t///////////////////////////////////////////////////////////////////////////\n\n\t/**\n\t * Convert Time into seconds.\n\t * \n\t * Unlike the method which it overrides, this takes into account \n\t * transporttime and musical notation.\n\t *\n\t * Time : 1.40\n\t * Notation: 4n|1m|2t\n\t * Now Relative: +3n\n\t * Math: 3n+16n or even complicated expressions ((3n*2)/6 + 1)\n\t *\n\t * @param {Time} time \n\t * @return {Seconds} \n\t */\n\tTone.prototype.toSeconds = function(time){\n\t\tif (this.isNumber(time)){\n\t\t\treturn time;\n\t\t} else if (this.isUndef(time)){\n\t\t\treturn this.now();\t\t\t\n\t\t} else if (this.isString(time)){\n\t\t\treturn (new Tone.Time(time)).toSeconds();\n\t\t} else if (time instanceof Tone.TimeBase){\n\t\t\treturn time.toSeconds();\n\t\t}\n\t};\n\n\t/**\n\t * Convert a frequency representation into a number.\n\t * @param {Frequency} freq \n\t * @return {Hertz} the frequency in hertz\n\t */\n\tTone.prototype.toFrequency = function(freq){\n\t\tif (this.isNumber(freq)){\n\t\t\treturn freq;\n\t\t} else if (this.isString(freq) || this.isUndef(freq)){\n\t\t\treturn (new Tone.Frequency(freq)).valueOf();\n\t\t} else if (freq instanceof Tone.TimeBase){\n\t\t\treturn freq.toFrequency();\n\t\t}\n\t};\n\n\t/**\n\t * Convert a time representation into ticks.\n\t * @param {Time} time\n\t * @return {Ticks} the time in ticks\n\t */\n\tTone.prototype.toTicks = function(time){\n\t\tif (this.isNumber(time) || this.isString(time)){\n\t\t\treturn (new Tone.TransportTime(time)).toTicks();\n\t\t} else if (this.isUndef(time)){\n\t\t\treturn Tone.Transport.ticks;\t\t\t\n\t\t} else if (time instanceof Tone.TimeBase){\n\t\t\treturn time.toTicks();\n\t\t}\n\t};\n\n\treturn Tone;\n});","define([\"Tone/core/Tone\", \"Tone/core/Param\", \"Tone/type/Type\"], function (Tone) {\n\n\t\"use strict\";\n\n\t/**\n\t * createGain shim\n\t * @private\n\t */\n\tif (window.GainNode && !AudioContext.prototype.createGain){\n\t\tAudioContext.prototype.createGain = AudioContext.prototype.createGainNode;\n\t}\n\n\t/**\n\t * @class A thin wrapper around the Native Web Audio GainNode.\n\t * The GainNode is a basic building block of the Web Audio\n\t * API and is useful for routing audio and adjusting gains. \n\t * @extends {Tone}\n\t * @param {Number=} gain The initial gain of the GainNode\n\t * @param {Tone.Type=} units The units of the gain parameter. \n\t */\n\tTone.Gain = function(){\n\n\t\tvar options = this.optionsObject(arguments, [\"gain\", \"units\"], Tone.Gain.defaults);\n\n\t\t/**\n\t\t * The GainNode\n\t\t * @type {GainNode}\n\t\t * @private\n\t\t */\n\t\tthis.input = this.output = this._gainNode = this.context.createGain();\n\n\t\t/**\n\t\t * The gain parameter of the gain node.\n\t\t * @type {Tone.Param}\n\t\t * @signal\n\t\t */\n\t\tthis.gain = new Tone.Param({\n\t\t\t\"param\" : this._gainNode.gain, \n\t\t\t\"units\" : options.units,\n\t\t\t\"value\" : options.gain,\n\t\t\t\"convert\" : options.convert\n\t\t});\n\t\tthis._readOnly(\"gain\");\n\t};\n\n\tTone.extend(Tone.Gain);\n\n\t/**\n\t * The defaults\n\t * @const\n\t * @type {Object}\n\t */\n\tTone.Gain.defaults = {\n\t\t\"gain\" : 1,\n\t\t\"convert\" : true,\n\t};\n\n\t/**\n\t * Clean up.\n\t * @return {Tone.Gain} this\n\t */\n\tTone.Gain.prototype.dispose = function(){\n\t\tTone.Param.prototype.dispose.call(this);\n\t\tthis._gainNode.disconnect();\n\t\tthis._gainNode = null;\n\t\tthis._writable(\"gain\");\n\t\tthis.gain.dispose();\n\t\tthis.gain = null;\n\t};\n\n\t//STATIC///////////////////////////////////////////////////////////////////\n\n\t/**\n\t * Create input and outputs for this object.\n\t * @param {Number} input The number of inputs\n\t * @param {Number=} outputs The number of outputs\n\t * @return {Tone} this\n\t * @internal\n\t */\n\tTone.prototype.createInsOuts = function(inputs, outputs){\n\n\t\tif (inputs === 1){\n\t\t\tthis.input = new Tone.Gain();\n\t\t} else if (inputs > 1){\n\t\t\tthis.input = new Array(inputs);\n\t\t}\n\n\t\tif (outputs === 1){\n\t\t\tthis.output = new Tone.Gain();\n\t\t} else if (outputs > 1){\n\t\t\tthis.output = new Array(inputs);\n\t\t}\n\t};\n\n\t///////////////////////////////////////////////////////////////////////////\n\n\treturn Tone.Gain;\n});","'use strict';\n\ndefine(function () {\n /*\n Helper function to generate an error\n with a custom stack trace that points to the sketch\n and removes other parts of the stack trace.\n\n @private\n @class customError\n @constructor\n @param {String} name custom error name\n @param {String} errorTrace custom error trace\n @param {String} failedPath path to the file that failed to load\n @property {String} name custom error name\n @property {String} message custom error message\n @property {String} stack trace the error back to a line in the user's sketch.\n Note: this edits out stack trace within p5.js and p5.sound.\n @property {String} originalStack unedited, original stack trace\n @property {String} failedPath path to the file that failed to load\n @return {Error} returns a custom Error object\n */\n var CustomError = function(name, errorTrace, failedPath) {\n var err = new Error();\n var tempStack, splitStack;\n\n err.name = name;\n err.originalStack = err.stack + errorTrace;\n tempStack = err.stack + errorTrace;\n err.failedPath = failedPath;\n\n // only print the part of the stack trace that refers to the user code:\n var splitStack = tempStack.split('\\n');\n splitStack = splitStack.filter(function(ln) {\n return !ln.match(/(p5.|native code|globalInit)/g);\n });\n err.stack = splitStack.join('\\n');\n\n return err; // TODO: is this really a constructor?\n };\n\n return CustomError;\n});\n","define([\"Tone/core/Tone\", \"Tone/core/Emitter\"], function (Tone) {\n\n\t/**\n\t * shim\n\t * @private\n\t */\n\tif (!window.hasOwnProperty(\"AudioContext\") && window.hasOwnProperty(\"webkitAudioContext\")){\n\t\twindow.AudioContext = window.webkitAudioContext;\n\t}\n\n\t/**\n\t * @class Wrapper around the native AudioContext.\n\t * @extends {Tone.Emitter}\n\t * @param {AudioContext=} context optionally pass in a context\n\t */\n\tTone.Context = function(context){\n\n\t\tTone.Emitter.call(this);\n\n\t\tif (!context){\n\t\t\tcontext = new window.AudioContext();\n\t\t}\n\t\tthis._context = context;\n\t\t// extend all of the methods\n\t\tfor (var prop in this._context){\n\t\t\tthis._defineProperty(this._context, prop);\n\t\t}\n\n\t\t///////////////////////////////////////////////////////////////////////\n\t\t// WORKER\n\t\t///////////////////////////////////////////////////////////////////////\n\n\t\t/**\n\t\t * The default latency hint\n\t\t * @type {String}\n\t\t * @private\n\t\t */\n\t\tthis._latencyHint = \"interactive\";\n\n\t\t/**\n\t\t * The amount of time events are scheduled\n\t\t * into the future\n\t\t * @type {Number}\n\t\t * @private\n\t\t */\n\t\tthis._lookAhead = 0.1;\n\n\t\t/**\n\t\t * How often the update look runs\n\t\t * @type {Number}\n\t\t * @private\n\t\t */\n\t\tthis._updateInterval = this._lookAhead/3;\n\n\t\t/**\n\t\t * A reference to the actual computed update interval\n\t\t * @type {Number}\n\t\t * @private\n\t\t */\n\t\tthis._computedUpdateInterval = 0;\n\n\t\t/**\n\t\t * The web worker which is used to update Tone.Clock\n\t\t * @private\n\t\t * @type {WebWorker}\n\t\t */\n\t\tthis._worker = this._createWorker();\n\n\t\t/**\n\t\t * An object containing all of the constants AudioBufferSourceNodes\n\t\t * @type {Object}\n\t\t * @private\n\t\t */\n\t\tthis._constants = {};\n\n\t};\n\n\tTone.extend(Tone.Context, Tone.Emitter);\n\tTone.Emitter.mixin(Tone.Context);\n\n\t/**\n\t * Define a property on this Tone.Context. \n\t * This is used to extend the native AudioContext\n\t * @param {AudioContext} context\n\t * @param {String} prop \n\t * @private\n\t */\n\tTone.Context.prototype._defineProperty = function(context, prop){\n\t\tif (this.isUndef(this[prop])){\n\t\t\tObject.defineProperty(this, prop, {\n\t\t\t\tget : function(){\n\t\t\t\t\tif (typeof context[prop] === \"function\"){\n\t\t\t\t\t\treturn context[prop].bind(context);\n\t\t\t\t\t} else {\n\t\t\t\t\t\treturn context[prop];\n\t\t\t\t\t}\n\t\t\t\t},\n\t\t\t\tset : function(val){\n\t\t\t\t\tcontext[prop] = val;\n\t\t\t\t}\n\t\t\t});\n\t\t}\n\t};\n\n\t/**\n\t * The current audio context time\n\t * @return {Number}\n\t */\n\tTone.Context.prototype.now = function(){\n\t\treturn this._context.currentTime;\n\t};\n\n\t/**\n\t * Generate a web worker\n\t * @return {WebWorker}\n\t * @private\n\t */\n\tTone.Context.prototype._createWorker = function(){\n\t\t\n\t\t//URL Shim\n\t\twindow.URL = window.URL || window.webkitURL;\n\n\t\tvar blob = new Blob([\n\t\t\t//the initial timeout time\n\t\t\t\"var timeoutTime = \"+(this._updateInterval * 1000).toFixed(1)+\";\" +\n\t\t\t//onmessage callback\n\t\t\t\"self.onmessage = function(msg){\" +\n\t\t\t\"\ttimeoutTime = parseInt(msg.data);\" + \n\t\t\t\"};\" + \n\t\t\t//the tick function which posts a message\n\t\t\t//and schedules a new tick\n\t\t\t\"function tick(){\" +\n\t\t\t\"\tsetTimeout(tick, timeoutTime);\" +\n\t\t\t\"\tself.postMessage('tick');\" +\n\t\t\t\"}\" +\n\t\t\t//call tick initially\n\t\t\t\"tick();\"\n\t\t]);\n\t\tvar blobUrl = URL.createObjectURL(blob);\n\t\tvar worker = new Worker(blobUrl);\n\n\t\tworker.addEventListener(\"message\", function(){\n\t\t\t// tick the clock\n\t\t\tthis.emit(\"tick\");\n\t\t}.bind(this));\n\n\t\t//lag compensation\n\t\tworker.addEventListener(\"message\", function(){\n\t\t\tvar now = this.now();\n\t\t\tif (this.isNumber(this._lastUpdate)){\n\t\t\t\tvar diff = now - this._lastUpdate;\n\t\t\t\tthis._computedUpdateInterval = Math.max(diff, this._computedUpdateInterval * 0.97);\n\t\t\t}\n\t\t\tthis._lastUpdate = now;\n\t\t}.bind(this));\n\n\t\treturn worker;\n\t};\n\n\t/**\n\t * Generate a looped buffer at some constant value.\n\t * @param {Number} val\n\t * @return {BufferSourceNode}\n\t */\n\tTone.Context.prototype.getConstant = function(val){\n\t\tif (this._constants[val]){\n\t\t\treturn this._constants[val];\n\t\t} else {\n\t\t\tvar buffer = this._context.createBuffer(1, 128, this._context.sampleRate);\n\t\t\tvar arr = buffer.getChannelData(0);\n\t\t\tfor (var i = 0; i < arr.length; i++){\n\t\t\t\tarr[i] = val;\n\t\t\t}\n\t\t\tvar constant = this._context.createBufferSource();\n\t\t\tconstant.channelCount = 1;\n\t\t\tconstant.channelCountMode = \"explicit\";\n\t\t\tconstant.buffer = buffer;\n\t\t\tconstant.loop = true;\n\t\t\tconstant.start(0);\n\t\t\tthis._constants[val] = constant;\n\t\t\treturn constant;\n\t\t}\n\t};\n\n\t/**\n\t * This is the time that the clock is falling behind\n\t * the scheduled update interval. The Context automatically\n\t * adjusts for the lag and schedules further in advance.\n\t * @type {Number}\n\t * @memberOf Tone.Context\n\t * @name lag\n\t * @static\n\t * @readOnly\n\t */\n\tObject.defineProperty(Tone.Context.prototype, \"lag\", {\n\t\tget : function(){\n\t\t\tvar diff = this._computedUpdateInterval - this._updateInterval;\n\t\t\tdiff = Math.max(diff, 0);\n\t\t\treturn diff;\n\t\t}\n\t});\n\n\t/**\n\t * The amount of time in advance that events are scheduled.\n\t * The lookAhead will adjust slightly in response to the \n\t * measured update time to try to avoid clicks.\n\t * @type {Number}\n\t * @memberOf Tone.Context\n\t * @name lookAhead\n\t * @static\n\t */\n\tObject.defineProperty(Tone.Context.prototype, \"lookAhead\", {\n\t\tget : function(){\n\t\t\treturn this._lookAhead;\n\t\t},\n\t\tset : function(lA){\n\t\t\tthis._lookAhead = lA;\n\t\t}\n\t});\n\n\t/**\n\t * How often the Web Worker callback is invoked.\n\t * This number corresponds to how responsive the scheduling\n\t * can be. Context.updateInterval + Context.lookAhead gives you the\n\t * total latency between scheduling an event and hearing it.\n\t * @type {Number}\n\t * @memberOf Tone.Context\n\t * @name updateInterval\n\t * @static\n\t */\n\tObject.defineProperty(Tone.Context.prototype, \"updateInterval\", {\n\t\tget : function(){\n\t\t\treturn this._updateInterval;\n\t\t},\n\t\tset : function(interval){\n\t\t\tthis._updateInterval = Math.max(interval, Tone.prototype.blockTime);\n\t\t\tthis._worker.postMessage(Math.max(interval * 1000, 1));\n\t\t}\n\t});\n\n\t/**\n\t * The type of playback, which affects tradeoffs between audio \n\t * output latency and responsiveness. \n\t * \n\t * In addition to setting the value in seconds, the latencyHint also\n\t * accepts the strings \"interactive\" (prioritizes low latency), \n\t * \"playback\" (prioritizes sustained playback), \"balanced\" (balances\n\t * latency and performance), and \"fastest\" (lowest latency, might glitch more often). \n\t * @type {String|Seconds}\n\t * @memberOf Tone.Context#\n\t * @name latencyHint\n\t * @static\n\t * @example\n\t * //set the lookAhead to 0.3 seconds\n\t * Tone.context.latencyHint = 0.3;\n\t */\n\tObject.defineProperty(Tone.Context.prototype, \"latencyHint\", {\n\t\tget : function(){\n\t\t\treturn this._latencyHint;\n\t\t},\n\t\tset : function(hint){\n\t\t\tvar lookAhead = hint;\n\t\t\tthis._latencyHint = hint;\n\t\t\tif (this.isString(hint)){\n\t\t\t\tswitch(hint){\n\t\t\t\t\tcase \"interactive\" :\n\t\t\t\t\t\tlookAhead = 0.1;\n\t\t\t\t\t\tthis._context.latencyHint = hint;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase \"playback\" :\n\t\t\t\t\t\tlookAhead = 0.8;\n\t\t\t\t\t\tthis._context.latencyHint = hint;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase \"balanced\" :\n\t\t\t\t\t\tlookAhead = 0.25;\n\t\t\t\t\t\tthis._context.latencyHint = hint;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase \"fastest\" :\n\t\t\t\t\t\tlookAhead = 0.01;\n\t\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t\tthis.lookAhead = lookAhead;\n\t\t\tthis.updateInterval = lookAhead/3;\n\t\t}\n\t});\n\n\t/**\n\t * Shim all connect/disconnect and some deprecated methods which are still in\n\t * some older implementations.\n\t * @private\n\t */\n\tfunction shimConnect(){\n\n\t\tvar nativeConnect = AudioNode.prototype.connect;\n\t\tvar nativeDisconnect = AudioNode.prototype.disconnect;\n\n\t\t//replace the old connect method\n\t\tfunction toneConnect(B, outNum, inNum){\n\t\t\tif (B.input){\n\t\t\t\tif (Array.isArray(B.input)){\n\t\t\t\t\tif (Tone.prototype.isUndef(inNum)){\n\t\t\t\t\t\tinNum = 0;\n\t\t\t\t\t}\n\t\t\t\t\tthis.connect(B.input[inNum]);\n\t\t\t\t} else {\n\t\t\t\t\tthis.connect(B.input, outNum, inNum);\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\ttry {\n\t\t\t\t\tif (B instanceof AudioNode){\n\t\t\t\t\t\tnativeConnect.call(this, B, outNum, inNum);\n\t\t\t\t\t} else {\n\t\t\t\t\t\tnativeConnect.call(this, B, outNum);\n\t\t\t\t\t}\n\t\t\t\t} catch (e) {\n\t\t\t\t\tthrow new Error(\"error connecting to node: \"+B+\"\\n\"+e);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t//replace the old disconnect method\n\t\tfunction toneDisconnect(B, outNum, inNum){\n\t\t\tif (B && B.input && Array.isArray(B.input)){\n\t\t\t\tif (Tone.prototype.isUndef(inNum)){\n\t\t\t\t\tinNum = 0;\n\t\t\t\t}\n\t\t\t\tthis.disconnect(B.input[inNum], outNum, inNum);\n\t\t\t} else if (B && B.input){\n\t\t\t\tthis.disconnect(B.input, outNum, inNum);\n\t\t\t} else {\n\t\t\t\ttry {\n\t\t\t\t\tnativeDisconnect.apply(this, arguments);\n\t\t\t\t} catch (e) {\n\t\t\t\t\tthrow new Error(\"error disconnecting node: \"+B+\"\\n\"+e);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tif (AudioNode.prototype.connect !== toneConnect){\n\t\t\tAudioNode.prototype.connect = toneConnect;\n\t\t\tAudioNode.prototype.disconnect = toneDisconnect;\n\t\t}\n\t}\n\n\t// set the audio context initially\n\tif (Tone.supported){\n\t\tshimConnect();\n\t\tTone.context = new Tone.Context();\n\t} else {\n\t\tconsole.warn(\"This browser does not support Tone.js\");\n\t}\n\n\treturn Tone.Context;\n});","module.exports = {\n recorderProcessor: 'recorder-processor',\n soundFileProcessor: 'sound-file-processor',\n amplitudeProcessor: 'amplitude-processor'\n};\n","define([\"Tone/core/Tone\", \"Tone/signal/Add\", \"Tone/signal/Multiply\", \"Tone/signal/Signal\"], function(Tone){\n\n\t\"use strict\";\n\t\n\t/**\n\t * @class Performs a linear scaling on an input signal.\n\t * Scales a NormalRange input to between\n\t * outputMin and outputMax.\n\t *\n\t * @constructor\n\t * @extends {Tone.SignalBase}\n\t * @param {number} [outputMin=0] The output value when the input is 0. \n\t * @param {number} [outputMax=1]\tThe output value when the input is 1. \n\t * @example\n\t * var scale = new Tone.Scale(50, 100);\n\t * var signal = new Tone.Signal(0.5).connect(scale);\n\t * //the output of scale equals 75\n\t */\n\tTone.Scale = function(outputMin, outputMax){\n\n\t\t/** \n\t\t * @private\n\t\t * @type {number}\n\t\t */\n\t\tthis._outputMin = this.defaultArg(outputMin, 0);\n\n\t\t/** \n\t\t * @private\n\t\t * @type {number}\n\t\t */\n\t\tthis._outputMax = this.defaultArg(outputMax, 1);\n\n\n\t\t/** \n\t\t * @private\n\t\t * @type {Tone.Multiply}\n\t\t * @private\n\t\t */\n\t\tthis._scale = this.input = new Tone.Multiply(1);\n\t\t\n\t\t/** \n\t\t * @private\n\t\t * @type {Tone.Add}\n\t\t * @private\n\t\t */\n\t\tthis._add = this.output = new Tone.Add(0);\n\n\t\tthis._scale.connect(this._add);\n\t\tthis._setRange();\n\t};\n\n\tTone.extend(Tone.Scale, Tone.SignalBase);\n\n\t/**\n\t * The minimum output value. This number is output when \n\t * the value input value is 0. \n\t * @memberOf Tone.Scale#\n\t * @type {number}\n\t * @name min\n\t */\n\tObject.defineProperty(Tone.Scale.prototype, \"min\", {\n\t\tget : function(){\n\t\t\treturn this._outputMin;\n\t\t},\n\t\tset : function(min){\n\t\t\tthis._outputMin = min;\n\t\t\tthis._setRange();\n\t\t}\n\t});\n\n\t/**\n\t * The maximum output value. This number is output when \n\t * the value input value is 1. \n\t * @memberOf Tone.Scale#\n\t * @type {number}\n\t * @name max\n\t */\n\tObject.defineProperty(Tone.Scale.prototype, \"max\", {\n\t\tget : function(){\n\t\t\treturn this._outputMax;\n\t\t},\n\t\tset : function(max){\n\t\t\tthis._outputMax = max;\n\t\t\tthis._setRange();\n\t\t}\n\t});\n\n\t/**\n\t * set the values\n\t * @private\n\t */\n\tTone.Scale.prototype._setRange = function() {\n\t\tthis._add.value = this._outputMin;\n\t\tthis._scale.value = this._outputMax - this._outputMin;\n\t};\n\n\t/**\n\t * Clean up.\n\t * @returns {Tone.Scale} this\n\t */\n\tTone.Scale.prototype.dispose = function(){\n\t\tTone.prototype.dispose.call(this);\n\t\tthis._add.dispose();\n\t\tthis._add = null;\n\t\tthis._scale.dispose();\n\t\tthis._scale = null;\n\t\treturn this;\n\t}; \n\n\treturn Tone.Scale;\n});\n","define([\"Tone/core/Tone\", \"Tone/signal/Signal\", \"Tone/core/Timeline\"], function (Tone) {\n\n\t\"use strict\";\n\n\t/**\n\t * @class A signal which adds the method getValueAtTime. \n\t * Code and inspiration from https://github.com/jsantell/web-audio-automation-timeline\n\t * @extends {Tone.Param}\n\t * @param {Number=} value The initial value of the signal\n\t * @param {String=} units The conversion units of the signal.\n\t */\n\tTone.TimelineSignal = function(){\n\n\t\tvar options = this.optionsObject(arguments, [\"value\", \"units\"], Tone.Signal.defaults);\n\t\t\n\t\t/**\n\t\t * The scheduled events\n\t\t * @type {Tone.Timeline}\n\t\t * @private\n\t\t */\n\t\tthis._events = new Tone.Timeline(10);\n\n\t\t//constructors\n\t\tTone.Signal.apply(this, options);\n\t\toptions.param = this._param;\n\t\tTone.Param.call(this, options);\n\n\t\t/**\n\t\t * The initial scheduled value\n\t\t * @type {Number}\n\t\t * @private\n\t\t */\n\t\tthis._initial = this._fromUnits(this._param.value);\n\t};\n\n\tTone.extend(Tone.TimelineSignal, Tone.Param);\n\n\t/**\n\t * The event types of a schedulable signal.\n\t * @enum {String}\n\t * @private\n\t */\n\tTone.TimelineSignal.Type = {\n\t\tLinear : \"linear\",\n\t\tExponential : \"exponential\",\n\t\tTarget : \"target\",\n\t\tCurve : \"curve\",\n\t\tSet : \"set\"\n\t};\n\n\t/**\n\t * The current value of the signal. \n\t * @memberOf Tone.TimelineSignal#\n\t * @type {Number}\n\t * @name value\n\t */\n\tObject.defineProperty(Tone.TimelineSignal.prototype, \"value\", {\n\t\tget : function(){\n\t\t\tvar now = this.now();\n\t\t\tvar val = this.getValueAtTime(now);\n\t\t\treturn this._toUnits(val);\n\t\t},\n\t\tset : function(value){\n\t\t\tvar convertedVal = this._fromUnits(value);\n\t\t\tthis._initial = convertedVal;\n\t\t\tthis.cancelScheduledValues();\n\t\t\tthis._param.value = convertedVal;\n\t\t}\n\t});\n\n\t///////////////////////////////////////////////////////////////////////////\n\t//\tSCHEDULING\n\t///////////////////////////////////////////////////////////////////////////\n\n\t/**\n\t * Schedules a parameter value change at the given time.\n\t * @param {*}\tvalue The value to set the signal.\n\t * @param {Time} time The time when the change should occur.\n\t * @returns {Tone.TimelineSignal} this\n\t * @example\n\t * //set the frequency to \"G4\" in exactly 1 second from now. \n\t * freq.setValueAtTime(\"G4\", \"+1\");\n\t */\n\tTone.TimelineSignal.prototype.setValueAtTime = function (value, startTime) {\n\t\tvalue = this._fromUnits(value);\n\t\tstartTime = this.toSeconds(startTime);\n\t\tthis._events.add({\n\t\t\t\"type\" : Tone.TimelineSignal.Type.Set,\n\t\t\t\"value\" : value,\n\t\t\t\"time\" : startTime\n\t\t});\n\t\t//invoke the original event\n\t\tthis._param.setValueAtTime(value, startTime);\n\t\treturn this;\n\t};\n\n\t/**\n\t * Schedules a linear continuous change in parameter value from the \n\t * previous scheduled parameter value to the given value.\n\t * \n\t * @param {number} value \n\t * @param {Time} endTime \n\t * @returns {Tone.TimelineSignal} this\n\t */\n\tTone.TimelineSignal.prototype.linearRampToValueAtTime = function (value, endTime) {\n\t\tvalue = this._fromUnits(value);\n\t\tendTime = this.toSeconds(endTime);\n\t\tthis._events.add({\n\t\t\t\"type\" : Tone.TimelineSignal.Type.Linear,\n\t\t\t\"value\" : value,\n\t\t\t\"time\" : endTime\n\t\t});\n\t\tthis._param.linearRampToValueAtTime(value, endTime);\n\t\treturn this;\n\t};\n\n\t/**\n\t * Schedules an exponential continuous change in parameter value from \n\t * the previous scheduled parameter value to the given value.\n\t * \n\t * @param {number} value \n\t * @param {Time} endTime \n\t * @returns {Tone.TimelineSignal} this\n\t */\n\tTone.TimelineSignal.prototype.exponentialRampToValueAtTime = function (value, endTime) {\n\t\t//get the previous event and make sure it's not starting from 0\n\t\tendTime = this.toSeconds(endTime);\n\t\tvar beforeEvent = this._searchBefore(endTime);\n\t\tif (beforeEvent && beforeEvent.value === 0){\n\t\t\t//reschedule that event\n\t\t\tthis.setValueAtTime(this._minOutput, beforeEvent.time);\n\t\t}\n\t\tvalue = this._fromUnits(value);\n\t\tvar setValue = Math.max(value, this._minOutput);\n\t\tthis._events.add({\n\t\t\t\"type\" : Tone.TimelineSignal.Type.Exponential,\n\t\t\t\"value\" : setValue,\n\t\t\t\"time\" : endTime\n\t\t});\n\t\t//if the ramped to value is 0, make it go to the min output, and then set to 0.\n\t\tif (value < this._minOutput){\n\t\t\tthis._param.exponentialRampToValueAtTime(this._minOutput, endTime - this.sampleTime);\n\t\t\tthis.setValueAtTime(0, endTime);\n\t\t} else {\n\t\t\tthis._param.exponentialRampToValueAtTime(value, endTime);\n\t\t}\n\t\treturn this;\n\t};\n\n\t/**\n\t * Start exponentially approaching the target value at the given time with\n\t * a rate having the given time constant.\n\t * @param {number} value \n\t * @param {Time} startTime \n\t * @param {number} timeConstant \n\t * @returns {Tone.TimelineSignal} this \n\t */\n\tTone.TimelineSignal.prototype.setTargetAtTime = function (value, startTime, timeConstant) {\n\t\tvalue = this._fromUnits(value);\n\t\tvalue = Math.max(this._minOutput, value);\n\t\ttimeConstant = Math.max(this._minOutput, timeConstant);\n\t\tstartTime = this.toSeconds(startTime);\n\t\tthis._events.add({\n\t\t\t\"type\" : Tone.TimelineSignal.Type.Target,\n\t\t\t\"value\" : value,\n\t\t\t\"time\" : startTime,\n\t\t\t\"constant\" : timeConstant\n\t\t});\n\t\tthis._param.setTargetAtTime(value, startTime, timeConstant);\n\t\treturn this;\n\t};\n\n\t/**\n\t * Set an array of arbitrary values starting at the given time for the given duration.\n\t * @param {Float32Array} values \n\t * @param {Time} startTime \n\t * @param {Time} duration\n\t * @param {NormalRange} [scaling=1] If the values in the curve should be scaled by some value\n\t * @returns {Tone.TimelineSignal} this \n\t */\n\tTone.TimelineSignal.prototype.setValueCurveAtTime = function (values, startTime, duration, scaling) {\n\t\tscaling = this.defaultArg(scaling, 1);\n\t\t//copy the array\n\t\tvar floats = new Array(values.length);\n\t\tfor (var i = 0; i < floats.length; i++){\n\t\t\tfloats[i] = this._fromUnits(values[i]) * scaling;\n\t\t}\n\t\tstartTime = this.toSeconds(startTime);\n\t\tduration = this.toSeconds(duration);\n\t\tthis._events.add({\n\t\t\t\"type\" : Tone.TimelineSignal.Type.Curve,\n\t\t\t\"value\" : floats,\n\t\t\t\"time\" : startTime,\n\t\t\t\"duration\" : duration\n\t\t});\n\t\t//set the first value\n\t\tthis._param.setValueAtTime(floats[0], startTime);\n\t\t//schedule a lienar ramp for each of the segments\n\t\tfor (var j = 1; j < floats.length; j++){\n\t\t\tvar segmentTime = startTime + (j / (floats.length - 1) * duration);\n\t\t\tthis._param.linearRampToValueAtTime(floats[j], segmentTime);\n\t\t}\n\t\treturn this;\n\t};\n\n\t/**\n\t * Cancels all scheduled parameter changes with times greater than or \n\t * equal to startTime.\n\t * \n\t * @param {Time} startTime\n\t * @returns {Tone.TimelineSignal} this\n\t */\n\tTone.TimelineSignal.prototype.cancelScheduledValues = function (after) {\n\t\tafter = this.toSeconds(after);\n\t\tthis._events.cancel(after);\n\t\tthis._param.cancelScheduledValues(after);\n\t\treturn this;\n\t};\n\n\t/**\n\t * Sets the computed value at the given time. This provides\n\t * a point from which a linear or exponential curve\n\t * can be scheduled after. Will cancel events after \n\t * the given time and shorten the currently scheduled\n\t * linear or exponential ramp so that it ends at `time` .\n\t * This is to avoid discontinuities and clicks in envelopes. \n\t * @param {Time} time When to set the ramp point\n\t * @returns {Tone.TimelineSignal} this\n\t */\n\tTone.TimelineSignal.prototype.setRampPoint = function (time) {\n\t\ttime = this.toSeconds(time);\n\t\t//get the value at the given time\n\t\tvar val = this._toUnits(this.getValueAtTime(time));\n\t\t//if there is an event at the given time\n\t\t//and that even is not a \"set\"\n\t\tvar before = this._searchBefore(time);\n\t\tif (before && before.time === time){\n\t\t\t//remove everything after\n\t\t\tthis.cancelScheduledValues(time + this.sampleTime);\n\t\t} else if (before && \n\t\t\t\t before.type === Tone.TimelineSignal.Type.Curve &&\n\t\t\t\t before.time + before.duration > time){\n\t\t\t//if the curve is still playing\n\t\t\t//cancel the curve\n\t\t\tthis.cancelScheduledValues(time);\n\t\t\tthis.linearRampToValueAtTime(val, time);\n\t\t} else {\n\t\t\t//reschedule the next event to end at the given time\n\t\t\tvar after = this._searchAfter(time);\n\t\t\tif (after){\n\t\t\t\t//cancel the next event(s)\n\t\t\t\tthis.cancelScheduledValues(time);\n\t\t\t\tif (after.type === Tone.TimelineSignal.Type.Linear){\n\t\t\t\t\tthis.linearRampToValueAtTime(val, time);\n\t\t\t\t} else if (after.type === Tone.TimelineSignal.Type.Exponential){\n\t\t\t\t\tthis.exponentialRampToValueAtTime(val, time);\n\t\t\t\t}\n\t\t\t}\n\t\t\tthis.setValueAtTime(val, time);\n\t\t}\n\t\treturn this;\n\t};\n\n\t/**\n\t * Do a linear ramp to the given value between the start and finish times.\n\t * @param {Number} value The value to ramp to.\n\t * @param {Time} start The beginning anchor point to do the linear ramp\n\t * @param {Time} finish The ending anchor point by which the value of\n\t * the signal will equal the given value.\n\t * @returns {Tone.TimelineSignal} this\n\t */\n\tTone.TimelineSignal.prototype.linearRampToValueBetween = function (value, start, finish) {\n\t\tthis.setRampPoint(start);\n\t\tthis.linearRampToValueAtTime(value, finish);\n\t\treturn this;\n\t};\n\n\t/**\n\t * Do a exponential ramp to the given value between the start and finish times.\n\t * @param {Number} value The value to ramp to.\n\t * @param {Time} start The beginning anchor point to do the exponential ramp\n\t * @param {Time} finish The ending anchor point by which the value of\n\t * the signal will equal the given value.\n\t * @returns {Tone.TimelineSignal} this\n\t */\n\tTone.TimelineSignal.prototype.exponentialRampToValueBetween = function (value, start, finish) {\n\t\tthis.setRampPoint(start);\n\t\tthis.exponentialRampToValueAtTime(value, finish);\n\t\treturn this;\n\t};\n\n\t///////////////////////////////////////////////////////////////////////////\n\t//\tGETTING SCHEDULED VALUES\n\t///////////////////////////////////////////////////////////////////////////\n\n\t/**\n\t * Returns the value before or equal to the given time\n\t * @param {Number} time The time to query\n\t * @return {Object} The event at or before the given time.\n\t * @private\n\t */\n\tTone.TimelineSignal.prototype._searchBefore = function(time){\n\t\treturn this._events.get(time);\n\t};\n\n\t/**\n\t * The event after the given time\n\t * @param {Number} time The time to query.\n\t * @return {Object} The next event after the given time\n\t * @private\n\t */\n\tTone.TimelineSignal.prototype._searchAfter = function(time){\n\t\treturn this._events.getAfter(time);\n\t};\n\n\t/**\n\t * Get the scheduled value at the given time. This will\n\t * return the unconverted (raw) value.\n\t * @param {Number} time The time in seconds.\n\t * @return {Number} The scheduled value at the given time.\n\t */\n\tTone.TimelineSignal.prototype.getValueAtTime = function(time){\n\t\ttime = this.toSeconds(time);\n\t\tvar after = this._searchAfter(time);\n\t\tvar before = this._searchBefore(time);\n\t\tvar value = this._initial;\n\t\t//if it was set by\n\t\tif (before === null){\n\t\t\tvalue = this._initial;\n\t\t} else if (before.type === Tone.TimelineSignal.Type.Target){\n\t\t\tvar previous = this._events.getBefore(before.time);\n\t\t\tvar previouVal;\n\t\t\tif (previous === null){\n\t\t\t\tpreviouVal = this._initial;\n\t\t\t} else {\n\t\t\t\tpreviouVal = previous.value;\n\t\t\t}\n\t\t\tvalue = this._exponentialApproach(before.time, previouVal, before.value, before.constant, time);\n\t\t} else if (before.type === Tone.TimelineSignal.Type.Curve){\n\t\t\tvalue = this._curveInterpolate(before.time, before.value, before.duration, time);\n\t\t} else if (after === null){\n\t\t\tvalue = before.value;\n\t\t} else if (after.type === Tone.TimelineSignal.Type.Linear){\n\t\t\tvalue = this._linearInterpolate(before.time, before.value, after.time, after.value, time);\n\t\t} else if (after.type === Tone.TimelineSignal.Type.Exponential){\n\t\t\tvalue = this._exponentialInterpolate(before.time, before.value, after.time, after.value, time);\n\t\t} else {\n\t\t\tvalue = before.value;\n\t\t}\n\t\treturn value;\n\t};\n\n\t/**\n\t * When signals connect to other signals or AudioParams, \n\t * they take over the output value of that signal or AudioParam. \n\t * For all other nodes, the behavior is the same as a default connect. \n\t *\n\t * @override\n\t * @param {AudioParam|AudioNode|Tone.Signal|Tone} node \n\t * @param {number} [outputNumber=0] The output number to connect from.\n\t * @param {number} [inputNumber=0] The input number to connect to.\n\t * @returns {Tone.TimelineSignal} this\n\t * @method\n\t */\n\tTone.TimelineSignal.prototype.connect = Tone.SignalBase.prototype.connect;\n\n\n\t///////////////////////////////////////////////////////////////////////////\n\t//\tAUTOMATION CURVE CALCULATIONS\n\t//\tMIT License, copyright (c) 2014 Jordan Santell\n\t///////////////////////////////////////////////////////////////////////////\n\n\t/**\n\t * Calculates the the value along the curve produced by setTargetAtTime\n\t * @private\n\t */\n\tTone.TimelineSignal.prototype._exponentialApproach = function (t0, v0, v1, timeConstant, t) {\n\t\treturn v1 + (v0 - v1) * Math.exp(-(t - t0) / timeConstant);\n\t};\n\n\t/**\n\t * Calculates the the value along the curve produced by linearRampToValueAtTime\n\t * @private\n\t */\n\tTone.TimelineSignal.prototype._linearInterpolate = function (t0, v0, t1, v1, t) {\n\t\treturn v0 + (v1 - v0) * ((t - t0) / (t1 - t0));\n\t};\n\n\t/**\n\t * Calculates the the value along the curve produced by exponentialRampToValueAtTime\n\t * @private\n\t */\n\tTone.TimelineSignal.prototype._exponentialInterpolate = function (t0, v0, t1, v1, t) {\n\t\tv0 = Math.max(this._minOutput, v0);\n\t\treturn v0 * Math.pow(v1 / v0, (t - t0) / (t1 - t0));\n\t};\n\n\t/**\n\t * Calculates the the value along the curve produced by setValueCurveAtTime\n\t * @private\n\t */\n\tTone.TimelineSignal.prototype._curveInterpolate = function (start, curve, duration, time) {\n\t\tvar len = curve.length;\n\t\t// If time is after duration, return the last curve value\n\t\tif (time >= start + duration) {\n\t\t\treturn curve[len - 1];\n\t\t} else if (time <= start){\n\t\t\treturn curve[0];\n\t\t} else {\n\t\t\tvar progress = (time - start) / duration;\n\t\t\tvar lowerIndex = Math.floor((len - 1) * progress);\n\t\t\tvar upperIndex = Math.ceil((len - 1) * progress);\n\t\t\tvar lowerVal = curve[lowerIndex];\n\t\t\tvar upperVal = curve[upperIndex];\n\t\t\tif (upperIndex === lowerIndex){\n\t\t\t\treturn lowerVal;\n\t\t\t} else {\n\t\t\t\treturn this._linearInterpolate(lowerIndex, lowerVal, upperIndex, upperVal, progress * (len - 1));\n\t\t\t}\n\t\t}\n\t};\n\n\t/**\n\t * Clean up.\n\t * @return {Tone.TimelineSignal} this\n\t */\n\tTone.TimelineSignal.prototype.dispose = function(){\n\t\tTone.Signal.prototype.dispose.call(this);\n\t\tTone.Param.prototype.dispose.call(this);\n\t\tthis._events.dispose();\n\t\tthis._events = null;\n\t};\n\n\treturn Tone.TimelineSignal;\n});","'use strict';\n\ndefine(function (require) {\n var Effect = require('effect');\n\n /**\n *
A p5.Filter uses a Web Audio Biquad Filter to filter\n * the frequency response of an input source. Subclasses\n * include:
\n * p5.LowPass:\n * Allows frequencies below the cutoff frequency to pass through,\n * and attenuates frequencies above the cutoff. \n * p5.HighPass:\n * The opposite of a lowpass filter. \n * p5.BandPass:\n * Allows a range of frequencies to pass through and attenuates\n * the frequencies below and above this frequency range. \n *\n * The .res() method controls either width of the\n * bandpass, or resonance of the low/highpass cutoff frequency.\n *\n * This class extends p5.Effect.\n * Methods amp(), chain(),\n * drywet(), connect(), and\n * disconnect() are available.\n *\n * @class p5.Filter\n * @extends p5.Effect\n * @constructor\n * @param {String} [type] 'lowpass' (default), 'highpass', 'bandpass'\n * @example\n *
\n * var fft, noise, filter;\n *\n * function setup() {\n * fill(255, 40, 255);\n *\n * filter = new p5.BandPass();\n *\n * noise = new p5.Noise();\n * // disconnect unfiltered noise,\n * // and connect to filter\n * noise.disconnect();\n * noise.connect(filter);\n * noise.start();\n *\n * fft = new p5.FFT();\n * }\n *\n * function draw() {\n * background(30);\n *\n * // set the BandPass frequency based on mouseX\n * var freq = map(mouseX, 0, width, 20, 10000);\n * filter.freq(freq);\n * // give the filter a narrow band (lower res = wider bandpass)\n * filter.res(50);\n *\n * // draw filtered spectrum\n * var spectrum = fft.analyze();\n * noStroke();\n * for (var i = 0; i < spectrum.length; i++) {\n * var x = map(i, 0, spectrum.length, 0, width);\n * var h = -height + map(spectrum[i], 0, 255, height, 0);\n * rect(x, height, width/spectrum.length, h);\n * }\n *\n * isMouseOverCanvas();\n * }\n *\n * function isMouseOverCanvas() {\n * var mX = mouseX, mY = mouseY;\n * if (mX > 0 && mX < width && mY < height && mY > 0) {\n * noise.amp(0.5, 0.2);\n * } else {\n * noise.amp(0, 0.2);\n * }\n * }\n *
\n */\n p5.Filter = function (type) {\n\n Effect.call(this);\n //add extend Effect by adding a Biquad Filter\n\n /**\n * The p5.Filter is built with a\n * \n * Web Audio BiquadFilter Node.\n *\n * @property {DelayNode} biquadFilter\n\t */\n\n this.biquad = this.ac.createBiquadFilter();\n\n this.input.connect(this.biquad);\n\n this.biquad.connect(this.wet);\n\n if (type) {\n this.setType(type);\n }\n\n //Properties useful for the toggle method.\n this._on = true;\n this._untoggledType = this.biquad.type;\n };\n p5.Filter.prototype = Object.create(Effect.prototype);\n\n\n /**\n * Filter an audio signal according to a set\n * of filter parameters.\n *\n * @method process\n * @param {Object} Signal An object that outputs audio\n * @param {Number} [freq] Frequency in Hz, from 10 to 22050\n * @param {Number} [res] Resonance/Width of the filter frequency\n * from 0.001 to 1000\n */\n p5.Filter.prototype.process = function(src, freq, res, time) {\n src.connect(this.input);\n this.set(freq, res, time);\n };\n\n\n /**\n * Set the frequency and the resonance of the filter.\n *\n * @method set\n * @param {Number} [freq] Frequency in Hz, from 10 to 22050\n * @param {Number} [res] Resonance (Q) from 0.001 to 1000\n * @param {Number} [timeFromNow] schedule this event to happen\n * seconds from now\n */\n p5.Filter.prototype.set = function(freq, res, time) {\n if (freq) {\n this.freq(freq, time);\n }\n if (res) {\n this.res(res, time);\n }\n };\n\n /**\n * Set the filter frequency, in Hz, from 10 to 22050 (the range of\n * human hearing, although in reality most people hear in a narrower\n * range).\n *\n * @method freq\n * @param {Number} freq Filter Frequency\n * @param {Number} [timeFromNow] schedule this event to happen\n * seconds from now\n * @return {Number} value Returns the current frequency value\n */\n p5.Filter.prototype.freq = function(freq, time) {\n var t = time || 0;\n if (freq <= 0) {\n freq = 1;\n }\n if (typeof freq === 'number') {\n this.biquad.frequency.cancelScheduledValues(this.ac.currentTime + 0.01 + t);\n this.biquad.frequency.exponentialRampToValueAtTime(freq, this.ac.currentTime + 0.02 + t);\n } else if (freq) {\n freq.connect(this.biquad.frequency);\n }\n return this.biquad.frequency.value;\n };\n\n /**\n * Controls either width of a bandpass frequency,\n * or the resonance of a low/highpass cutoff frequency.\n *\n * @method res\n * @param {Number} res Resonance/Width of filter freq\n * from 0.001 to 1000\n * @param {Number} [timeFromNow] schedule this event to happen\n * seconds from now\n * @return {Number} value Returns the current res value\n */\n p5.Filter.prototype.res = function(res, time) {\n var t = time || 0;\n if (typeof res === 'number') {\n this.biquad.Q.value = res;\n this.biquad.Q.cancelScheduledValues(this.ac.currentTime + 0.01 + t);\n this.biquad.Q.linearRampToValueAtTime(res, this.ac.currentTime + 0.02 + t);\n } else if (res) {\n res.connect(this.biquad.Q);\n }\n return this.biquad.Q.value;\n };\n\n /**\n * Controls the gain attribute of a Biquad Filter.\n * This is distinctly different from .amp() which is inherited from p5.Effect\n * .amp() controls the volume via the output gain node\n * p5.Filter.gain() controls the gain parameter of a Biquad Filter node.\n *\n * @method gain\n * @param {Number} gain\n * @return {Number} Returns the current or updated gain value\n */\n p5.Filter.prototype.gain = function(gain, time) {\n var t = time || 0;\n if (typeof gain === 'number') {\n this.biquad.gain.value = gain;\n this.biquad.gain.cancelScheduledValues(this.ac.currentTime + 0.01 + t);\n this.biquad.gain.linearRampToValueAtTime(gain, this.ac.currentTime + 0.02 + t);\n } else if (gain) {\n gain.connect(this.biquad.gain);\n }\n return this.biquad.gain.value;\n };\n\n\n /**\n * Toggle function. Switches between the specified type and allpass\n *\n * @method toggle\n * @return {boolean} [Toggle value]\n */\n p5.Filter.prototype.toggle = function() {\n this._on = !this._on;\n\n if (this._on === true) {\n this.biquad.type = this._untoggledType;\n } else if (this._on === false) {\n this.biquad.type = 'allpass';\n }\n\n return this._on;\n };\n\n /**\n * Set the type of a p5.Filter. Possible types include:\n * \"lowpass\" (default), \"highpass\", \"bandpass\",\n * \"lowshelf\", \"highshelf\", \"peaking\", \"notch\",\n * \"allpass\".\n *\n * @method setType\n * @param {String} t\n */\n p5.Filter.prototype.setType = function(t) {\n this.biquad.type = t;\n this._untoggledType = this.biquad.type;\n };\n\n p5.Filter.prototype.dispose = function() {\n // remove reference from soundArray\n Effect.prototype.dispose.apply(this);\n if (this.biquad) {\n this.biquad.disconnect();\n delete this.biquad;\n }\n };\n\n /**\n * Constructor: new p5.LowPass() Filter.\n * This is the same as creating a p5.Filter and then calling\n * its method setType('lowpass').\n * See p5.Filter for methods.\n *\n * @class p5.LowPass\n * @constructor\n * @extends p5.Filter\n */\n p5.LowPass = function() {\n p5.Filter.call(this, 'lowpass');\n };\n p5.LowPass.prototype = Object.create(p5.Filter.prototype);\n\n /**\n * Constructor: new p5.HighPass() Filter.\n * This is the same as creating a p5.Filter and then calling\n * its method setType('highpass').\n * See p5.Filter for methods.\n *\n * @class p5.HighPass\n * @constructor\n * @extends p5.Filter\n */\n p5.HighPass = function() {\n p5.Filter.call(this, 'highpass');\n };\n p5.HighPass.prototype = Object.create(p5.Filter.prototype);\n\n /**\n * Constructor: new p5.BandPass() Filter.\n * This is the same as creating a p5.Filter and then calling\n * its method setType('bandpass').\n * See p5.Filter for methods.\n *\n * @class p5.BandPass\n * @constructor\n * @extends p5.Filter\n */\n p5.BandPass = function() {\n p5.Filter.call(this, 'bandpass');\n };\n p5.BandPass.prototype = Object.create(p5.Filter.prototype);\n\n return p5.Filter;\n});\n","define([\"Tone/core/Tone\", \"Tone/signal/Add\", \"Tone/signal/Negate\", \"Tone/signal/Signal\", \"Tone/core/Gain\"], function(Tone){\n\n\t\"use strict\";\n\n\t/**\n\t * @class Subtract the signal connected to input[1] from the signal connected \n\t * to input[0]. If an argument is provided in the constructor, the \n\t * signals .value will be subtracted from the incoming signal.\n\t *\n\t * @extends {Tone.Signal}\n\t * @constructor\n\t * @param {number=} value The value to subtract from the incoming signal. If the value\n\t * is omitted, it will subtract the second signal from the first.\n\t * @example\n\t * var sub = new Tone.Subtract(1);\n\t * var sig = new Tone.Signal(4).connect(sub);\n\t * //the output of sub is 3. \n\t * @example\n\t * var sub = new Tone.Subtract();\n\t * var sigA = new Tone.Signal(10);\n\t * var sigB = new Tone.Signal(2.5);\n\t * sigA.connect(sub, 0, 0);\n\t * sigB.connect(sub, 0, 1);\n\t * //output of sub is 7.5\n\t */\n\tTone.Subtract = function(value){\n\n\t\tthis.createInsOuts(2, 0);\n\n\t\t/**\n\t\t * the summing node\n\t\t * @type {GainNode}\n\t\t * @private\n\t\t */\n\t\tthis._sum = this.input[0] = this.output = new Tone.Gain();\n\n\t\t/**\n\t\t * negate the input of the second input before connecting it\n\t\t * to the summing node.\n\t\t * @type {Tone.Negate}\n\t\t * @private\n\t\t */\n\t\tthis._neg = new Tone.Negate();\n\n\t\t/**\n\t\t * the node where the value is set\n\t\t * @private\n\t\t * @type {Tone.Signal}\n\t\t */\n\t\tthis._param = this.input[1] = new Tone.Signal(value);\n\n\t\tthis._param.chain(this._neg, this._sum);\n\t};\n\n\tTone.extend(Tone.Subtract, Tone.Signal);\n\n\t/**\n\t * Clean up.\n\t * @returns {Tone.SignalBase} this\n\t */\n\tTone.Subtract.prototype.dispose = function(){\n\t\tTone.prototype.dispose.call(this);\n\t\tthis._neg.dispose();\n\t\tthis._neg = null;\n\t\tthis._sum.disconnect();\n\t\tthis._sum = null;\n\t\tthis._param.dispose();\n\t\tthis._param = null;\n\t\treturn this;\n\t};\n\n\treturn Tone.Subtract;\n});","'use strict';\n\nglobal.TONE_SILENCE_VERSION_LOGGING = true;\n\ndefine(['startaudiocontext', 'Tone/core/Context', 'Tone/core/Tone'], function (StartAudioContext, Context, Tone) {\n // Create the Audio Context\n const audiocontext = new window.AudioContext();\n\n // Tone and p5.sound share the same audio context\n Tone.context.dispose();\n Tone.setContext(audiocontext);\n\n /**\n *
Returns the Audio Context for this sketch. Useful for users\n * who would like to dig deeper into the Web Audio API\n * .
\n *\n *
Some browsers require users to startAudioContext\n * with a user gesture, such as touchStarted in the example below.
\n *\n * @method getAudioContext\n * @return {Object} AudioContext for this sketch\n * @example\n *
\n * function draw() {\n * background(255);\n * textAlign(CENTER);\n *\n * if (getAudioContext().state !== 'running') {\n * text('click to start audio', width/2, height/2);\n * } else {\n * text('audio is enabled', width/2, height/2);\n * }\n * }\n *\n * function touchStarted() {\n * if (getAudioContext().state !== 'running') {\n * getAudioContext().resume();\n * }\n * var synth = new p5.MonoSynth();\n * synth.play('A4', 0.5, 0, 0.2);\n * }\n *\n *
It is a good practice to give users control over starting audio playback.\n * This practice is enforced by Google Chrome's autoplay policy as of r70\n * (info), iOS Safari, and other browsers.\n *
\n *\n *
\n * userStartAudio() starts the Audio Context on a user gesture. It utilizes\n * the StartAudioContext library by\n * Yotam Mann (MIT Licence, 2016). Read more at https://github.com/tambien/StartAudioContext.\n *
\n *\n *
Starting the audio context on a user gesture can be as simple as userStartAudio().\n * Optional parameters let you decide on a specific element that will start the audio context,\n * and/or call a function once the audio context is started.
\n * @param {Element|Array} [element(s)] This argument can be an Element,\n * Selector String, NodeList, p5.Element,\n * jQuery Element, or an Array of any of those.\n * @param {Function} [callback] Callback to invoke when the AudioContext has started\n * @return {Promise} Returns a Promise which is resolved when\n * the AudioContext state is 'running'\n * @method userStartAudio\n * @for p5\n * @example\n *
\n * function setup() {\n * var myDiv = createDiv('click to start audio');\n * myDiv.position(0, 0);\n *\n * var mySynth = new p5.MonoSynth();\n *\n * // This won't play until the context has started\n * mySynth.play('A6');\n *\n * // Start the audio context on a click/touch event\n * userStartAudio().then(function() {\n * myDiv.remove();\n * });\n * }\n *
\n */\n p5.prototype.userStartAudio = function(elements, callback) {\n var elt = elements;\n if (elements instanceof p5.Element) {\n elt = elements.elt;\n } else if (elements instanceof Array && elements[0] instanceof p5.Element ) {\n elt = elements.map(function(e) { return e.elt});\n }\n return StartAudioContext(audiocontext, elt, callback);\n };\n\n return audiocontext;\n});\n","define([\"Tone/core/Tone\"], function (Tone) {\n\n\t\"use strict\";\n\n\t/**\n\t * @class Tone.Emitter gives classes which extend it\n\t * the ability to listen for and emit events. \n\t * Inspiration and reference from Jerome Etienne's [MicroEvent](https://github.com/jeromeetienne/microevent.js).\n\t * MIT (c) 2011 Jerome Etienne.\n\t * \n\t * @extends {Tone}\n\t */\n\tTone.Emitter = function(){\n\t\t/**\n\t\t * Contains all of the events.\n\t\t * @private\n\t\t * @type {Object}\n\t\t */\n\t\tthis._events = {};\n\t};\n\n\tTone.extend(Tone.Emitter);\n\n\t/**\n\t * Bind a callback to a specific event.\n\t * @param {String} event The name of the event to listen for.\n\t * @param {Function} callback The callback to invoke when the\n\t * event is emitted\n\t * @return {Tone.Emitter} this\n\t */\n\tTone.Emitter.prototype.on = function(event, callback){\n\t\t//split the event\n\t\tvar events = event.split(/\\W+/);\n\t\tfor (var i = 0; i < events.length; i++){\n\t\t\tvar eventName = events[i];\n\t\t\tif (!this._events.hasOwnProperty(eventName)){\n\t\t\t\tthis._events[eventName] = [];\n\t\t\t}\n\t\t\tthis._events[eventName].push(callback);\n\t\t}\n\t\treturn this;\n\t};\n\n\t/**\n\t * Remove the event listener.\n\t * @param {String} event The event to stop listening to.\n\t * @param {Function=} callback The callback which was bound to \n\t * the event with Tone.Emitter.on.\n\t * If no callback is given, all callbacks\n\t * events are removed.\n\t * @return {Tone.Emitter} this\n\t */\n\tTone.Emitter.prototype.off = function(event, callback){\n\t\tvar events = event.split(/\\W+/);\n\t\tfor (var ev = 0; ev < events.length; ev++){\n\t\t\tevent = events[ev];\n\t\t\tif (this._events.hasOwnProperty(event)){\n\t\t\t\tif (Tone.prototype.isUndef(callback)){\n\t\t\t\t\tthis._events[event] = [];\n\t\t\t\t} else {\n\t\t\t\t\tvar eventList = this._events[event];\n\t\t\t\t\tfor (var i = 0; i < eventList.length; i++){\n\t\t\t\t\t\tif (eventList[i] === callback){\n\t\t\t\t\t\t\teventList.splice(i, 1);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\treturn this;\n\t};\n\n\t/**\n\t * Invoke all of the callbacks bound to the event\n\t * with any arguments passed in. \n\t * @param {String} event The name of the event.\n\t * @param {*...} args The arguments to pass to the functions listening.\n\t * @return {Tone.Emitter} this\n\t */\n\tTone.Emitter.prototype.emit = function(event){\n\t\tif (this._events){\n\t\t\tvar args = Array.apply(null, arguments).slice(1);\n\t\t\tif (this._events.hasOwnProperty(event)){\n\t\t\t\tvar eventList = this._events[event];\n\t\t\t\tfor (var i = 0, len = eventList.length; i < len; i++){\n\t\t\t\t\teventList[i].apply(this, args);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\treturn this;\n\t};\n\n\t/**\n\t * Add Emitter functions (on/off/emit) to the object\n\t * @param {Object|Function} object The object or class to extend.\n\t */\n\tTone.Emitter.mixin = function(object){\n\t\tvar functions = [\"on\", \"off\", \"emit\"];\n\t\tobject._events = {};\n\t\tfor (var i = 0; i < functions.length; i++){\n\t\t\tvar func = functions[i];\n\t\t\tvar emitterFunc = Tone.Emitter.prototype[func];\n\t\t\tobject[func] = emitterFunc;\n\t\t}\n\t};\n\n\t/**\n\t * Clean up\n\t * @return {Tone.Emitter} this\n\t */\n\tTone.Emitter.prototype.dispose = function(){\n\t\tTone.prototype.dispose.call(this);\n\t\tthis._events = null;\n\t\treturn this;\n\t};\n\n\treturn Tone.Emitter;\n});","define([\"Tone/core/Tone\"], function(Tone){\n\n\t\"use strict\";\n\n\t/**\n\t * @class Base class for all Signals. Used Internally. \n\t *\n\t * @constructor\n\t * @extends {Tone}\n\t */\n\tTone.SignalBase = function(){};\n\n\tTone.extend(Tone.SignalBase);\n\n\t/**\n\t * When signals connect to other signals or AudioParams, \n\t * they take over the output value of that signal or AudioParam. \n\t * For all other nodes, the behavior is the same as a default connect. \n\t *\n\t * @override\n\t * @param {AudioParam|AudioNode|Tone.Signal|Tone} node \n\t * @param {number} [outputNumber=0] The output number to connect from.\n\t * @param {number} [inputNumber=0] The input number to connect to.\n\t * @returns {Tone.SignalBase} this\n\t */\n\tTone.SignalBase.prototype.connect = function(node, outputNumber, inputNumber){\n\t\t//zero it out so that the signal can have full control\n\t\tif ((Tone.Signal && Tone.Signal === node.constructor) || \n\t\t\t\t(Tone.Param && Tone.Param === node.constructor) || \n\t\t\t\t(Tone.TimelineSignal && Tone.TimelineSignal === node.constructor)){\n\t\t\t//cancel changes\n\t\t\tnode._param.cancelScheduledValues(0);\n\t\t\t//reset the value\n\t\t\tnode._param.value = 0;\n\t\t\t//mark the value as overridden\n\t\t\tnode.overridden = true;\n\t\t} else if (node instanceof AudioParam){\n\t\t\tnode.cancelScheduledValues(0);\n\t\t\tnode.value = 0;\n\t\t} \n\t\tTone.prototype.connect.call(this, node, outputNumber, inputNumber);\n\t\treturn this;\n\t};\n\n\treturn Tone.SignalBase;\n});","define([\"Tone/core/Tone\", \"Tone/type/TimeBase\"], function (Tone) {\n\n\t/**\n\t * @class Tone.Time is a primitive type for encoding Time values. \n\t * Eventually all time values are evaluated to seconds\n\t * using the `eval` method. Tone.Time can be constructed\n\t * with or without the `new` keyword. Tone.Time can be passed\n\t * into the parameter of any method which takes time as an argument. \n\t * @constructor\n\t * @extends {Tone.TimeBase}\n\t * @param {String|Number} val The time value.\n\t * @param {String=} units The units of the value.\n\t * @example\n\t * var t = Tone.Time(\"4n\");//encodes a quarter note\n\t * t.mult(4); // multiply that value by 4\n\t * t.toNotation(); //returns \"1m\"\n\t */\n\tTone.Time = function(val, units){\n\t\tif (this instanceof Tone.Time){\n\n\t\t\t/**\n\t\t\t * If the current clock time should\n\t\t\t * be added to the output\n\t\t\t * @type {Boolean}\n\t\t\t * @private\n\t\t\t */\n\t\t\tthis._plusNow = false;\n\t\t\t\n\t\t\tTone.TimeBase.call(this, val, units);\n\n\t\t} else {\n\t\t\treturn new Tone.Time(val, units);\n\t\t}\n\t};\n\n\tTone.extend(Tone.Time, Tone.TimeBase);\n\n\t//clone the expressions so that \n\t//we can add more without modifying the original\n\tTone.Time.prototype._unaryExpressions = Object.create(Tone.TimeBase.prototype._unaryExpressions);\n\n\t/*\n\t * Adds an additional unary expression\n\t * which quantizes values to the next subdivision\n\t * @type {Object}\n\t * @private\n\t */\n\tTone.Time.prototype._unaryExpressions.quantize = {\n\t\tregexp : /^@/,\n\t\tmethod : function(rh){\n\t\t\treturn Tone.Transport.nextSubdivision(rh());\n\t\t}\n\t};\n\n\t/*\n\t * Adds an additional unary expression\n\t * which adds the current clock time.\n\t * @type {Object}\n\t * @private\n\t */\n\tTone.Time.prototype._unaryExpressions.now = {\n\t\tregexp : /^\\+/,\n\t\tmethod : function(lh){\n\t\t\tthis._plusNow = true;\n\t\t\treturn lh();\n\t\t}\n\t};\n\n\t/**\n\t * Quantize the time by the given subdivision. Optionally add a\n\t * percentage which will move the time value towards the ideal\n\t * quantized value by that percentage. \n\t * @param {Number|Time} val The subdivision to quantize to\n\t * @param {NormalRange} [percent=1] Move the time value\n\t * towards the quantized value by\n\t * a percentage.\n\t * @return {Tone.Time} this\n\t * @example\n\t * Tone.Time(21).quantize(2) //returns 22\n\t * Tone.Time(0.6).quantize(\"4n\", 0.5) //returns 0.55\n\t */\n\tTone.Time.prototype.quantize = function(subdiv, percent){\n\t\tpercent = this.defaultArg(percent, 1);\n\t\tthis._expr = function(expr, subdivision, percent){\n\t\t\texpr = expr();\n\t\t\tsubdivision = subdivision.toSeconds();\n\t\t\tvar multiple = Math.round(expr / subdivision);\n\t\t\tvar ideal = multiple * subdivision;\n\t\t\tvar diff = ideal - expr;\n\t\t\treturn expr + diff * percent;\n\t\t}.bind(this, this._expr, new this.constructor(subdiv), percent);\n\t\treturn this;\n\t};\n\n\t/**\n\t * Adds the clock time to the time expression at the \n\t * moment of evaluation. \n\t * @return {Tone.Time} this\n\t */\n\tTone.Time.prototype.addNow = function(){\n\t\tthis._plusNow = true;\n\t\treturn this;\n\t};\n\n\t/**\n\t * @override\n\t * Override the default value return when no arguments are passed in.\n\t * The default value is 'now'\n\t * @private\n\t */\n\tTone.Time.prototype._defaultExpr = function(){\n\t\tthis._plusNow = true;\n\t\treturn this._noOp;\n\t};\n\n\t/**\n\t * Copies the value of time to this Time\n\t * @param {Tone.Time} time\n\t * @return {Time}\n\t */\n\tTone.Time.prototype.copy = function(time){\n\t\tTone.TimeBase.prototype.copy.call(this, time);\n\t\tthis._plusNow = time._plusNow;\n\t\treturn this;\n\t};\n\n\t//CONVERSIONS//////////////////////////////////////////////////////////////\n\n\t/**\n\t * Convert a Time to Notation. Values will be thresholded to the nearest 128th note. \n\t * @return {Notation} \n\t * @example\n\t * //if the Transport is at 120bpm:\n\t * Tone.Time(2).toNotation();//returns \"1m\"\n\t */\n\tTone.Time.prototype.toNotation = function(){\n\t\tvar time = this.toSeconds();\n\t\tvar testNotations = [\"1m\", \"2n\", \"4n\", \"8n\", \"16n\", \"32n\", \"64n\", \"128n\"];\n\t\tvar retNotation = this._toNotationHelper(time, testNotations);\n\t\t//try the same thing but with tripelets\n\t\tvar testTripletNotations = [\"1m\", \"2n\", \"2t\", \"4n\", \"4t\", \"8n\", \"8t\", \"16n\", \"16t\", \"32n\", \"32t\", \"64n\", \"64t\", \"128n\"];\n\t\tvar retTripletNotation = this._toNotationHelper(time, testTripletNotations);\n\t\t//choose the simpler expression of the two\n\t\tif (retTripletNotation.split(\"+\").length < retNotation.split(\"+\").length){\n\t\t\treturn retTripletNotation;\n\t\t} else {\n\t\t\treturn retNotation;\n\t\t}\n\t};\n\n\t/**\n\t * Helper method for Tone.toNotation\n\t * @param {Number} units \n\t * @param {Array} testNotations\n\t * @return {String}\n\t * @private\n\t */\n\tTone.Time.prototype._toNotationHelper = function(units, testNotations){\n\t\t//the threshold is the last value in the array\n\t\tvar threshold = this._notationToUnits(testNotations[testNotations.length - 1]);\n\t\tvar retNotation = \"\";\n\t\tfor (var i = 0; i < testNotations.length; i++){\n\t\t\tvar notationTime = this._notationToUnits(testNotations[i]);\n\t\t\t//account for floating point errors (i.e. round up if the value is 0.999999)\n\t\t\tvar multiple = units / notationTime;\n\t\t\tvar floatingPointError = 0.000001;\n\t\t\tif (1 - multiple % 1 < floatingPointError){\n\t\t\t\tmultiple += floatingPointError;\n\t\t\t}\n\t\t\tmultiple = Math.floor(multiple);\n\t\t\tif (multiple > 0){\n\t\t\t\tif (multiple === 1){\n\t\t\t\t\tretNotation += testNotations[i];\n\t\t\t\t} else {\n\t\t\t\t\tretNotation += multiple.toString() + \"*\" + testNotations[i];\n\t\t\t\t}\n\t\t\t\tunits -= multiple * notationTime;\n\t\t\t\tif (units < threshold){\n\t\t\t\t\tbreak;\n\t\t\t\t} else {\n\t\t\t\t\tretNotation += \" + \";\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tif (retNotation === \"\"){\n\t\t\tretNotation = \"0\";\n\t\t}\n\t\treturn retNotation;\n\t};\n\n\t/**\n\t * Convert a notation value to the current units\n\t * @param {Notation} notation \n\t * @return {Number} \n\t * @private\n\t */\n\tTone.Time.prototype._notationToUnits = function(notation){\n\t\tvar primaryExprs = this._primaryExpressions;\n\t\tvar notationExprs = [primaryExprs.n, primaryExprs.t, primaryExprs.m];\n\t\tfor (var i = 0; i < notationExprs.length; i++){\n\t\t\tvar expr = notationExprs[i];\n\t\t\tvar match = notation.match(expr.regexp);\n\t\t\tif (match){\n\t\t\t\treturn expr.method.call(this, match[1]);\n\t\t\t}\n\t\t}\n\t};\n\n\t/**\n\t * Return the time encoded as Bars:Beats:Sixteenths.\n\t * @return {BarsBeatsSixteenths}\n\t */\n\tTone.Time.prototype.toBarsBeatsSixteenths = function(){\n\t\tvar quarterTime = this._beatsToUnits(1);\n\t\tvar quarters = this.toSeconds() / quarterTime;\n\t\tvar measures = Math.floor(quarters / this._timeSignature());\n\t\tvar sixteenths = (quarters % 1) * 4;\n\t\tquarters = Math.floor(quarters) % this._timeSignature();\n\t\tsixteenths = sixteenths.toString();\n\t\tif (sixteenths.length > 3){\n\t\t\tsixteenths = parseFloat(sixteenths).toFixed(3);\n\t\t}\n\t\tvar progress = [measures, quarters, sixteenths];\n\t\treturn progress.join(\":\");\n\t};\n\n\t/**\n\t * Return the time in ticks.\n\t * @return {Ticks}\n\t */\n\tTone.Time.prototype.toTicks = function(){\n\t\tvar quarterTime = this._beatsToUnits(1);\n\t\tvar quarters = this.valueOf() / quarterTime;\n\t\treturn Math.floor(quarters * Tone.Transport.PPQ);\n\t};\n\n\t/**\n\t * Return the time in samples\n\t * @return {Samples} \n\t */\n\tTone.Time.prototype.toSamples = function(){\n\t\treturn this.toSeconds() * this.context.sampleRate;\n\t};\n\n\t/**\n\t * Return the time as a frequency value\n\t * @return {Frequency} \n\t * @example\n\t * Tone.Time(2).toFrequency(); //0.5\n\t */\n\tTone.Time.prototype.toFrequency = function(){\n\t\treturn 1/this.toSeconds();\n\t};\n\n\t/**\n\t * Return the time in seconds.\n\t * @return {Seconds} \n\t */\n\tTone.Time.prototype.toSeconds = function(){\n\t\treturn this.valueOf();\n\t};\n\n\t/**\n\t * Return the time in milliseconds.\n\t * @return {Milliseconds} \n\t */\n\tTone.Time.prototype.toMilliseconds = function(){\n\t\treturn this.toSeconds() * 1000;\n\t};\n\n\t/**\n\t * Return the time in seconds.\n\t * @return {Seconds} \n\t */\n\tTone.Time.prototype.valueOf = function(){\n\t\tvar val = this._expr();\n\t\treturn val + (this._plusNow?this.now():0);\n\t};\n\n\treturn Tone.Time;\n});","define([\"Tone/core/Tone\"], function (Tone) {\n\n\t/**\n\t * @class Tone.TimeBase is a flexible encoding of time\n\t * which can be evaluated to and from a string.\n\t * Parsing code modified from https://code.google.com/p/tapdigit/\n\t * Copyright 2011 2012 Ariya Hidayat, New BSD License\n\t * @extends {Tone}\n\t * @param {Time} val The time value as a number or string\n\t * @param {String=} units Unit values\n\t * @example\n\t * Tone.TimeBase(4, \"n\")\n\t * Tone.TimeBase(2, \"t\")\n\t * Tone.TimeBase(\"2t\").add(\"1m\")\n\t * Tone.TimeBase(\"2t + 1m\");\n\t */\n\tTone.TimeBase = function(val, units){\n\n\t\t//allows it to be constructed with or without 'new'\n\t\tif (this instanceof Tone.TimeBase) {\n\n\t\t\t/**\n\t\t\t * Any expressions parsed from the Time\n\t\t\t * @type {Array}\n\t\t\t * @private\n\t\t\t */\n\t\t\tthis._expr = this._noOp;\n\n\t\t\tif (val instanceof Tone.TimeBase){\n\t\t\t\tthis.copy(val);\n\t\t\t} else if (!this.isUndef(units) || this.isNumber(val)){\n\t\t\t\t//default units\n\t\t\t\tunits = this.defaultArg(units, this._defaultUnits);\n\t\t\t\tvar method = this._primaryExpressions[units].method;\n\t\t\t\tthis._expr = method.bind(this, val);\n\t\t\t} else if (this.isString(val)){\n\t\t\t\tthis.set(val);\n\t\t\t} else if (this.isUndef(val)){\n\t\t\t\t//default expression\n\t\t\t\tthis._expr = this._defaultExpr();\n\t\t\t}\n\t\t} else {\n\n\t\t\treturn new Tone.TimeBase(val, units);\n\t\t}\n\t};\n\n\tTone.extend(Tone.TimeBase);\n\n\t/**\n\t * Repalce the current time value with the value\n\t * given by the expression string.\n\t * @param {String} exprString\n\t * @return {Tone.TimeBase} this\n\t */\n\tTone.TimeBase.prototype.set = function(exprString){\n\t\tthis._expr = this._parseExprString(exprString);\n\t\treturn this;\n\t};\n\n\t/**\n\t * Return a clone of the TimeBase object.\n\t * @return {Tone.TimeBase} The new cloned Tone.TimeBase\n\t */\n\tTone.TimeBase.prototype.clone = function(){\n\t\tvar instance = new this.constructor();\n\t\tinstance.copy(this);\n\t\treturn instance;\n\t};\n\n\t/**\n\t * Copies the value of time to this Time\n\t * @param {Tone.TimeBase} time\n\t * @return {TimeBase}\n\t */\n\tTone.TimeBase.prototype.copy = function(time){\n\t\tvar val = time._expr();\n\t\treturn this.set(val);\n\t};\n\n\t///////////////////////////////////////////////////////////////////////////\n\t//\tABSTRACT SYNTAX TREE PARSER\n\t///////////////////////////////////////////////////////////////////////////\n\n\t/**\n\t * All the primary expressions.\n\t * @private\n\t * @type {Object}\n\t */\n\tTone.TimeBase.prototype._primaryExpressions = {\n\t\t\"n\" : {\n\t\t\tregexp : /^(\\d+)n/i,\n\t\t\tmethod : function(value){\n\t\t\t\tvalue = parseInt(value);\n\t\t\t\tif (value === 1){\n\t\t\t\t\treturn this._beatsToUnits(this._timeSignature());\n\t\t\t\t} else {\n\t\t\t\t\treturn this._beatsToUnits(4 / value);\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\t\t\"t\" : {\n\t\t\tregexp : /^(\\d+)t/i,\n\t\t\tmethod : function(value){\n\t\t\t\tvalue = parseInt(value);\n\t\t\t\treturn this._beatsToUnits(8 / (parseInt(value) * 3));\n\t\t\t}\n\t\t},\n\t\t\"m\" : {\n\t\t\tregexp : /^(\\d+)m/i,\n\t\t\tmethod : function(value){\n\t\t\t\treturn this._beatsToUnits(parseInt(value) * this._timeSignature());\n\t\t\t}\n\t\t},\n\t\t\"i\" : {\n\t\t\tregexp : /^(\\d+)i/i,\n\t\t\tmethod : function(value){\n\t\t\t\treturn this._ticksToUnits(parseInt(value));\n\t\t\t}\n\t\t},\n\t\t\"hz\" : {\n\t\t\tregexp : /^(\\d+(?:\\.\\d+)?)hz/i,\n\t\t\tmethod : function(value){\n\t\t\t\treturn this._frequencyToUnits(parseFloat(value));\n\t\t\t}\n\t\t},\n\t\t\"tr\" : {\n\t\t\tregexp : /^(\\d+(?:\\.\\d+)?):(\\d+(?:\\.\\d+)?):?(\\d+(?:\\.\\d+)?)?/,\n\t\t\tmethod : function(m, q, s){\n\t\t\t\tvar total = 0;\n\t\t\t\tif (m && m !== \"0\"){\n\t\t\t\t\ttotal += this._beatsToUnits(this._timeSignature() * parseFloat(m));\n\t\t\t\t}\n\t\t\t\tif (q && q !== \"0\"){\n\t\t\t\t\ttotal += this._beatsToUnits(parseFloat(q));\n\t\t\t\t}\n\t\t\t\tif (s && s !== \"0\"){\n\t\t\t\t\ttotal += this._beatsToUnits(parseFloat(s) / 4);\n\t\t\t\t}\n\t\t\t\treturn total;\n\t\t\t}\n\t\t},\n\t\t\"s\" : {\n\t\t\tregexp : /^(\\d+(?:\\.\\d+)?s)/,\n\t\t\tmethod : function(value){\n\t\t\t\treturn this._secondsToUnits(parseFloat(value));\n\t\t\t}\n\t\t},\n\t\t\"samples\" : {\n\t\t\tregexp : /^(\\d+)samples/,\n\t\t\tmethod : function(value){\n\t\t\t\treturn parseInt(value) / this.context.sampleRate;\n\t\t\t}\n\t\t},\n\t\t\"default\" : {\n\t\t\tregexp : /^(\\d+(?:\\.\\d+)?)/,\n\t\t\tmethod : function(value){\n\t\t\t\treturn this._primaryExpressions[this._defaultUnits].method.call(this, value);\n\t\t\t}\n\t\t}\n\t};\n\n\t/**\n\t * All the binary expressions that TimeBase can accept.\n\t * @private\n\t * @type {Object}\n\t */\n\tTone.TimeBase.prototype._binaryExpressions = {\n\t\t\"+\" : {\n\t\t\tregexp : /^\\+/,\n\t\t\tprecedence : 2,\n\t\t\tmethod : function(lh, rh){\n\t\t\t\treturn lh() + rh();\n\t\t\t}\n\t\t},\n\t\t\"-\" : {\n\t\t\tregexp : /^\\-/,\n\t\t\tprecedence : 2,\n\t\t\tmethod : function(lh, rh){\n\t\t\t\treturn lh() - rh();\n\t\t\t}\n\t\t},\n\t\t\"*\" : {\n\t\t\tregexp : /^\\*/,\n\t\t\tprecedence : 1,\n\t\t\tmethod : function(lh, rh){\n\t\t\t\treturn lh() * rh();\n\t\t\t}\n\t\t},\n\t\t\"/\" : {\n\t\t\tregexp : /^\\//,\n\t\t\tprecedence : 1,\n\t\t\tmethod : function(lh, rh){\n\t\t\t\treturn lh() / rh();\n\t\t\t}\n\t\t}\n\t};\n\n\t/**\n\t * All the unary expressions.\n\t * @private\n\t * @type {Object}\n\t */\n\tTone.TimeBase.prototype._unaryExpressions = {\n\t\t\"neg\" : {\n\t\t\tregexp : /^\\-/,\n\t\t\tmethod : function(lh){\n\t\t\t\treturn -lh();\n\t\t\t}\n\t\t}\n\t};\n\n\t/**\n\t * Syntactic glue which holds expressions together\n\t * @private\n\t * @type {Object}\n\t */\n\tTone.TimeBase.prototype._syntaxGlue = {\n\t\t\"(\" : {\n\t\t\tregexp : /^\\(/\n\t\t},\n\t\t\")\" : {\n\t\t\tregexp : /^\\)/\n\t\t}\n\t};\n\n\t/**\n\t * tokenize the expression based on the Expressions object\n\t * @param {string} expr \n\t * @return {Object} returns two methods on the tokenized list, next and peek\n\t * @private\n\t */\n\tTone.TimeBase.prototype._tokenize = function(expr){\n\t\tvar position = -1;\n\t\tvar tokens = [];\n\n\t\twhile(expr.length > 0){\n\t\t\texpr = expr.trim();\n\t\t\tvar token = getNextToken(expr, this);\n\t\t\ttokens.push(token);\n\t\t\texpr = expr.substr(token.value.length);\n\t\t}\n\n\t\tfunction getNextToken(expr, context){\n\t\t\tvar expressions = [\"_binaryExpressions\", \"_unaryExpressions\", \"_primaryExpressions\", \"_syntaxGlue\"];\n\t\t\tfor (var i = 0; i < expressions.length; i++){\n\t\t\t\tvar group = context[expressions[i]];\n\t\t\t\tfor (var opName in group){\n\t\t\t\t\tvar op = group[opName];\n\t\t\t\t\tvar reg = op.regexp;\n\t\t\t\t\tvar match = expr.match(reg);\n\t\t\t\t\tif (match !== null){\n\t\t\t\t\t\treturn {\n\t\t\t\t\t\t\tmethod : op.method,\n\t\t\t\t\t\t\tprecedence : op.precedence,\n\t\t\t\t\t\t\tregexp : op.regexp,\n\t\t\t\t\t\t\tvalue : match[0],\n\t\t\t\t\t\t};\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\tthrow new SyntaxError(\"Tone.TimeBase: Unexpected token \"+expr);\n\t\t}\n\n\t\treturn {\n\t\t\tnext : function(){\n\t\t\t\treturn tokens[++position];\n\t\t\t},\n\t\t\tpeek : function(){\n\t\t\t\treturn tokens[position + 1];\n\t\t\t}\n\t\t};\n\t};\n\n\t/**\n\t * Given a token, find the value within the groupName\n\t * @param {Object} token\n\t * @param {String} groupName\n\t * @param {Number} precedence\n\t * @private\n\t */\n\tTone.TimeBase.prototype._matchGroup = function(token, group, prec) {\n\t\tvar ret = false;\n\t\tif (!this.isUndef(token)){\n\t\t\tfor (var opName in group){\n\t\t\t\tvar op = group[opName];\n\t\t\t\tif (op.regexp.test(token.value)){\n\t\t\t\t\tif (!this.isUndef(prec)){\n\t\t\t\t\t\tif(op.precedence === prec){\t\n\t\t\t\t\t\t\treturn op;\n\t\t\t\t\t\t}\n\t\t\t\t\t} else {\n\t\t\t\t\t\treturn op;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\treturn ret;\n\t};\n\n\t/**\n\t * Match a binary expression given the token and the precedence\n\t * @param {Lexer} lexer\n\t * @param {Number} precedence\n\t * @private\n\t */\n\tTone.TimeBase.prototype._parseBinary = function(lexer, precedence){\n\t\tif (this.isUndef(precedence)){\n\t\t\tprecedence = 2;\n\t\t}\n\t\tvar expr;\n\t\tif (precedence < 0){\n\t\t\texpr = this._parseUnary(lexer);\n\t\t} else {\n\t\t\texpr = this._parseBinary(lexer, precedence - 1);\n\t\t}\n\t\tvar token = lexer.peek();\n\t\twhile (token && this._matchGroup(token, this._binaryExpressions, precedence)){\n\t\t\ttoken = lexer.next();\n\t\t\texpr = token.method.bind(this, expr, this._parseBinary(lexer, precedence - 1));\n\t\t\ttoken = lexer.peek();\n\t\t}\n\t\treturn expr;\n\t};\n\n\t/**\n\t * Match a unary expression.\n\t * @param {Lexer} lexer\n\t * @private\n\t */\n\tTone.TimeBase.prototype._parseUnary = function(lexer){\n\t\tvar token, expr;\n\t\ttoken = lexer.peek();\n\t\tvar op = this._matchGroup(token, this._unaryExpressions);\n\t\tif (op) {\n\t\t\ttoken = lexer.next();\n\t\t\texpr = this._parseUnary(lexer);\n\t\t\treturn op.method.bind(this, expr);\n\t\t}\n\t\treturn this._parsePrimary(lexer);\n\t};\n\n\t/**\n\t * Match a primary expression (a value).\n\t * @param {Lexer} lexer\n\t * @private\n\t */\n\tTone.TimeBase.prototype._parsePrimary = function(lexer){\n\t\tvar token, expr;\n\t\ttoken = lexer.peek();\n\t\tif (this.isUndef(token)) {\n\t\t\tthrow new SyntaxError(\"Tone.TimeBase: Unexpected end of expression\");\n\t\t}\n\t\tif (this._matchGroup(token, this._primaryExpressions)) {\n\t\t\ttoken = lexer.next();\n\t\t\tvar matching = token.value.match(token.regexp);\n\t\t\treturn token.method.bind(this, matching[1], matching[2], matching[3]);\n\t\t}\n\t\tif (token && token.value === \"(\"){\n\t\t\tlexer.next();\n\t\t\texpr = this._parseBinary(lexer);\n\t\t\ttoken = lexer.next();\n\t\t\tif (!(token && token.value === \")\")) {\n\t\t\t\tthrow new SyntaxError(\"Expected )\");\n\t\t\t}\n\t\t\treturn expr;\n\t\t}\n\t\tthrow new SyntaxError(\"Tone.TimeBase: Cannot process token \" + token.value);\n\t};\n\n\t/**\n\t * Recursively parse the string expression into a syntax tree.\n\t * @param {string} expr \n\t * @return {Function} the bound method to be evaluated later\n\t * @private\n\t */\n\tTone.TimeBase.prototype._parseExprString = function(exprString){\n\t\tif (!this.isString(exprString)){\n\t\t\texprString = exprString.toString();\n\t\t}\n\t\tvar lexer = this._tokenize(exprString);\n\t\tvar tree = this._parseBinary(lexer);\n\t\treturn tree;\n\t};\n\n\t///////////////////////////////////////////////////////////////////////////\n\t//\tDEFAULTS\n\t///////////////////////////////////////////////////////////////////////////\n\n\t/**\n\t * The initial expression value\n\t * @return {Number} The initial value 0\n\t * @private\n\t */\n\tTone.TimeBase.prototype._noOp = function(){\n\t\treturn 0;\n\t};\n\n\t/**\n\t * The default expression value if no arguments are given\n\t * @private\n\t */\n\tTone.TimeBase.prototype._defaultExpr = function(){\n\t\treturn this._noOp;\n\t};\n\n\t/**\n\t * The default units if none are given.\n\t * @private\n\t */\n\tTone.TimeBase.prototype._defaultUnits = \"s\";\n\n\t///////////////////////////////////////////////////////////////////////////\n\t//\tUNIT CONVERSIONS\n\t///////////////////////////////////////////////////////////////////////////\n\n\t/**\n\t * Returns the value of a frequency in the current units\n\t * @param {Frequency} freq\n\t * @return {Number}\n\t * @private\n\t */\n\tTone.TimeBase.prototype._frequencyToUnits = function(freq){\n\t\treturn 1/freq;\n\t};\n\n\t/**\n\t * Return the value of the beats in the current units\n\t * @param {Number} beats\n\t * @return {Number}\n\t * @private\n\t */\n\tTone.TimeBase.prototype._beatsToUnits = function(beats){\n\t\treturn (60 / Tone.Transport.bpm.value) * beats;\n\t};\n\n\t/**\n\t * Returns the value of a second in the current units\n\t * @param {Seconds} seconds\n\t * @return {Number}\n\t * @private\n\t */\n\tTone.TimeBase.prototype._secondsToUnits = function(seconds){\n\t\treturn seconds;\n\t};\n\n\t/**\n\t * Returns the value of a tick in the current time units\n\t * @param {Ticks} ticks\n\t * @return {Number}\n\t * @private\n\t */\n\tTone.TimeBase.prototype._ticksToUnits = function(ticks){\n\t\treturn ticks * (this._beatsToUnits(1) / Tone.Transport.PPQ);\n\t};\n\n\t/**\n\t * Return the time signature.\n\t * @return {Number}\n\t * @private\n\t */\n\tTone.TimeBase.prototype._timeSignature = function(){\n\t\treturn Tone.Transport.timeSignature;\n\t};\n\n\t///////////////////////////////////////////////////////////////////////////\n\t//\tEXPRESSIONS\n\t///////////////////////////////////////////////////////////////////////////\n\n\t/**\n\t * Push an expression onto the expression list\n\t * @param {Time} val\n\t * @param {String} type\n\t * @param {String} units\n\t * @return {Tone.TimeBase} \n\t * @private\n\t */\n\tTone.TimeBase.prototype._pushExpr = function(val, name, units){\n\t\t//create the expression\n\t\tif (!(val instanceof Tone.TimeBase)){\n\t\t\tval = new this.constructor(val, units);\n\t\t}\n\t\tthis._expr = this._binaryExpressions[name].method.bind(this, this._expr, val._expr);\n\t\treturn this;\n\t};\n\n\t/**\n\t * Add to the current value.\n\t * @param {Time} val The value to add\n\t * @param {String=} units Optional units to use with the value.\n\t * @return {Tone.TimeBase} this\n\t * @example\n\t * Tone.TimeBase(\"2m\").add(\"1m\"); //\"3m\"\n\t */\n\tTone.TimeBase.prototype.add = function(val, units){\n\t\treturn this._pushExpr(val, \"+\", units);\n\t};\n\n\t/**\n\t * Subtract the value from the current time.\n\t * @param {Time} val The value to subtract\n\t * @param {String=} units Optional units to use with the value.\n\t * @return {Tone.TimeBase} this\n\t * @example\n\t * Tone.TimeBase(\"2m\").sub(\"1m\"); //\"1m\"\n\t */\n\tTone.TimeBase.prototype.sub = function(val, units){\n\t\treturn this._pushExpr(val, \"-\", units);\n\t};\n\n\t/**\n\t * Multiply the current value by the given time.\n\t * @param {Time} val The value to multiply\n\t * @param {String=} units Optional units to use with the value.\n\t * @return {Tone.TimeBase} this\n\t * @example\n\t * Tone.TimeBase(\"2m\").mult(\"2\"); //\"4m\"\n\t */\n\tTone.TimeBase.prototype.mult = function(val, units){\n\t\treturn this._pushExpr(val, \"*\", units);\n\t};\n\n\t/**\n\t * Divide the current value by the given time.\n\t * @param {Time} val The value to divide by\n\t * @param {String=} units Optional units to use with the value.\n\t * @return {Tone.TimeBase} this\n\t * @example\n\t * Tone.TimeBase(\"2m\").div(2); //\"1m\"\n\t */\n\tTone.TimeBase.prototype.div = function(val, units){\n\t\treturn this._pushExpr(val, \"/\", units);\n\t};\n\n\t/**\n\t * Evaluate the time value. Returns the time\n\t * in seconds.\n\t * @return {Seconds} \n\t */\n\tTone.TimeBase.prototype.valueOf = function(){\n\t\treturn this._expr();\n\t};\n\n\t/**\n\t * Clean up\n\t * @return {Tone.TimeBase} this\n\t */\n\tTone.TimeBase.prototype.dispose = function(){\n\t\tthis._expr = null;\n\t};\n\n\treturn Tone.TimeBase;\n});","define([\"Tone/core/Tone\", \"Tone/type/Type\"], function(Tone){\n\n\t\"use strict\";\n\n\t/**\n\t * @class Tone.Param wraps the native Web Audio's AudioParam to provide\n\t * additional unit conversion functionality. It also\n\t * serves as a base-class for classes which have a single,\n\t * automatable parameter. \n\t * @extends {Tone}\n\t * @param {AudioParam} param The parameter to wrap.\n\t * @param {Tone.Type} units The units of the audio param.\n\t * @param {Boolean} convert If the param should be converted.\n\t */\n\tTone.Param = function(){\n\n\t\tvar options = this.optionsObject(arguments, [\"param\", \"units\", \"convert\"], Tone.Param.defaults);\n\n\t\t/**\n\t\t * The native parameter to control\n\t\t * @type {AudioParam}\n\t\t * @private\n\t\t */\n\t\tthis._param = this.input = options.param;\n\n\t\t/**\n\t\t * The units of the parameter\n\t\t * @type {Tone.Type}\n\t\t */\n\t\tthis.units = options.units;\n\n\t\t/**\n\t\t * If the value should be converted or not\n\t\t * @type {Boolean}\n\t\t */\n\t\tthis.convert = options.convert;\n\n\t\t/**\n\t\t * True if the signal value is being overridden by \n\t\t * a connected signal.\n\t\t * @readOnly\n\t\t * @type {boolean}\n\t\t * @private\n\t\t */\n\t\tthis.overridden = false;\n\n\t\t/**\n\t\t * If there is an LFO, this is where it is held.\n\t\t * @type {Tone.LFO}\n\t\t * @private\n\t\t */\n\t\tthis._lfo = null;\n\n\t\tif (this.isObject(options.lfo)){\n\t\t\tthis.value = options.lfo;\n\t\t} else if (!this.isUndef(options.value)){\n\t\t\tthis.value = options.value;\n\t\t}\n\t};\n\n\tTone.extend(Tone.Param);\n\t\n\t/**\n\t * Defaults\n\t * @type {Object}\n\t * @const\n\t */\n\tTone.Param.defaults = {\n\t\t\"units\" : Tone.Type.Default,\n\t\t\"convert\" : true,\n\t\t\"param\" : undefined\n\t};\n\n\t/**\n\t * The current value of the parameter. \n\t * @memberOf Tone.Param#\n\t * @type {Number}\n\t * @name value\n\t */\n\tObject.defineProperty(Tone.Param.prototype, \"value\", {\n\t\tget : function(){\n\t\t\treturn this._toUnits(this._param.value);\n\t\t},\n\t\tset : function(value){\n\t\t\tif (this.isObject(value)){\n\t\t\t\t//throw an error if the LFO needs to be included\n\t\t\t\tif (this.isUndef(Tone.LFO)){\n\t\t\t\t\tthrow new Error(\"Include 'Tone.LFO' to use an LFO as a Param value.\");\n\t\t\t\t}\n\t\t\t\t//remove the old one\n\t\t\t\tif (this._lfo){\n\t\t\t\t\tthis._lfo.dispose();\n\t\t\t\t}\n\t\t\t\tthis._lfo = new Tone.LFO(value).start();\n\t\t\t\tthis._lfo.connect(this.input);\n\t\t\t} else {\n\t\t\t\tvar convertedVal = this._fromUnits(value);\n\t\t\t\tthis._param.cancelScheduledValues(0);\n\t\t\t\tthis._param.value = convertedVal;\n\t\t\t}\n\t\t}\n\t});\n\n\t/**\n\t * Convert the given value from the type specified by Tone.Param.units\n\t * into the destination value (such as Gain or Frequency).\n\t * @private\n\t * @param {*} val the value to convert\n\t * @return {number} the number which the value should be set to\n\t */\n\tTone.Param.prototype._fromUnits = function(val){\n\t\tif (this.convert || this.isUndef(this.convert)){\n\t\t\tswitch(this.units){\n\t\t\t\tcase Tone.Type.Time: \n\t\t\t\t\treturn this.toSeconds(val);\n\t\t\t\tcase Tone.Type.Frequency: \n\t\t\t\t\treturn this.toFrequency(val);\n\t\t\t\tcase Tone.Type.Decibels: \n\t\t\t\t\treturn this.dbToGain(val);\n\t\t\t\tcase Tone.Type.NormalRange: \n\t\t\t\t\treturn Math.min(Math.max(val, 0), 1);\n\t\t\t\tcase Tone.Type.AudioRange: \n\t\t\t\t\treturn Math.min(Math.max(val, -1), 1);\n\t\t\t\tcase Tone.Type.Positive: \n\t\t\t\t\treturn Math.max(val, 0);\n\t\t\t\tdefault:\n\t\t\t\t\treturn val;\n\t\t\t}\n\t\t} else {\n\t\t\treturn val;\n\t\t}\n\t};\n\n\t/**\n\t * Convert the parameters value into the units specified by Tone.Param.units.\n\t * @private\n\t * @param {number} val the value to convert\n\t * @return {number}\n\t */\n\tTone.Param.prototype._toUnits = function(val){\n\t\tif (this.convert || this.isUndef(this.convert)){\n\t\t\tswitch(this.units){\n\t\t\t\tcase Tone.Type.Decibels: \n\t\t\t\t\treturn this.gainToDb(val);\n\t\t\t\tdefault:\n\t\t\t\t\treturn val;\n\t\t\t}\n\t\t} else {\n\t\t\treturn val;\n\t\t}\n\t};\n\n\t/**\n\t * the minimum output value\n\t * @type {Number}\n\t * @private\n\t */\n\tTone.Param.prototype._minOutput = 0.00001;\n\n\t/**\n\t * Schedules a parameter value change at the given time.\n\t * @param {*}\tvalue The value to set the signal.\n\t * @param {Time} time The time when the change should occur.\n\t * @returns {Tone.Param} this\n\t * @example\n\t * //set the frequency to \"G4\" in exactly 1 second from now. \n\t * freq.setValueAtTime(\"G4\", \"+1\");\n\t */\n\tTone.Param.prototype.setValueAtTime = function(value, time){\n\t\tvalue = this._fromUnits(value);\n\t\ttime = this.toSeconds(time);\n\t\tif (time <= this.now() + this.blockTime){\n\t\t\tthis._param.value = value;\n\t\t} else {\n\t\t\tthis._param.setValueAtTime(value, time);\n\t\t}\n\t\treturn this;\n\t};\n\n\t/**\n\t * Creates a schedule point with the current value at the current time.\n\t * This is useful for creating an automation anchor point in order to \n\t * schedule changes from the current value. \n\t *\n\t * @param {number=} now (Optionally) pass the now value in. \n\t * @returns {Tone.Param} this\n\t */\n\tTone.Param.prototype.setRampPoint = function(now){\n\t\tnow = this.defaultArg(now, this.now());\n\t\tvar currentVal = this._param.value;\n\t\t// exponentialRampToValueAt cannot ever ramp from or to 0\n\t\t// More info: https://bugzilla.mozilla.org/show_bug.cgi?id=1125600#c2\n\t\tif (currentVal === 0){\n\t\t\tcurrentVal = this._minOutput;\n\t\t}\n\t\tthis._param.setValueAtTime(currentVal, now);\n\t\treturn this;\n\t};\n\n\t/**\n\t * Schedules a linear continuous change in parameter value from the \n\t * previous scheduled parameter value to the given value.\n\t * \n\t * @param {number} value \n\t * @param {Time} endTime \n\t * @returns {Tone.Param} this\n\t */\n\tTone.Param.prototype.linearRampToValueAtTime = function(value, endTime){\n\t\tvalue = this._fromUnits(value);\n\t\tthis._param.linearRampToValueAtTime(value, this.toSeconds(endTime));\n\t\treturn this;\n\t};\n\n\t/**\n\t * Schedules an exponential continuous change in parameter value from \n\t * the previous scheduled parameter value to the given value.\n\t * \n\t * @param {number} value \n\t * @param {Time} endTime \n\t * @returns {Tone.Param} this\n\t */\n\tTone.Param.prototype.exponentialRampToValueAtTime = function(value, endTime){\n\t\tvalue = this._fromUnits(value);\n\t\tvalue = Math.max(this._minOutput, value);\n\t\tthis._param.exponentialRampToValueAtTime(value, this.toSeconds(endTime));\n\t\treturn this;\n\t};\n\n\t/**\n\t * Schedules an exponential continuous change in parameter value from \n\t * the current time and current value to the given value over the \n\t * duration of the rampTime.\n\t * \n\t * @param {number} value The value to ramp to.\n\t * @param {Time} rampTime the time that it takes the \n\t * value to ramp from it's current value\n\t * @param {Time}\t[startTime=now] \tWhen the ramp should start. \n\t * @returns {Tone.Param} this\n\t * @example\n\t * //exponentially ramp to the value 2 over 4 seconds. \n\t * signal.exponentialRampToValue(2, 4);\n\t */\n\tTone.Param.prototype.exponentialRampToValue = function(value, rampTime, startTime){\n\t\tstartTime = this.toSeconds(startTime);\n\t\tthis.setRampPoint(startTime);\n\t\tthis.exponentialRampToValueAtTime(value, startTime + this.toSeconds(rampTime));\n\t\treturn this;\n\t};\n\n\t/**\n\t * Schedules an linear continuous change in parameter value from \n\t * the current time and current value to the given value over the \n\t * duration of the rampTime.\n\t * \n\t * @param {number} value The value to ramp to.\n\t * @param {Time} rampTime the time that it takes the \n\t * value to ramp from it's current value\n\t * @param {Time}\t[startTime=now] \tWhen the ramp should start. \n\t * @returns {Tone.Param} this\n\t * @example\n\t * //linearly ramp to the value 4 over 3 seconds. \n\t * signal.linearRampToValue(4, 3);\n\t */\n\tTone.Param.prototype.linearRampToValue = function(value, rampTime, startTime){\n\t\tstartTime = this.toSeconds(startTime);\n\t\tthis.setRampPoint(startTime);\n\t\tthis.linearRampToValueAtTime(value, startTime + this.toSeconds(rampTime));\n\t\treturn this;\n\t};\n\n\t/**\n\t * Start exponentially approaching the target value at the given time with\n\t * a rate having the given time constant.\n\t * @param {number} value \n\t * @param {Time} startTime \n\t * @param {number} timeConstant \n\t * @returns {Tone.Param} this \n\t */\n\tTone.Param.prototype.setTargetAtTime = function(value, startTime, timeConstant){\n\t\tvalue = this._fromUnits(value);\n\t\t// The value will never be able to approach without timeConstant > 0.\n\t\t// http://www.w3.org/TR/webaudio/#dfn-setTargetAtTime, where the equation\n\t\t// is described. 0 results in a division by 0.\n\t\tvalue = Math.max(this._minOutput, value);\n\t\ttimeConstant = Math.max(this._minOutput, timeConstant);\n\t\tthis._param.setTargetAtTime(value, this.toSeconds(startTime), timeConstant);\n\t\treturn this;\n\t};\n\n\t/**\n\t * Sets an array of arbitrary parameter values starting at the given time\n\t * for the given duration.\n\t * \t\n\t * @param {Array} values \n\t * @param {Time} startTime \n\t * @param {Time} duration \n\t * @returns {Tone.Param} this\n\t */\n\tTone.Param.prototype.setValueCurveAtTime = function(values, startTime, duration){\n\t\tfor (var i = 0; i < values.length; i++){\n\t\t\tvalues[i] = this._fromUnits(values[i]);\n\t\t}\n\t\tthis._param.setValueCurveAtTime(values, this.toSeconds(startTime), this.toSeconds(duration));\n\t\treturn this;\n\t};\n\n\t/**\n\t * Cancels all scheduled parameter changes with times greater than or \n\t * equal to startTime.\n\t * \n\t * @param {Time} startTime\n\t * @returns {Tone.Param} this\n\t */\n\tTone.Param.prototype.cancelScheduledValues = function(startTime){\n\t\tthis._param.cancelScheduledValues(this.toSeconds(startTime));\n\t\treturn this;\n\t};\n\n\t/**\n\t * Ramps to the given value over the duration of the rampTime. \n\t * Automatically selects the best ramp type (exponential or linear)\n\t * depending on the `units` of the signal\n\t * \n\t * @param {number} value \n\t * @param {Time} rampTime \tThe time that it takes the \n\t * value to ramp from it's current value\n\t * @param {Time}\t[startTime=now] \tWhen the ramp should start. \n\t * @returns {Tone.Param} this\n\t * @example\n\t * //ramp to the value either linearly or exponentially \n\t * //depending on the \"units\" value of the signal\n\t * signal.rampTo(0, 10);\n\t * @example\n\t * //schedule it to ramp starting at a specific time\n\t * signal.rampTo(0, 10, 5)\n\t */\n\tTone.Param.prototype.rampTo = function(value, rampTime, startTime){\n\t\trampTime = this.defaultArg(rampTime, 0);\n\t\tif (this.units === Tone.Type.Frequency || this.units === Tone.Type.BPM || this.units === Tone.Type.Decibels){\n\t\t\tthis.exponentialRampToValue(value, rampTime, startTime);\n\t\t} else {\n\t\t\tthis.linearRampToValue(value, rampTime, startTime);\n\t\t}\n\t\treturn this;\n\t};\n\n\t/**\n\t * The LFO created by the signal instance. If none\n\t * was created, this is null.\n\t * @type {Tone.LFO}\n\t * @readOnly\n\t * @memberOf Tone.Param#\n\t * @name lfo\n\t */\n\tObject.defineProperty(Tone.Param.prototype, \"lfo\", {\n\t\tget : function(){\n\t\t\treturn this._lfo;\n\t\t}\n\t});\n\n\t/**\n\t * Clean up\n\t * @returns {Tone.Param} this\n\t */\n\tTone.Param.prototype.dispose = function(){\n\t\tTone.prototype.dispose.call(this);\n\t\tthis._param = null;\n\t\tif (this._lfo){\n\t\t\tthis._lfo.dispose();\n\t\t\tthis._lfo = null;\n\t\t}\n\t\treturn this;\n\t};\n\n\treturn Tone.Param;\n});","'use strict';\n\ndefine(function (require) {\n var p5sound = require('master');\n\n var Add = require('Tone/signal/Add');\n var Mult = require('Tone/signal/Multiply');\n var Scale = require('Tone/signal/Scale');\n\n /**\n *
Creates a signal that oscillates between -1.0 and 1.0.\n * By default, the oscillation takes the form of a sinusoidal\n * shape ('sine'). Additional types include 'triangle',\n * 'sawtooth' and 'square'. The frequency defaults to\n * 440 oscillations per second (440Hz, equal to the pitch of an\n * 'A' note).
\n *\n * @class p5.Oscillator\n * @constructor\n * @param {Number} [freq] frequency defaults to 440Hz\n * @param {String} [type] type of oscillator. Options:\n * 'sine' (default), 'triangle',\n * 'sawtooth', 'square'\n * @example\n *
\n * var osc;\n * var playing = false;\n *\n * function setup() {\n * backgroundColor = color(255,0,255);\n * textAlign(CENTER);\n *\n * osc = new p5.Oscillator();\n * osc.setType('sine');\n * osc.freq(240);\n * osc.amp(0);\n * osc.start();\n * }\n *\n * function draw() {\n * background(backgroundColor)\n * text('click to play', width/2, height/2);\n * }\n *\n * function mouseClicked() {\n * if (mouseX > 0 && mouseX < width && mouseY < height && mouseY > 0) {\n * if (!playing) {\n * // ramp amplitude to 0.5 over 0.05 seconds\n * osc.amp(0.5, 0.05);\n * playing = true;\n * backgroundColor = color(0,255,255);\n * } else {\n * // ramp amplitude to 0 over 0.5 seconds\n * osc.amp(0, 0.5);\n * playing = false;\n * backgroundColor = color(255,0,255);\n * }\n * }\n * }\n *
\n */\n p5.Oscillator = function(freq, type) {\n if (typeof freq === 'string') {\n var f = type;\n type = freq;\n freq = f;\n } if (typeof type === 'number') {\n var f = type;\n type = freq;\n freq = f;\n }\n this.started = false;\n\n // components\n this.phaseAmount = undefined;\n this.oscillator = p5sound.audiocontext.createOscillator();\n this.f = freq || 440.0; // frequency\n this.oscillator.type = type || 'sine';\n this.oscillator.frequency.setValueAtTime(this.f, p5sound.audiocontext.currentTime);\n\n // connections\n this.output = p5sound.audiocontext.createGain();\n\n this._freqMods = []; // modulators connected to this oscillator's frequency\n\n // set default output gain to 0.5\n this.output.gain.value = 0.5;\n this.output.gain.setValueAtTime(0.5, p5sound.audiocontext.currentTime);\n\n this.oscillator.connect(this.output);\n // stereo panning\n this.panPosition = 0.0;\n this.connection = p5sound.input; // connect to p5sound by default\n this.panner = new p5.Panner(this.output, this.connection, 1);\n\n //array of math operation signal chaining\n this.mathOps = [this.output];\n\n // add to the soundArray so we can dispose of the osc later\n p5sound.soundArray.push(this);\n };\n\n /**\n * Start an oscillator. Accepts an optional parameter to\n * determine how long (in seconds from now) until the\n * oscillator starts.\n *\n * @method start\n * @for p5.Oscillator\n * @param {Number} [time] startTime in seconds from now.\n * @param {Number} [frequency] frequency in Hz.\n */\n p5.Oscillator.prototype.start = function(time, f) {\n if (this.started) {\n var now = p5sound.audiocontext.currentTime;\n this.stop(now);\n }\n if (!this.started) {\n var freq = f || this.f;\n var type = this.oscillator.type;\n\n // set old osc free to be garbage collected (memory)\n if (this.oscillator) {\n this.oscillator.disconnect();\n delete this.oscillator;\n }\n\n // var detune = this.oscillator.frequency.value;\n this.oscillator = p5sound.audiocontext.createOscillator();\n this.oscillator.frequency.value = Math.abs(freq);\n this.oscillator.type = type;\n // this.oscillator.detune.value = detune;\n this.oscillator.connect(this.output);\n time = time || 0;\n this.oscillator.start(time + p5sound.audiocontext.currentTime);\n this.freqNode = this.oscillator.frequency;\n\n // if other oscillators are already connected to this osc's freq\n for (var i in this._freqMods) {\n if (typeof this._freqMods[i].connect !== 'undefined') {\n this._freqMods[i].connect(this.oscillator.frequency);\n }\n }\n\n this.started = true;\n }\n };\n\n /**\n * Stop an oscillator. Accepts an optional parameter\n * to determine how long (in seconds from now) until the\n * oscillator stops.\n *\n * @method stop\n * @for p5.Oscillator\n * @param {Number} secondsFromNow Time, in seconds from now.\n */\n p5.Oscillator.prototype.stop = function(time) {\n if (this.started) {\n var t = time || 0;\n var now = p5sound.audiocontext.currentTime;\n this.oscillator.stop(t + now);\n this.started = false;\n }\n };\n\n /**\n * Set the amplitude between 0 and 1.0. Or, pass in an object\n * such as an oscillator to modulate amplitude with an audio signal.\n *\n * @method amp\n * @for p5.Oscillator\n * @param {Number|Object} vol between 0 and 1.0\n * or a modulating signal/oscillator\n * @param {Number} [rampTime] create a fade that lasts rampTime\n * @param {Number} [timeFromNow] schedule this event to happen\n * seconds from now\n * @return {AudioParam} gain If no value is provided,\n * returns the Web Audio API\n * AudioParam that controls\n * this oscillator's\n * gain/amplitude/volume)\n */\n p5.Oscillator.prototype.amp = function(vol, rampTime, tFromNow) {\n var self = this;\n if (typeof vol === 'number') {\n var rampTime = rampTime || 0;\n var tFromNow = tFromNow || 0;\n var now = p5sound.audiocontext.currentTime;\n this.output.gain.linearRampToValueAtTime(vol, now + tFromNow + rampTime);\n }\n\n else if (vol) {\n vol.connect(self.output.gain);\n } else {\n // return the Gain Node\n return this.output.gain;\n }\n };\n\n // these are now the same thing\n p5.Oscillator.prototype.fade = p5.Oscillator.prototype.amp;\n\n p5.Oscillator.prototype.getAmp = function() {\n return this.output.gain.value;\n };\n\n /**\n * Set frequency of an oscillator to a value. Or, pass in an object\n * such as an oscillator to modulate the frequency with an audio signal.\n *\n * @method freq\n * @for p5.Oscillator\n * @param {Number|Object} Frequency Frequency in Hz\n * or modulating signal/oscillator\n * @param {Number} [rampTime] Ramp time (in seconds)\n * @param {Number} [timeFromNow] Schedule this event to happen\n * at x seconds from now\n * @return {AudioParam} Frequency If no value is provided,\n * returns the Web Audio API\n * AudioParam that controls\n * this oscillator's frequency\n * @example\n *
\n * var osc = new p5.Oscillator(300);\n * osc.start();\n * osc.freq(40, 10);\n *
\n */\n p5.Oscillator.prototype.freq = function(val, rampTime, tFromNow) {\n if (typeof val === 'number' && !isNaN(val)) {\n this.f = val;\n var now = p5sound.audiocontext.currentTime;\n var rampTime = rampTime || 0;\n var tFromNow = tFromNow || 0;\n var t = now + tFromNow + rampTime;\n // var currentFreq = this.oscillator.frequency.value;\n // this.oscillator.frequency.cancelScheduledValues(now);\n\n if (rampTime === 0) {\n this.oscillator.frequency.setValueAtTime(val, tFromNow + now);\n } else {\n if (val > 0 ) {\n this.oscillator.frequency.exponentialRampToValueAtTime(val, tFromNow + rampTime + now);\n } else {\n this.oscillator.frequency.linearRampToValueAtTime(val, tFromNow + rampTime + now);\n }\n }\n\n // reset phase if oscillator has a phase\n if (this.phaseAmount) {\n this.phase(this.phaseAmount);\n }\n\n } else if (val) {\n if (val.output) {\n val = val.output;\n }\n val.connect(this.oscillator.frequency);\n\n // keep track of what is modulating this param\n // so it can be re-connected if\n this._freqMods.push( val );\n } else {\n // return the Frequency Node\n return this.oscillator.frequency;\n }\n };\n\n p5.Oscillator.prototype.getFreq = function() {\n return this.oscillator.frequency.value;\n };\n\n /**\n * Set type to 'sine', 'triangle', 'sawtooth' or 'square'.\n *\n * @method setType\n * @for p5.Oscillator\n * @param {String} type 'sine', 'triangle', 'sawtooth' or 'square'.\n */\n p5.Oscillator.prototype.setType = function(type) {\n this.oscillator.type = type;\n };\n\n p5.Oscillator.prototype.getType = function() {\n return this.oscillator.type;\n };\n\n /**\n * Connect to a p5.sound / Web Audio object.\n *\n * @method connect\n * @for p5.Oscillator\n * @param {Object} unit A p5.sound or Web Audio object\n */\n p5.Oscillator.prototype.connect = function(unit) {\n if (!unit) {\n this.panner.connect(p5sound.input);\n }\n else if (unit.hasOwnProperty('input')) {\n this.panner.connect(unit.input);\n this.connection = unit.input;\n }\n else {\n this.panner.connect(unit);\n this.connection = unit;\n }\n };\n\n /**\n * Disconnect all outputs\n *\n * @method disconnect\n * @for p5.Oscillator\n */\n p5.Oscillator.prototype.disconnect = function() {\n if (this.output) {\n this.output.disconnect();\n }\n if (this.panner) {\n this.panner.disconnect();\n if (this.output) {\n this.output.connect(this.panner);\n }\n }\n this.oscMods = [];\n };\n\n /**\n * Pan between Left (-1) and Right (1)\n *\n * @method pan\n * @for p5.Oscillator\n * @param {Number} panning Number between -1 and 1\n * @param {Number} timeFromNow schedule this event to happen\n * seconds from now\n */\n p5.Oscillator.prototype.pan = function(pval, tFromNow) {\n this.panPosition = pval;\n this.panner.pan(pval, tFromNow);\n };\n\n p5.Oscillator.prototype.getPan = function() {\n return this.panPosition;\n };\n\n // get rid of the oscillator\n p5.Oscillator.prototype.dispose = function() {\n // remove reference from soundArray\n var index = p5sound.soundArray.indexOf(this);\n p5sound.soundArray.splice(index, 1);\n\n if (this.oscillator) {\n var now = p5sound.audiocontext.currentTime;\n this.stop(now);\n this.disconnect();\n this.panner = null;\n this.oscillator = null;\n }\n // if it is a Pulse\n if (this.osc2) {\n this.osc2.dispose();\n }\n };\n\n /**\n * Set the phase of an oscillator between 0.0 and 1.0.\n * In this implementation, phase is a delay time\n * based on the oscillator's current frequency.\n *\n * @method phase\n * @for p5.Oscillator\n * @param {Number} phase float between 0.0 and 1.0\n */\n p5.Oscillator.prototype.phase = function(p) {\n var delayAmt = p5.prototype.map(p, 0, 1.0, 0, 1/this.f);\n var now = p5sound.audiocontext.currentTime;\n\n this.phaseAmount = p;\n\n if (!this.dNode) {\n // create a delay node\n this.dNode = p5sound.audiocontext.createDelay();\n // put the delay node in between output and panner\n this.oscillator.disconnect();\n this.oscillator.connect(this.dNode);\n this.dNode.connect(this.output);\n }\n\n // set delay time to match phase:\n this.dNode.delayTime.setValueAtTime(delayAmt, now);\n };\n\n // ========================== //\n // SIGNAL MATH FOR MODULATION //\n // ========================== //\n\n // return sigChain(this, scale, thisChain, nextChain, Scale);\n var sigChain = function(o, mathObj, thisChain, nextChain, type) {\n var chainSource = o.oscillator;\n // if this type of math already exists in the chain, replace it\n for (var i in o.mathOps) {\n if (o.mathOps[i] instanceof type) {\n chainSource.disconnect();\n o.mathOps[i].dispose();\n thisChain = i;\n // assume nextChain is output gain node unless...\n if (thisChain < o.mathOps.length - 2) {\n nextChain = o.mathOps[i+1];\n }\n }\n }\n if (thisChain === o.mathOps.length - 1) {\n o.mathOps.push(nextChain);\n }\n // assume source is the oscillator unless i > 0\n if (i > 0) {\n chainSource = o.mathOps[i-1];\n }\n chainSource.disconnect();\n chainSource.connect(mathObj);\n mathObj.connect(nextChain);\n o.mathOps[thisChain] = mathObj;\n return o;\n };\n\n /**\n * Add a value to the p5.Oscillator's output amplitude,\n * and return the oscillator. Calling this method again\n * will override the initial add() with a new value.\n *\n * @method add\n * @for p5.Oscillator\n * @param {Number} number Constant number to add\n * @return {p5.Oscillator} Oscillator Returns this oscillator\n * with scaled output\n *\n */\n p5.Oscillator.prototype.add = function(num) {\n var add = new Add(num);\n var thisChain = this.mathOps.length-1;\n var nextChain = this.output;\n return sigChain(this, add, thisChain, nextChain, Add);\n };\n\n /**\n * Multiply the p5.Oscillator's output amplitude\n * by a fixed value (i.e. turn it up!). Calling this method\n * again will override the initial mult() with a new value.\n *\n * @method mult\n * @for p5.Oscillator\n * @param {Number} number Constant number to multiply\n * @return {p5.Oscillator} Oscillator Returns this oscillator\n * with multiplied output\n */\n p5.Oscillator.prototype.mult = function(num) {\n var mult = new Mult(num);\n var thisChain = this.mathOps.length-1;\n var nextChain = this.output;\n return sigChain(this, mult, thisChain, nextChain, Mult);\n };\n\n /**\n * Scale this oscillator's amplitude values to a given\n * range, and return the oscillator. Calling this method\n * again will override the initial scale() with new values.\n *\n * @method scale\n * @for p5.Oscillator\n * @param {Number} inMin input range minumum\n * @param {Number} inMax input range maximum\n * @param {Number} outMin input range minumum\n * @param {Number} outMax input range maximum\n * @return {p5.Oscillator} Oscillator Returns this oscillator\n * with scaled output\n */\n p5.Oscillator.prototype.scale = function(inMin, inMax, outMin, outMax) {\n var mapOutMin, mapOutMax;\n if (arguments.length === 4) {\n mapOutMin = p5.prototype.map(outMin, inMin, inMax, 0, 1) - 0.5;\n mapOutMax = p5.prototype.map(outMax, inMin, inMax, 0, 1) - 0.5;\n }\n else {\n mapOutMin = arguments[0];\n mapOutMax = arguments[1];\n }\n var scale = new Scale(mapOutMin, mapOutMax);\n var thisChain = this.mathOps.length-1;\n var nextChain = this.output;\n return sigChain(this, scale, thisChain, nextChain, Scale);\n\n // this.output.disconnect();\n // this.output.connect(scale)\n };\n\n // ============================== //\n // SinOsc, TriOsc, SqrOsc, SawOsc //\n // ============================== //\n\n /**\n * Constructor: new p5.SinOsc().\n * This creates a Sine Wave Oscillator and is\n * equivalent to new p5.Oscillator('sine')\n * or creating a p5.Oscillator and then calling\n * its method setType('sine').\n * See p5.Oscillator for methods.\n *\n * @class p5.SinOsc\n * @constructor\n * @extends p5.Oscillator\n * @param {Number} [freq] Set the frequency\n */\n p5.SinOsc = function(freq) {\n p5.Oscillator.call(this, freq, 'sine');\n };\n\n p5.SinOsc.prototype = Object.create(p5.Oscillator.prototype);\n\n /**\n * Constructor: new p5.TriOsc().\n * This creates a Triangle Wave Oscillator and is\n * equivalent to new p5.Oscillator('triangle')\n * or creating a p5.Oscillator and then calling\n * its method setType('triangle').\n * See p5.Oscillator for methods.\n *\n * @class p5.TriOsc\n * @constructor\n * @extends p5.Oscillator\n * @param {Number} [freq] Set the frequency\n */\n p5.TriOsc = function(freq) {\n p5.Oscillator.call(this, freq, 'triangle');\n };\n\n p5.TriOsc.prototype = Object.create(p5.Oscillator.prototype);\n\n /**\n * Constructor: new p5.SawOsc().\n * This creates a SawTooth Wave Oscillator and is\n * equivalent to new p5.Oscillator('sawtooth')\n * or creating a p5.Oscillator and then calling\n * its method setType('sawtooth').\n * See p5.Oscillator for methods.\n *\n * @class p5.SawOsc\n * @constructor\n * @extends p5.Oscillator\n * @param {Number} [freq] Set the frequency\n */\n p5.SawOsc = function(freq) {\n p5.Oscillator.call(this, freq, 'sawtooth');\n };\n\n p5.SawOsc.prototype = Object.create(p5.Oscillator.prototype);\n\n /**\n * Constructor: new p5.SqrOsc().\n * This creates a Square Wave Oscillator and is\n * equivalent to new p5.Oscillator('square')\n * or creating a p5.Oscillator and then calling\n * its method setType('square').\n * See p5.Oscillator for methods.\n *\n * @class p5.SqrOsc\n * @constructor\n * @extends p5.Oscillator\n * @param {Number} [freq] Set the frequency\n */\n p5.SqrOsc = function(freq) {\n p5.Oscillator.call(this, freq, 'square');\n };\n\n p5.SqrOsc.prototype = Object.create(p5.Oscillator.prototype);\n\n});\n","define([\"Tone/core/Tone\", \"Tone/type/Type\"], function (Tone) {\n\n\t\"use strict\";\n\n\t/**\n\t * @class A Timeline class for scheduling and maintaining state\n\t * along a timeline. All events must have a \"time\" property. \n\t * Internally, events are stored in time order for fast \n\t * retrieval.\n\t * @extends {Tone}\n\t * @param {Positive} [memory=Infinity] The number of previous events that are retained.\n\t */\n\tTone.Timeline = function(){\n\n\t\tvar options = this.optionsObject(arguments, [\"memory\"], Tone.Timeline.defaults);\n\n\t\t/**\n\t\t * The array of scheduled timeline events\n\t\t * @type {Array}\n\t\t * @private\n\t\t */\n\t\tthis._timeline = [];\n\n\t\t/**\n\t\t * An array of items to remove from the list. \n\t\t * @type {Array}\n\t\t * @private\n\t\t */\n\t\tthis._toRemove = [];\n\n\t\t/**\n\t\t * Flag if the tieline is mid iteration\n\t\t * @private\n\t\t * @type {Boolean}\n\t\t */\n\t\tthis._iterating = false;\n\n\t\t/**\n\t\t * The memory of the timeline, i.e.\n\t\t * how many events in the past it will retain\n\t\t * @type {Positive}\n\t\t */\n\t\tthis.memory = options.memory;\n\t};\n\n\tTone.extend(Tone.Timeline);\n\n\t/**\n\t * the default parameters\n\t * @static\n\t * @const\n\t */\n\tTone.Timeline.defaults = {\n\t\t\"memory\" : Infinity\n\t};\n\n\t/**\n\t * The number of items in the timeline.\n\t * @type {Number}\n\t * @memberOf Tone.Timeline#\n\t * @name length\n\t * @readOnly\n\t */\n\tObject.defineProperty(Tone.Timeline.prototype, \"length\", {\n\t\tget : function(){\n\t\t\treturn this._timeline.length;\n\t\t}\n\t});\n\n\t/**\n\t * Insert an event object onto the timeline. Events must have a \"time\" attribute.\n\t * @param {Object} event The event object to insert into the \n\t * timeline. \n\t * @returns {Tone.Timeline} this\n\t */\n\tTone.Timeline.prototype.add = function(event){\n\t\t//the event needs to have a time attribute\n\t\tif (this.isUndef(event.time)){\n\t\t\tthrow new Error(\"Tone.Timeline: events must have a time attribute\");\n\t\t}\n\t\tif (this._timeline.length){\n\t\t\tvar index = this._search(event.time);\n\t\t\tthis._timeline.splice(index + 1, 0, event);\n\t\t} else {\n\t\t\tthis._timeline.push(event);\t\t\t\n\t\t}\n\t\t//if the length is more than the memory, remove the previous ones\n\t\tif (this.length > this.memory){\n\t\t\tvar diff = this.length - this.memory;\n\t\t\tthis._timeline.splice(0, diff);\n\t\t}\n\t\treturn this;\n\t};\n\n\t/**\n\t * Remove an event from the timeline.\n\t * @param {Object} event The event object to remove from the list.\n\t * @returns {Tone.Timeline} this\n\t */\n\tTone.Timeline.prototype.remove = function(event){\n\t\tif (this._iterating){\n\t\t\tthis._toRemove.push(event);\n\t\t} else {\n\t\t\tvar index = this._timeline.indexOf(event);\n\t\t\tif (index !== -1){\n\t\t\t\tthis._timeline.splice(index, 1);\n\t\t\t}\n\t\t}\n\t\treturn this;\n\t};\n\n\t/**\n\t * Get the nearest event whose time is less than or equal to the given time.\n\t * @param {Number} time The time to query.\n\t * @returns {Object} The event object set after that time.\n\t */\n\tTone.Timeline.prototype.get = function(time){\n\t\tvar index = this._search(time);\n\t\tif (index !== -1){\n\t\t\treturn this._timeline[index];\n\t\t} else {\n\t\t\treturn null;\n\t\t}\n\t};\n\n\t/**\n\t * Return the first event in the timeline without removing it\n\t * @returns {Object} The first event object\n\t */\n\tTone.Timeline.prototype.peek = function(){\n\t\treturn this._timeline[0];\n\t};\n\n\t/**\n\t * Return the first event in the timeline and remove it\n\t * @returns {Object} The first event object\n\t */\n\tTone.Timeline.prototype.shift = function(){\n\t\treturn this._timeline.shift();\n\t};\n\n\t/**\n\t * Get the event which is scheduled after the given time.\n\t * @param {Number} time The time to query.\n\t * @returns {Object} The event object after the given time\n\t */\n\tTone.Timeline.prototype.getAfter = function(time){\n\t\tvar index = this._search(time);\n\t\tif (index + 1 < this._timeline.length){\n\t\t\treturn this._timeline[index + 1];\n\t\t} else {\n\t\t\treturn null;\n\t\t}\n\t};\n\n\t/**\n\t * Get the event before the event at the given time.\n\t * @param {Number} time The time to query.\n\t * @returns {Object} The event object before the given time\n\t */\n\tTone.Timeline.prototype.getBefore = function(time){\n\t\tvar len = this._timeline.length;\n\t\t//if it's after the last item, return the last item\n\t\tif (len > 0 && this._timeline[len - 1].time < time){\n\t\t\treturn this._timeline[len - 1];\n\t\t}\n\t\tvar index = this._search(time);\n\t\tif (index - 1 >= 0){\n\t\t\treturn this._timeline[index - 1];\n\t\t} else {\n\t\t\treturn null;\n\t\t}\n\t};\n\n\t/**\n\t * Cancel events after the given time\n\t * @param {Number} time The time to query.\n\t * @returns {Tone.Timeline} this\n\t */\n\tTone.Timeline.prototype.cancel = function(after){\n\t\tif (this._timeline.length > 1){\n\t\t\tvar index = this._search(after);\n\t\t\tif (index >= 0){\n\t\t\t\tif (this._timeline[index].time === after){\n\t\t\t\t\t//get the first item with that time\n\t\t\t\t\tfor (var i = index; i >= 0; i--){\n\t\t\t\t\t\tif (this._timeline[i].time === after){\n\t\t\t\t\t\t\tindex = i;\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tthis._timeline = this._timeline.slice(0, index);\n\t\t\t\t} else {\n\t\t\t\t\tthis._timeline = this._timeline.slice(0, index + 1);\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tthis._timeline = [];\n\t\t\t}\n\t\t} else if (this._timeline.length === 1){\n\t\t\t//the first item's time\n\t\t\tif (this._timeline[0].time >= after){\n\t\t\t\tthis._timeline = [];\n\t\t\t}\n\t\t}\n\t\treturn this;\n\t};\n\n\t/**\n\t * Cancel events before or equal to the given time.\n\t * @param {Number} time The time to cancel before.\n\t * @returns {Tone.Timeline} this\n\t */\n\tTone.Timeline.prototype.cancelBefore = function(time){\n\t\tif (this._timeline.length){\n\t\t\tvar index = this._search(time);\n\t\t\tif (index >= 0){\n\t\t\t\tthis._timeline = this._timeline.slice(index + 1);\n\t\t\t}\n\t\t}\n\t\treturn this;\n\t};\n\n\t/**\n\t * Does a binary serach on the timeline array and returns the \n\t * nearest event index whose time is after or equal to the given time.\n\t * If a time is searched before the first index in the timeline, -1 is returned.\n\t * If the time is after the end, the index of the last item is returned.\n\t * @param {Number} time \n\t * @return {Number} the index in the timeline array \n\t * @private\n\t */\n\tTone.Timeline.prototype._search = function(time){\n\t\tvar beginning = 0;\n\t\tvar len = this._timeline.length;\n\t\tvar end = len;\n\t\tif (len > 0 && this._timeline[len - 1].time <= time){\n\t\t\treturn len - 1;\n\t\t}\n\t\twhile (beginning < end){\n\t\t\t// calculate the midpoint for roughly equal partition\n\t\t\tvar midPoint = Math.floor(beginning + (end - beginning) / 2);\n\t\t\tvar event = this._timeline[midPoint];\n\t\t\tvar nextEvent = this._timeline[midPoint + 1];\n\t\t\tif (event.time === time){\n\t\t\t\t//choose the last one that has the same time\n\t\t\t\tfor (var i = midPoint; i < this._timeline.length; i++){\n\t\t\t\t\tvar testEvent = this._timeline[i];\n\t\t\t\t\tif (testEvent.time === time){\n\t\t\t\t\t\tmidPoint = i;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\treturn midPoint;\n\t\t\t} else if (event.time < time && nextEvent.time > time){\n\t\t\t\treturn midPoint;\n\t\t\t} else if (event.time > time){\n\t\t\t\t//search lower\n\t\t\t\tend = midPoint;\n\t\t\t} else if (event.time < time){\n\t\t\t\t//search upper\n\t\t\t\tbeginning = midPoint + 1;\n\t\t\t} \n\t\t}\n\t\treturn -1;\n\t};\n\n\t/**\n\t * Internal iterator. Applies extra safety checks for \n\t * removing items from the array. \n\t * @param {Function} callback \n\t * @param {Number=} lowerBound \n\t * @param {Number=} upperBound \n\t * @private\n\t */\n\tTone.Timeline.prototype._iterate = function(callback, lowerBound, upperBound){\n\t\tthis._iterating = true;\n\t\tlowerBound = this.defaultArg(lowerBound, 0);\n\t\tupperBound = this.defaultArg(upperBound, this._timeline.length - 1);\n\t\tfor (var i = lowerBound; i <= upperBound; i++){\n\t\t\tcallback(this._timeline[i]);\n\t\t}\n\t\tthis._iterating = false;\n\t\tif (this._toRemove.length > 0){\n\t\t\tfor (var j = 0; j < this._toRemove.length; j++){\n\t\t\t\tvar index = this._timeline.indexOf(this._toRemove[j]);\n\t\t\t\tif (index !== -1){\n\t\t\t\t\tthis._timeline.splice(index, 1);\n\t\t\t\t}\n\t\t\t}\n\t\t\tthis._toRemove = [];\n\t\t}\n\t};\n\n\t/**\n\t * Iterate over everything in the array\n\t * @param {Function} callback The callback to invoke with every item\n\t * @returns {Tone.Timeline} this\n\t */\n\tTone.Timeline.prototype.forEach = function(callback){\n\t\tthis._iterate(callback);\n\t\treturn this;\n\t};\n\n\t/**\n\t * Iterate over everything in the array at or before the given time.\n\t * @param {Number} time The time to check if items are before\n\t * @param {Function} callback The callback to invoke with every item\n\t * @returns {Tone.Timeline} this\n\t */\n\tTone.Timeline.prototype.forEachBefore = function(time, callback){\n\t\t//iterate over the items in reverse so that removing an item doesn't break things\n\t\tvar upperBound = this._search(time);\n\t\tif (upperBound !== -1){\n\t\t\tthis._iterate(callback, 0, upperBound);\n\t\t}\n\t\treturn this;\n\t};\n\n\t/**\n\t * Iterate over everything in the array after the given time.\n\t * @param {Number} time The time to check if items are before\n\t * @param {Function} callback The callback to invoke with every item\n\t * @returns {Tone.Timeline} this\n\t */\n\tTone.Timeline.prototype.forEachAfter = function(time, callback){\n\t\t//iterate over the items in reverse so that removing an item doesn't break things\n\t\tvar lowerBound = this._search(time);\n\t\tthis._iterate(callback, lowerBound + 1);\n\t\treturn this;\n\t};\n\n\t/**\n\t * Iterate over everything in the array at or after the given time. Similar to \n\t * forEachAfter, but includes the item(s) at the given time.\n\t * @param {Number} time The time to check if items are before\n\t * @param {Function} callback The callback to invoke with every item\n\t * @returns {Tone.Timeline} this\n\t */\n\tTone.Timeline.prototype.forEachFrom = function(time, callback){\n\t\t//iterate over the items in reverse so that removing an item doesn't break things\n\t\tvar lowerBound = this._search(time);\n\t\t//work backwards until the event time is less than time\n\t\twhile (lowerBound >= 0 && this._timeline[lowerBound].time >= time){\n\t\t\tlowerBound--;\n\t\t}\n\t\tthis._iterate(callback, lowerBound + 1);\n\t\treturn this;\n\t};\n\n\t/**\n\t * Iterate over everything in the array at the given time\n\t * @param {Number} time The time to check if items are before\n\t * @param {Function} callback The callback to invoke with every item\n\t * @returns {Tone.Timeline} this\n\t */\n\tTone.Timeline.prototype.forEachAtTime = function(time, callback){\n\t\t//iterate over the items in reverse so that removing an item doesn't break things\n\t\tvar upperBound = this._search(time);\n\t\tif (upperBound !== -1){\n\t\t\tthis._iterate(function(event){\n\t\t\t\tif (event.time === time){\n\t\t\t\t\tcallback(event);\n\t\t\t\t} \n\t\t\t}, 0, upperBound);\n\t\t}\n\t\treturn this;\n\t};\n\n\t/**\n\t * Clean up.\n\t * @return {Tone.Timeline} this\n\t */\n\tTone.Timeline.prototype.dispose = function(){\n\t\tTone.prototype.dispose.call(this);\n\t\tthis._timeline = null;\n\t\tthis._toRemove = null;\n\t};\n\n\treturn Tone.Timeline;\n});","define([\"Tone/core/Tone\", \"Tone/signal/Multiply\", \"Tone/signal/Signal\"], function(Tone){\n\n\t\"use strict\";\n\n\t/**\n\t * @class Negate the incoming signal. i.e. an input signal of 10 will output -10\n\t *\n\t * @constructor\n\t * @extends {Tone.SignalBase}\n\t * @example\n\t * var neg = new Tone.Negate();\n\t * var sig = new Tone.Signal(-2).connect(neg);\n\t * //output of neg is positive 2. \n\t */\n\tTone.Negate = function(){\n\t\t/**\n\t\t * negation is done by multiplying by -1\n\t\t * @type {Tone.Multiply}\n\t\t * @private\n\t\t */\n\t\tthis._multiply = this.input = this.output = new Tone.Multiply(-1);\n\t};\n\n\tTone.extend(Tone.Negate, Tone.SignalBase);\n\n\t/**\n\t * clean up\n\t * @returns {Tone.Negate} this\n\t */\n\tTone.Negate.prototype.dispose = function(){\n\t\tTone.prototype.dispose.call(this);\n\t\tthis._multiply.dispose();\n\t\tthis._multiply = null;\n\t\treturn this;\n\t}; \n\n\treturn Tone.Negate;\n});","define([\"Tone/core/Tone\", \"Tone/signal/Signal\", \"Tone/signal/Multiply\", \"Tone/signal/WaveShaper\"], \nfunction(Tone){\n\n\t\"use strict\";\n\n\t/**\n\t * @class GreaterThanZero outputs 1 when the input is strictly greater than zero\n\t * \n\t * @constructor\n\t * @extends {Tone.SignalBase}\n\t * @example\n\t * var gt0 = new Tone.GreaterThanZero();\n\t * var sig = new Tone.Signal(0.01).connect(gt0);\n\t * //the output of gt0 is 1. \n\t * sig.value = 0;\n\t * //the output of gt0 is 0. \n\t */\n\tTone.GreaterThanZero = function(){\n\t\t\n\t\t/**\n\t\t * @type {Tone.WaveShaper}\n\t\t * @private\n\t\t */\n\t\tthis._thresh = this.output = new Tone.WaveShaper(function(val){\n\t\t\tif (val <= 0){\n\t\t\t\treturn 0;\n\t\t\t} else {\n\t\t\t\treturn 1;\n\t\t\t}\n\t\t}, 127);\n\n\t\t/**\n\t\t * scale the first thresholded signal by a large value.\n\t\t * this will help with values which are very close to 0\n\t\t * @type {Tone.Multiply}\n\t\t * @private\n\t\t */\n\t\tthis._scale = this.input = new Tone.Multiply(10000);\n\n\t\t//connections\n\t\tthis._scale.connect(this._thresh);\n\t};\n\n\tTone.extend(Tone.GreaterThanZero, Tone.SignalBase);\n\n\t/**\n\t * dispose method\n\t * @returns {Tone.GreaterThanZero} this\n\t */\n\tTone.GreaterThanZero.prototype.dispose = function(){\n\t\tTone.prototype.dispose.call(this);\n\t\tthis._scale.dispose();\n\t\tthis._scale = null;\n\t\tthis._thresh.dispose();\n\t\tthis._thresh = null;\n\t\treturn this;\n\t};\n\n\treturn Tone.GreaterThanZero;\n});","define([\"Tone/core/Tone\", \"Tone/signal/TimelineSignal\", \"Tone/core/TimelineState\", \n\t\"Tone/core/Emitter\", \"Tone/core/Context\"], function (Tone) {\n\n\t\"use strict\";\n\n\t/**\n\t * @class A sample accurate clock which provides a callback at the given rate. \n\t * While the callback is not sample-accurate (it is still susceptible to\n\t * loose JS timing), the time passed in as the argument to the callback\n\t * is precise. For most applications, it is better to use Tone.Transport\n\t * instead of the Clock by itself since you can synchronize multiple callbacks.\n\t *\n\t * \t@constructor\n\t * @extends {Tone.Emitter}\n\t * \t@param {function} callback The callback to be invoked with the time of the audio event\n\t * \t@param {Frequency} frequency The rate of the callback\n\t * \t@example\n\t * //the callback will be invoked approximately once a second\n\t * //and will print the time exactly once a second apart.\n\t * var clock = new Tone.Clock(function(time){\n\t * \tconsole.log(time);\n\t * }, 1);\n\t */\n\tTone.Clock = function(){\n\n\t\tTone.Emitter.call(this);\n\n\t\tvar options = this.optionsObject(arguments, [\"callback\", \"frequency\"], Tone.Clock.defaults);\n\n\t\t/**\n\t\t * The callback function to invoke at the scheduled tick.\n\t\t * @type {Function}\n\t\t */\n\t\tthis.callback = options.callback;\n\n\t\t/**\n\t\t * The next time the callback is scheduled.\n\t\t * @type {Number}\n\t\t * @private\n\t\t */\n\t\tthis._nextTick = 0;\n\n\t\t/**\n\t\t * The last state of the clock.\n\t\t * @type {State}\n\t\t * @private\n\t\t */\n\t\tthis._lastState = Tone.State.Stopped;\n\n\t\t/**\n\t\t * The rate the callback function should be invoked. \n\t\t * @type {BPM}\n\t\t * @signal\n\t\t */\n\t\tthis.frequency = new Tone.TimelineSignal(options.frequency, Tone.Type.Frequency);\n\t\tthis._readOnly(\"frequency\");\n\n\t\t/**\n\t\t * The number of times the callback was invoked. Starts counting at 0\n\t\t * and increments after the callback was invoked. \n\t\t * @type {Ticks}\n\t\t * @readOnly\n\t\t */\n\t\tthis.ticks = 0;\n\n\t\t/**\n\t\t * The state timeline\n\t\t * @type {Tone.TimelineState}\n\t\t * @private\n\t\t */\n\t\tthis._state = new Tone.TimelineState(Tone.State.Stopped);\n\n\t\t/**\n\t\t * The loop function bound to its context. \n\t\t * This is necessary to remove the event in the end.\n\t\t * @type {Function}\n\t\t * @private\n\t\t */\n\t\tthis._boundLoop = this._loop.bind(this);\n\n\t\t//bind a callback to the worker thread\n \tthis.context.on(\"tick\", this._boundLoop);\n\t};\n\n\tTone.extend(Tone.Clock, Tone.Emitter);\n\n\t/**\n\t * The defaults\n\t * @const\n\t * @type {Object}\n\t */\n\tTone.Clock.defaults = {\n\t\t\"callback\" : Tone.noOp,\n\t\t\"frequency\" : 1,\n\t\t\"lookAhead\" : \"auto\",\n\t};\n\n\t/**\n\t * Returns the playback state of the source, either \"started\", \"stopped\" or \"paused\".\n\t * @type {Tone.State}\n\t * @readOnly\n\t * @memberOf Tone.Clock#\n\t * @name state\n\t */\n\tObject.defineProperty(Tone.Clock.prototype, \"state\", {\n\t\tget : function(){\n\t\t\treturn this._state.getValueAtTime(this.now());\n\t\t}\n\t});\n\n\t/**\n\t * Start the clock at the given time. Optionally pass in an offset\n\t * of where to start the tick counter from.\n\t * @param {Time} time The time the clock should start\n\t * @param {Ticks=} offset Where the tick counter starts counting from.\n\t * @return {Tone.Clock} this\n\t */\n\tTone.Clock.prototype.start = function(time, offset){\n\t\ttime = this.toSeconds(time);\n\t\tif (this._state.getValueAtTime(time) !== Tone.State.Started){\n\t\t\tthis._state.add({\n\t\t\t\t\"state\" : Tone.State.Started, \n\t\t\t\t\"time\" : time,\n\t\t\t\t\"offset\" : offset\n\t\t\t});\n\t\t}\n\t\treturn this;\t\n\t};\n\n\t/**\n\t * Stop the clock. Stopping the clock resets the tick counter to 0.\n\t * @param {Time} [time=now] The time when the clock should stop.\n\t * @returns {Tone.Clock} this\n\t * @example\n\t * clock.stop();\n\t */\n\tTone.Clock.prototype.stop = function(time){\n\t\ttime = this.toSeconds(time);\n\t\tthis._state.cancel(time);\n\t\tthis._state.setStateAtTime(Tone.State.Stopped, time);\n\t\treturn this;\t\n\t};\n\n\n\t/**\n\t * Pause the clock. Pausing does not reset the tick counter.\n\t * @param {Time} [time=now] The time when the clock should stop.\n\t * @returns {Tone.Clock} this\n\t */\n\tTone.Clock.prototype.pause = function(time){\n\t\ttime = this.toSeconds(time);\n\t\tif (this._state.getValueAtTime(time) === Tone.State.Started){\n\t\t\tthis._state.setStateAtTime(Tone.State.Paused, time);\n\t\t}\n\t\treturn this;\t\n\t};\n\n\t/**\n\t * The scheduling loop.\n\t * @param {Number} time The current page time starting from 0\n\t * when the page was loaded.\n\t * @private\n\t */\n\tTone.Clock.prototype._loop = function(){\n\t\t//get the frequency value to compute the value of the next loop\n\t\tvar now = this.now();\n\t\t//if it's started\n\t\tvar lookAhead = this.context.lookAhead;\n\t\tvar updateInterval = this.context.updateInterval;\n\t\tvar lagCompensation = this.context.lag * 2;\n\t\tvar loopInterval = now + lookAhead + updateInterval + lagCompensation;\n\t\twhile (loopInterval > this._nextTick && this._state){\n\t\t\tvar currentState = this._state.getValueAtTime(this._nextTick);\n\t\t\tif (currentState !== this._lastState){\n\t\t\t\tthis._lastState = currentState;\n\t\t\t\tvar event = this._state.get(this._nextTick);\n\t\t\t\t// emit an event\n\t\t\t\tif (currentState === Tone.State.Started){\n\t\t\t\t\t//correct the time\n\t\t\t\t\tthis._nextTick = event.time;\n\t\t\t\t\tif (!this.isUndef(event.offset)){\n\t\t\t\t\t\tthis.ticks = event.offset;\n\t\t\t\t\t}\n\t\t\t\t\tthis.emit(\"start\", event.time, this.ticks);\n\t\t\t\t} else if (currentState === Tone.State.Stopped){\n\t\t\t\t\tthis.ticks = 0;\n\n\t\t\t\t\tthis.emit(\"stop\", event.time);\n\t\t\t\t} else if (currentState === Tone.State.Paused){\n\t\t\t\t\tthis.emit(\"pause\", event.time);\n\t\t\t\t}\n\t\t\t}\n\t\t\tvar tickTime = this._nextTick;\n\t\t\tif (this.frequency){\n\t\t\t\tthis._nextTick += 1 / this.frequency.getValueAtTime(this._nextTick);\n\t\t\t\tif (currentState === Tone.State.Started){\n\t\t\t\t\tthis.callback(tickTime);\n\t\t\t\t\tthis.ticks++;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t};\n\n\t/**\n\t * Returns the scheduled state at the given time.\n\t * @param {Time} time The time to query.\n\t * @return {String} The name of the state input in setStateAtTime.\n\t * @example\n\t * clock.start(\"+0.1\");\n\t * clock.getStateAtTime(\"+0.1\"); //returns \"started\"\n\t */\n\tTone.Clock.prototype.getStateAtTime = function(time){\n\t\ttime = this.toSeconds(time);\n\t\treturn this._state.getValueAtTime(time);\n\t};\n\n\t/**\n\t * Clean up\n\t * @returns {Tone.Clock} this\n\t */\n\tTone.Clock.prototype.dispose = function(){\n\t\tTone.Emitter.prototype.dispose.call(this);\n\t\tthis.context.off(\"tick\", this._boundLoop);\n\t\tthis._writable(\"frequency\");\n\t\tthis.frequency.dispose();\n\t\tthis.frequency = null;\n\t\tthis._boundLoop = null;\n\t\tthis._nextTick = Infinity;\n\t\tthis.callback = null;\n\t\tthis._state.dispose();\n\t\tthis._state = null;\n\t};\n\n\treturn Tone.Clock;\n});","'use strict';\ndefine(function (require) {\n\n var p5sound = require('master');\n var AudioVoice = require('audioVoice');\n var noteToFreq = require('helpers').noteToFreq;\n\n var DEFAULT_SUSTAIN = 0.15;\n\n /**\n * A MonoSynth is used as a single voice for sound synthesis.\n * This is a class to be used in conjunction with the PolySynth\n * class. Custom synthetisers should be built inheriting from\n * this class.\n *\n * @class p5.MonoSynth\n * @constructor\n * @example\n *
\n * var monoSynth;\n *\n * function setup() {\n * var cnv = createCanvas(100, 100);\n * cnv.mousePressed(playSynth);\n *\n * monoSynth = new p5.MonoSynth();\n *\n * textAlign(CENTER);\n * text('click to play', width/2, height/2);\n * }\n *\n * function playSynth() {\n * // time from now (in seconds)\n * var time = 0;\n * // note duration (in seconds)\n * var dur = 0.25;\n * // velocity (volume, from 0 to 1)\n * var v = 0.2;\n *\n * monoSynth.play(\"G3\", v, time, dur);\n * monoSynth.play(\"C4\", v, time += dur, dur);\n *\n * background(random(255), random(255), 255);\n * text('click to play', width/2, height/2);\n * }\n *
\n **/\n\n p5.MonoSynth = function () {\n AudioVoice.call(this);\n\n this.oscillator = new p5.Oscillator();\n\n this.env = new p5.Envelope();\n this.env.setRange(1, 0);\n this.env.setExp(true);\n\n //set params\n this.setADSR(0.02, 0.25, 0.05, 0.35);\n\n // oscillator --> env --> this.output (gain) --> p5.soundOut\n this.oscillator.disconnect();\n this.oscillator.connect(this.output);\n\n this.env.disconnect();\n this.env.setInput(this.output.gain);\n\n // reset oscillator gain to 1.0\n this.oscillator.output.gain.value = 1.0;\n\n this.oscillator.start();\n this.connect();\n\n p5sound.soundArray.push(this);\n };\n\n p5.MonoSynth.prototype = Object.create(p5.AudioVoice.prototype);\n\n /**\n * Play tells the MonoSynth to start playing a note. This method schedules\n * the calling of .triggerAttack and .triggerRelease.\n *\n * @method play\n * @for p5.MonoSynth\n * @param {String | Number} note the note you want to play, specified as a\n * frequency in Hertz (Number) or as a midi\n * value in Note/Octave format (\"C4\", \"Eb3\"...etc\")\n * See \n * Tone. Defaults to 440 hz.\n * @param {Number} [velocity] velocity of the note to play (ranging from 0 to 1)\n * @param {Number} [secondsFromNow] time from now (in seconds) at which to play\n * @param {Number} [sustainTime] time to sustain before releasing the envelope\n * @example\n *
\n * var monoSynth;\n *\n * function setup() {\n * var cnv = createCanvas(100, 100);\n * cnv.mousePressed(playSynth);\n *\n * monoSynth = new p5.MonoSynth();\n *\n * textAlign(CENTER);\n * text('click to play', width/2, height/2);\n * }\n *\n * function playSynth() {\n * // time from now (in seconds)\n * var time = 0;\n * // note duration (in seconds)\n * var dur = 1/6;\n * // note velocity (volume, from 0 to 1)\n * var v = random();\n *\n * monoSynth.play(\"Fb3\", v, 0, dur);\n * monoSynth.play(\"Gb3\", v, time += dur, dur);\n *\n * background(random(255), random(255), 255);\n * text('click to play', width/2, height/2);\n * }\n *
\n *\n */\n p5.MonoSynth.prototype.play = function (note, velocity, secondsFromNow, susTime) {\n this.triggerAttack(note, velocity, ~~secondsFromNow);\n this.triggerRelease(~~secondsFromNow + (susTime || DEFAULT_SUSTAIN));\n };\n\n /**\n * Trigger the Attack, and Decay portion of the Envelope.\n * Similar to holding down a key on a piano, but it will\n * hold the sustain level until you let go.\n *\n * @param {String | Number} note the note you want to play, specified as a\n * frequency in Hertz (Number) or as a midi\n * value in Note/Octave format (\"C4\", \"Eb3\"...etc\")\n * See \n * Tone. Defaults to 440 hz\n * @param {Number} [velocity] velocity of the note to play (ranging from 0 to 1)\n * @param {Number} [secondsFromNow] time from now (in seconds) at which to play\n * @method triggerAttack\n * @for p5.MonoSynth\n * @example\n *
\n * var monoSynth = new p5.MonoSynth();\n *\n * function mousePressed() {\n * monoSynth.triggerAttack(\"E3\");\n * }\n *\n * function mouseReleased() {\n * monoSynth.triggerRelease();\n * }\n *
\n */\n p5.MonoSynth.prototype.triggerAttack = function (note, velocity, secondsFromNow) {\n var secondsFromNow = ~~secondsFromNow;\n var freq = noteToFreq(note);\n var vel = velocity || 0.1;\n this.oscillator.freq(freq, 0, secondsFromNow);\n this.env.ramp(this.output.gain, secondsFromNow, vel);\n };\n\n /**\n * Trigger the release of the Envelope. This is similar to releasing\n * the key on a piano and letting the sound fade according to the\n * release level and release time.\n *\n * @param {Number} secondsFromNow time to trigger the release\n * @method triggerRelease\n * @for p5.MonoSynth\n * @example\n *
\n * var monoSynth = new p5.MonoSynth();\n *\n * function mousePressed() {\n * monoSynth.triggerAttack(\"E3\");\n * }\n *\n * function mouseReleased() {\n * monoSynth.triggerRelease();\n * }\n *
\n */\n p5.MonoSynth.prototype.triggerRelease = function (secondsFromNow) {\n var secondsFromNow = secondsFromNow || 0;\n this.env.ramp(this.output.gain, secondsFromNow, 0);\n };\n\n /**\n * Set values like a traditional\n * \n * ADSR envelope\n * .\n *\n * @method setADSR\n * @for p5.MonoSynth\n * @param {Number} attackTime Time (in seconds before envelope\n * reaches Attack Level\n * @param {Number} [decayTime] Time (in seconds) before envelope\n * reaches Decay/Sustain Level\n * @param {Number} [susRatio] Ratio between attackLevel and releaseLevel, on a scale from 0 to 1,\n * where 1.0 = attackLevel, 0.0 = releaseLevel.\n * The susRatio determines the decayLevel and the level at which the\n * sustain portion of the envelope will sustain.\n * For example, if attackLevel is 0.4, releaseLevel is 0,\n * and susAmt is 0.5, the decayLevel would be 0.2. If attackLevel is\n * increased to 1.0 (using setRange),\n * then decayLevel would increase proportionally, to become 0.5.\n * @param {Number} [releaseTime] Time in seconds from now (defaults to 0)\n */\n p5.MonoSynth.prototype.setADSR = function (attack,decay,sustain,release) {\n this.env.setADSR(attack, decay, sustain, release);\n };\n\n\n /**\n * Getters and Setters\n * @property {Number} attack\n * @for p5.MonoSynth\n */\n /**\n * @property {Number} decay\n * @for p5.MonoSynth\n */\n /**\n * @property {Number} sustain\n * @for p5.MonoSynth\n */\n /**\n * @property {Number} release\n * @for p5.MonoSynth\n */\n Object.defineProperties(p5.MonoSynth.prototype, {\n 'attack': {\n get : function() {\n return this.env.aTime;\n },\n set : function(attack) {\n this.env.setADSR(attack, this.env.dTime,\n this.env.sPercent, this.env.rTime);\n }\n },\n 'decay': {\n get : function() {\n return this.env.dTime;\n },\n set : function(decay) {\n this.env.setADSR(this.env.aTime, decay,\n this.env.sPercent, this.env.rTime);\n }\n },\n 'sustain': {\n get : function() {\n return this.env.sPercent;\n },\n set : function(sustain) {\n this.env.setADSR(this.env.aTime, this.env.dTime,\n sustain, this.env.rTime);\n }\n },\n 'release': {\n get : function() {\n return this.env.rTime;\n },\n set : function(release) {\n this.env.setADSR(this.env.aTime, this.env.dTime,\n this.env.sPercent, release);\n }\n },\n });\n\n\n /**\n * MonoSynth amp\n * @method amp\n * @for p5.MonoSynth\n * @param {Number} vol desired volume\n * @param {Number} [rampTime] Time to reach new volume\n * @return {Number} new volume value\n */\n p5.MonoSynth.prototype.amp = function(vol, rampTime) {\n var t = rampTime || 0;\n if (typeof vol !== 'undefined') {\n this.oscillator.amp(vol, t);\n }\n return this.oscillator.amp().value;\n };\n\n /**\n * Connect to a p5.sound / Web Audio object.\n *\n * @method connect\n * @for p5.MonoSynth\n * @param {Object} unit A p5.sound or Web Audio object\n */\n\n p5.MonoSynth.prototype.connect = function(unit) {\n var u = unit || p5sound.input;\n this.output.connect(u.input ? u.input : u);\n };\n\n /**\n * Disconnect all outputs\n *\n * @method disconnect\n * @for p5.MonoSynth\n */\n p5.MonoSynth.prototype.disconnect = function() {\n if (this.output) {\n this.output.disconnect();\n }\n };\n\n\n /**\n * Get rid of the MonoSynth and free up its resources / memory.\n *\n * @method dispose\n * @for p5.MonoSynth\n */\n p5.MonoSynth.prototype.dispose = function() {\n AudioVoice.prototype.dispose.apply(this);\n\n if (this.env) {\n this.env.dispose();\n }\n if (this.oscillator) {\n this.oscillator.dispose();\n }\n };\n\n});\n","'use strict';\ndefine(function() {\n var p5sound = require('master');\n\n /**\n * Base class for monophonic synthesizers. Any extensions of this class\n * should follow the API and implement the methods below in order to\n * remain compatible with p5.PolySynth();\n *\n * @class p5.AudioVoice\n * @constructor\n */\n p5.AudioVoice = function () {\n\t this.ac = p5sound.audiocontext;\n\t this.output = this.ac.createGain();\n\t this.connect();\n\t p5sound.soundArray.push(this);\n };\n\n p5.AudioVoice.prototype.play = function (note, velocity, secondsFromNow, sustime) {\n };\n\n p5.AudioVoice.prototype.triggerAttack = function (note, velocity, secondsFromNow) {\n };\n\n p5.AudioVoice.prototype.triggerRelease = function (secondsFromNow) {\n };\n\n p5.AudioVoice.prototype.amp = function(vol, rampTime) {\n };\n\n /**\n * Connect to p5 objects or Web Audio Nodes\n * @method connect\n * @for p5.AudioVoice\n * @param {Object} unit\n */\n p5.AudioVoice.prototype.connect = function(unit) {\n var u = unit || p5sound.input;\n this.output.connect(u.input ? u.input : u);\n };\n\n /**\n * Disconnect from soundOut\n * @method disconnect\n * @for p5.AudioVoice\n */\n p5.AudioVoice.prototype.disconnect = function() {\n this.output.disconnect();\n };\n\n p5.AudioVoice.prototype.dispose = function() {\n if (this.output) {\n this.output.disconnect();\n delete this.output;\n }\n };\n\n return p5.AudioVoice;\n});\n","'use strict';\ndefine(function (require) {\n\n var p5sound = require('master');\n var TimelineSignal = require('Tone/signal/TimelineSignal');\n var noteToFreq = require('helpers').noteToFreq;\n\n /**\n * An AudioVoice is used as a single voice for sound synthesis.\n * The PolySynth class holds an array of AudioVoice, and deals\n * with voices allocations, with setting notes to be played, and\n * parameters to be set.\n *\n * @class p5.PolySynth\n * @constructor\n *\n * @param {Number} [synthVoice] A monophonic synth voice inheriting\n * the AudioVoice class. Defaults to p5.MonoSynth\n * @param {Number} [maxVoices] Number of voices, defaults to 8;\n * @example\n *
\n * var polySynth;\n *\n * function setup() {\n * var cnv = createCanvas(100, 100);\n * cnv.mousePressed(playSynth);\n *\n * polySynth = new p5.PolySynth();\n *\n * textAlign(CENTER);\n * text('click to play', width/2, height/2);\n * }\n *\n * function playSynth() {\n * // note duration (in seconds)\n * var dur = 1.5;\n *\n * // time from now (in seconds)\n * var time = 0;\n *\n * // velocity (volume, from 0 to 1)\n * var vel = 0.1;\n *\n * // notes can overlap with each other\n * polySynth.play(\"G2\", vel, 0, dur);\n * polySynth.play(\"C3\", vel, time += 1/3, dur);\n * polySynth.play(\"G3\", vel, time += 1/3, dur);\n *\n * background(random(255), random(255), 255);\n * text('click to play', width/2, height/2);\n * }\n *
\n **/\n p5.PolySynth = function(audioVoice, maxVoices) {\n //audiovoices will contain maxVoices many monophonic synths\n this.audiovoices = [];\n\n /**\n * An object that holds information about which notes have been played and\n * which notes are currently being played. New notes are added as keys\n * on the fly. While a note has been attacked, but not released, the value of the\n * key is the audiovoice which is generating that note. When notes are released,\n * the value of the key becomes undefined.\n * @property notes\n */\n this.notes = {};\n\n //indices of the most recently used, and least recently used audiovoice\n this._newest = 0;\n this._oldest = 0;\n\n /**\n * A PolySynth must have at least 1 voice, defaults to 8\n * @property polyvalue\n */\n this.maxVoices = maxVoices || 8;\n\n /**\n * Monosynth that generates the sound for each note that is triggered. The\n * p5.PolySynth defaults to using the p5.MonoSynth as its voice.\n * @property AudioVoice\n */\n this.AudioVoice = audioVoice === undefined ? p5.MonoSynth : audioVoice;\n\n /**\n * This value must only change as a note is attacked or released. Due to delay\n * and sustain times, Tone.TimelineSignal is required to schedule the change in value.\n\t * @private\n * @property {Tone.TimelineSignal} _voicesInUse\n */\n this._voicesInUse = new TimelineSignal(0);\n\n this.output = p5sound.audiocontext.createGain();\n this.connect();\n\n //Construct the appropriate number of audiovoices\n this._allocateVoices();\n p5sound.soundArray.push(this);\n };\n\n /**\n * Construct the appropriate number of audiovoices\n * @private\n * @for p5.PolySynth\n * @method _allocateVoices\n */\n p5.PolySynth.prototype._allocateVoices = function() {\n for(var i = 0; i< this.maxVoices; i++) {\n this.audiovoices.push(new this.AudioVoice());\n this.audiovoices[i].disconnect();\n this.audiovoices[i].connect(this.output);\n }\n };\n\n /**\n * Play a note by triggering noteAttack and noteRelease with sustain time\n *\n * @method play\n * @for p5.PolySynth\n * @param {Number} [note] midi note to play (ranging from 0 to 127 - 60 being a middle C)\n * @param {Number} [velocity] velocity of the note to play (ranging from 0 to 1)\n * @param {Number} [secondsFromNow] time from now (in seconds) at which to play\n * @param {Number} [sustainTime] time to sustain before releasing the envelope\n * @example\n *
\n * var polySynth;\n *\n * function setup() {\n * var cnv = createCanvas(100, 100);\n * cnv.mousePressed(playSynth);\n *\n * polySynth = new p5.PolySynth();\n *\n * textAlign(CENTER);\n * text('click to play', width/2, height/2);\n * }\n *\n * function playSynth() {\n * // note duration (in seconds)\n * var dur = 0.1;\n *\n * // time from now (in seconds)\n * var time = 0;\n *\n * // velocity (volume, from 0 to 1)\n * var vel = 0.1;\n *\n * polySynth.play(\"G2\", vel, 0, dur);\n * polySynth.play(\"C3\", vel, 0, dur);\n * polySynth.play(\"G3\", vel, 0, dur);\n *\n * background(random(255), random(255), 255);\n * text('click to play', width/2, height/2);\n * }\n *
\n */\n p5.PolySynth.prototype.play = function (note,velocity, secondsFromNow, susTime) {\n var susTime = susTime || 1;\n this.noteAttack(note, velocity, secondsFromNow);\n this.noteRelease(note, secondsFromNow + susTime);\n };\n\n\n /**\n * noteADSR sets the envelope for a specific note that has just been triggered.\n * Using this method modifies the envelope of whichever audiovoice is being used\n * to play the desired note. The envelope should be reset before noteRelease is called\n * in order to prevent the modified envelope from being used on other notes.\n *\n * @method noteADSR\n * @for p5.PolySynth\n * @param {Number} [note] Midi note on which ADSR should be set.\n * @param {Number} [attackTime] Time (in seconds before envelope\n * reaches Attack Level\n * @param {Number} [decayTime] Time (in seconds) before envelope\n * reaches Decay/Sustain Level\n * @param {Number} [susRatio] Ratio between attackLevel and releaseLevel, on a scale from 0 to 1,\n * where 1.0 = attackLevel, 0.0 = releaseLevel.\n * The susRatio determines the decayLevel and the level at which the\n * sustain portion of the envelope will sustain.\n * For example, if attackLevel is 0.4, releaseLevel is 0,\n * and susAmt is 0.5, the decayLevel would be 0.2. If attackLevel is\n * increased to 1.0 (using setRange),\n * then decayLevel would increase proportionally, to become 0.5.\n * @param {Number} [releaseTime] Time in seconds from now (defaults to 0)\n **/\n\n p5.PolySynth.prototype.noteADSR = function (note,a,d,s,r,timeFromNow) {\n var now = p5sound.audiocontext.currentTime;\n var timeFromNow = timeFromNow || 0;\n var t = now + timeFromNow\n this.audiovoices[ this.notes[note].getValueAtTime(t) ].setADSR(a,d,s,r);\n };\n\n\n /**\n * Set the PolySynths global envelope. This method modifies the envelopes of each\n * monosynth so that all notes are played with this envelope.\n *\n * @method setADSR\n * @for p5.PolySynth\n * @param {Number} [attackTime] Time (in seconds before envelope\n * reaches Attack Level\n * @param {Number} [decayTime] Time (in seconds) before envelope\n * reaches Decay/Sustain Level\n * @param {Number} [susRatio] Ratio between attackLevel and releaseLevel, on a scale from 0 to 1,\n * where 1.0 = attackLevel, 0.0 = releaseLevel.\n * The susRatio determines the decayLevel and the level at which the\n * sustain portion of the envelope will sustain.\n * For example, if attackLevel is 0.4, releaseLevel is 0,\n * and susAmt is 0.5, the decayLevel would be 0.2. If attackLevel is\n * increased to 1.0 (using setRange),\n * then decayLevel would increase proportionally, to become 0.5.\n * @param {Number} [releaseTime] Time in seconds from now (defaults to 0)\n **/\n p5.PolySynth.prototype.setADSR = function(a,d,s,r) {\n this.audiovoices.forEach(function(voice) {\n voice.setADSR(a,d,s,r);\n });\n };\n\n /**\n * Trigger the Attack, and Decay portion of a MonoSynth.\n * Similar to holding down a key on a piano, but it will\n * hold the sustain level until you let go.\n *\n * @method noteAttack\n * @for p5.PolySynth\n * @param {Number} [note] midi note on which attack should be triggered.\n * @param {Number} [velocity] velocity of the note to play (ranging from 0 to 1)/\n * @param {Number} [secondsFromNow] time from now (in seconds)\n * @example\n *
\n * var polySynth = new p5.PolySynth();\n * var pitches = [\"G\", \"D\", \"G\", \"C\"];\n * var octaves = [2, 3, 4];\n *\n * function mousePressed() {\n * // play a chord: multiple notes at the same time\n * for (var i = 0; i < 4; i++) {\n * var note = random(pitches) + random(octaves);\n * polySynth.noteAttack(note, 0.1);\n * }\n * }\n *\n * function mouseReleased() {\n * // release all voices\n * polySynth.noteRelease();\n * }\n *
\n */\n p5.PolySynth.prototype.noteAttack = function (_note, _velocity, secondsFromNow) {\n //this value goes to the audiovoices which handle their own scheduling\n var secondsFromNow = ~~secondsFromNow;\n\n //this value is used by this._voicesInUse\n var acTime = p5sound.audiocontext.currentTime + secondsFromNow;\n\n //Convert note to frequency if necessary. This is because entries into this.notes\n //should be based on frequency for the sake of consistency.\n var note = noteToFreq(_note);\n var velocity = _velocity || 0.1;\n\n var currentVoice;\n\n //Release the note if it is already playing\n if (this.notes[note] && this.notes[note].getValueAtTime(acTime) !== null) {\n this.noteRelease(note, 0);\n }\n\n //Check to see how many voices are in use at the time the note will start\n if (this._voicesInUse.getValueAtTime(acTime) < this.maxVoices) {\n currentVoice = Math.max(~~this._voicesInUse.getValueAtTime(acTime), 0);\n }\n //If we are exceeding the polyvalue, bump off the oldest notes and replace\n //with a new note\n else {\n currentVoice = this._oldest;\n\n var oldestNote = p5.prototype.freqToMidi(this.audiovoices[this._oldest].oscillator.freq().value);\n this.noteRelease(oldestNote);\n this._oldest = ( this._oldest + 1 ) % (this.maxVoices - 1);\n }\n\n //Overrite the entry in the notes object. A note (frequency value)\n //corresponds to the index of the audiovoice that is playing it\n this.notes[note] = new TimelineSignal();\n this.notes[note].setValueAtTime(currentVoice, acTime);\n\n //Find the scheduled change in this._voicesInUse that will be previous to this new note\n //Add 1 and schedule this value at time 't', when this note will start playing\n var previousVal = this._voicesInUse._searchBefore(acTime) === null ? 0 : this._voicesInUse._searchBefore(acTime).value;\n this._voicesInUse.setValueAtTime(previousVal + 1, acTime);\n\n //Then update all scheduled values that follow to increase by 1\n this._updateAfter(acTime, 1);\n\n this._newest = currentVoice;\n //The audiovoice handles the actual scheduling of the note\n if (typeof velocity === 'number') {\n var maxRange = 1 / this._voicesInUse.getValueAtTime(acTime) * 2;\n velocity = velocity > maxRange ? maxRange : velocity;\n }\n this.audiovoices[currentVoice].triggerAttack(note, velocity, secondsFromNow);\n };\n\n /**\n * Private method to ensure accurate values of this._voicesInUse\n * Any time a new value is scheduled, it is necessary to increment all subsequent\n * scheduledValues after attack, and decrement all subsequent\n * scheduledValues after release\n *\n * @private\n * @for p5.PolySynth\n * @param {[type]} time [description]\n * @param {[type]} value [description]\n * @return {[type]} [description]\n */\n p5.PolySynth.prototype._updateAfter = function(time, value) {\n if(this._voicesInUse._searchAfter(time) === null) {\n return;\n } else{\n this._voicesInUse._searchAfter(time).value += value;\n var nextTime = this._voicesInUse._searchAfter(time).time;\n this._updateAfter(nextTime, value);\n }\n };\n\n\n /**\n * Trigger the Release of an AudioVoice note. This is similar to releasing\n * the key on a piano and letting the sound fade according to the\n * release level and release time.\n *\n * @method noteRelease\n * @for p5.PolySynth\n * @param {Number} [note] midi note on which attack should be triggered.\n * If no value is provided, all notes will be released.\n * @param {Number} [secondsFromNow] time to trigger the release\n * @example\n *
\n * var pitches = [\"G\", \"D\", \"G\", \"C\"];\n * var octaves = [2, 3, 4];\n * var polySynth = new p5.PolySynth();\n *\n * function mousePressed() {\n * // play a chord: multiple notes at the same time\n * for (var i = 0; i < 4; i++) {\n * var note = random(pitches) + random(octaves);\n * polySynth.noteAttack(note, 0.1);\n * }\n * }\n *\n * function mouseReleased() {\n * // release all voices\n * polySynth.noteRelease();\n * }\n *
\n *\n */\n p5.PolySynth.prototype.noteRelease = function (_note,secondsFromNow) {\n var now = p5sound.audiocontext.currentTime;\n var tFromNow = secondsFromNow || 0;\n var t = now + tFromNow;\n\n // if a note value is not provided, release all voices\n if (!_note) {\n this.audiovoices.forEach(function(voice) {\n voice.triggerRelease(tFromNow)\n });\n this._voicesInUse.setValueAtTime(0, t);\n for (var n in this.notes) {\n this.notes[n].dispose();\n delete this.notes[n];\n }\n return;\n }\n\n //Make sure note is in frequency inorder to query the this.notes object\n var note = noteToFreq(_note);\n\n if (!this.notes[note] || this.notes[note].getValueAtTime(t) === null) {\n console.warn('Cannot release a note that is not already playing');\n } else {\n //Find the scheduled change in this._voicesInUse that will be previous to this new note\n //subtract 1 and schedule this value at time 't', when this note will stop playing\n var previousVal = Math.max(~~this._voicesInUse.getValueAtTime(t).value, 1);\n this._voicesInUse.setValueAtTime(previousVal - 1, t);\n //Then update all scheduled values that follow to decrease by 1 but never go below 0\n if (previousVal > 0) {\n this._updateAfter(t, -1);\n }\n\n this.audiovoices[ this.notes[note].getValueAtTime(t) ].triggerRelease(tFromNow);\n this.notes[note].dispose();\n delete this.notes[note];\n\n this._newest = this._newest === 0 ? 0 : (this._newest - 1) % (this.maxVoices - 1);\n }\n\n };\n\n /**\n * Connect to a p5.sound / Web Audio object.\n *\n * @method connect\n * @for p5.PolySynth\n * @param {Object} unit A p5.sound or Web Audio object\n */\n p5.PolySynth.prototype.connect = function (unit) {\n var u = unit || p5sound.input;\n this.output.connect(u.input ? u.input : u);\n };\n\n /**\n * Disconnect all outputs\n *\n * @method disconnect\n * @for p5.PolySynth\n */\n p5.PolySynth.prototype.disconnect = function() {\n if (this.output) {\n this.output.disconnect();\n }\n };\n\n /**\n * Get rid of the MonoSynth and free up its resources / memory.\n *\n * @method dispose\n * @for p5.PolySynth\n */\n p5.PolySynth.prototype.dispose = function() {\n this.audiovoices.forEach(function(voice) {\n voice.dispose();\n });\n\n if (this.output) {\n this.output.disconnect();\n delete this.output;\n }\n };\n\n});\n","'use strict';\n\ndefine(function (require) {\n\n require('audioworklet-polyfill');\n require('shims');\n require('audiocontext');\n var p5SOUND = require('master');\n require('helpers');\n require('errorHandler');\n require('audioWorklet');\n require('panner');\n require('soundfile');\n require('amplitude');\n require('fft');\n require('signal');\n require('oscillator');\n require('envelope');\n require('pulse');\n require('noise');\n require('audioin');\n require('filter');\n require('eq');\n require('panner3d');\n require('listener3d');\n require('delay');\n require('reverb');\n require('metro');\n require('looper');\n require('soundLoop');\n require('compressor');\n require('soundRecorder');\n require('peakDetect');\n require('gain');\n require('monosynth');\n require('polysynth');\n require('distortion');\n require('audioVoice');\n require('monosynth');\n require('polysynth');\n\n return p5SOUND;\n\n});\n","!function(){var e,t=[];function r(e){var r=this,n={},i=-1;this.parameters.forEach(function(e,o){var s=t[++i]||(t[i]=new Float32Array(r.bufferSize));s.fill(e.value),n[o]=s}),this.processor.realm.exec(\"self.sampleRate=sampleRate=\"+this.context.sampleRate+\";self.currentTime=currentTime=\"+this.context.currentTime);var s=o(e.inputBuffer),a=o(e.outputBuffer);this.instance.process([s],[a],n)}function o(e){for(var t=[],r=0;r= this.sampleLimit) {\\n this.stop();\\n return true;\\n }\\n\\n var input = inputs[0];\\n var output = outputs[0];\\n\\n for (var channel = 0; channel < output.length; ++channel) {\\n var inputChannel = input[channel];\\n\\n if (channel === 0) {\\n this.leftBuffers.push(inputChannel);\\n\\n if (this.numInputChannels === 1) {\\n this.rightBuffers.push(inputChannel);\\n }\\n } else if (channel === 1 && this.numInputChannels > 1) {\\n this.rightBuffers.push(inputChannel);\\n }\\n }\\n\\n this.recordedSamples += output[0].length;\\n return true;\\n }\\n }, {\\n key: \\\"record\\\",\\n value: function record(duration) {\\n if (duration) {\\n this.sampleLimit = Math.round(duration * sampleRate);\\n }\\n\\n this.recording = true;\\n }\\n }, {\\n key: \\\"stop\\\",\\n value: function stop() {\\n this.recording = false;\\n var buffers = this.getBuffers();\\n var leftBuffer = buffers[0].buffer;\\n var rightBuffer = buffers[1].buffer;\\n this.port.postMessage({\\n name: 'buffers',\\n leftBuffer: leftBuffer,\\n rightBuffer: rightBuffer\\n }, [leftBuffer, rightBuffer]);\\n this.clear();\\n }\\n }, {\\n key: \\\"getBuffers\\\",\\n value: function getBuffers() {\\n var buffers = [];\\n buffers.push(this.mergeBuffers(this.leftBuffers));\\n buffers.push(this.mergeBuffers(this.rightBuffers));\\n return buffers;\\n }\\n }, {\\n key: \\\"mergeBuffers\\\",\\n value: function mergeBuffers(channelBuffer) {\\n var result = new Float32Array(this.recordedSamples);\\n var offset = 0;\\n var lng = channelBuffer.length;\\n\\n for (var i = 0; i < lng; i++) {\\n var buffer = channelBuffer[i];\\n result.set(buffer, offset);\\n offset += buffer.length;\\n }\\n\\n return result;\\n }\\n }, {\\n key: \\\"clear\\\",\\n value: function clear() {\\n this.leftBuffers = [];\\n this.rightBuffers = [];\\n this.recordedSamples = 0;\\n this.sampleLimit = null;\\n }\\n }]);\\n\\n return RecorderProcessor;\\n}(_wrapNativeSuper(AudioWorkletProcessor));\\n\\nregisterProcessor(processorNames.recorderProcessor, RecorderProcessor);\"","export default \"function _typeof(obj) { if (typeof Symbol === \\\"function\\\" && typeof Symbol.iterator === \\\"symbol\\\") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === \\\"function\\\" && obj.constructor === Symbol && obj !== Symbol.prototype ? \\\"symbol\\\" : typeof obj; }; } return _typeof(obj); }\\n\\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\\\"Cannot call a class as a function\\\"); } }\\n\\nfunction _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if (\\\"value\\\" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }\\n\\nfunction _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }\\n\\nfunction _possibleConstructorReturn(self, call) { if (call && (_typeof(call) === \\\"object\\\" || typeof call === \\\"function\\\")) { return call; } return _assertThisInitialized(self); }\\n\\nfunction _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError(\\\"this hasn't been initialised - super() hasn't been called\\\"); } return self; }\\n\\nfunction _inherits(subClass, superClass) { if (typeof superClass !== \\\"function\\\" && superClass !== null) { throw new TypeError(\\\"Super expression must either be null or a function\\\"); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, writable: true, configurable: true } }); if (superClass) _setPrototypeOf(subClass, superClass); }\\n\\nfunction _wrapNativeSuper(Class) { var _cache = typeof Map === \\\"function\\\" ? new Map() : undefined; _wrapNativeSuper = function _wrapNativeSuper(Class) { if (Class === null || !_isNativeFunction(Class)) return Class; if (typeof Class !== \\\"function\\\") { throw new TypeError(\\\"Super expression must either be null or a function\\\"); } if (typeof _cache !== \\\"undefined\\\") { if (_cache.has(Class)) return _cache.get(Class); _cache.set(Class, Wrapper); } function Wrapper() { return _construct(Class, arguments, _getPrototypeOf(this).constructor); } Wrapper.prototype = Object.create(Class.prototype, { constructor: { value: Wrapper, enumerable: false, writable: true, configurable: true } }); return _setPrototypeOf(Wrapper, Class); }; return _wrapNativeSuper(Class); }\\n\\nfunction isNativeReflectConstruct() { if (typeof Reflect === \\\"undefined\\\" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === \\\"function\\\") return true; try { Date.prototype.toString.call(Reflect.construct(Date, [], function () {})); return true; } catch (e) { return false; } }\\n\\nfunction _construct(Parent, args, Class) { if (isNativeReflectConstruct()) { _construct = Reflect.construct; } else { _construct = function _construct(Parent, args, Class) { var a = [null]; a.push.apply(a, args); var Constructor = Function.bind.apply(Parent, a); var instance = new Constructor(); if (Class) _setPrototypeOf(instance, Class.prototype); return instance; }; } return _construct.apply(null, arguments); }\\n\\nfunction _isNativeFunction(fn) { return Function.toString.call(fn).indexOf(\\\"[native code]\\\") !== -1; }\\n\\nfunction _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); }\\n\\nfunction _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); }; return _getPrototypeOf(o); }\\n\\n// import processor name via preval.require so that it's available as a value at compile time\\nvar processorNames = {\\n \\\"recorderProcessor\\\": \\\"recorder-processor\\\",\\n \\\"soundFileProcessor\\\": \\\"sound-file-processor\\\",\\n \\\"amplitudeProcessor\\\": \\\"amplitude-processor\\\"\\n};\\n\\nvar SoundFileProcessor =\\n/*#__PURE__*/\\nfunction (_AudioWorkletProcesso) {\\n _inherits(SoundFileProcessor, _AudioWorkletProcesso);\\n\\n function SoundFileProcessor() {\\n var _this;\\n\\n _classCallCheck(this, SoundFileProcessor);\\n\\n _this = _possibleConstructorReturn(this, _getPrototypeOf(SoundFileProcessor).call(this));\\n _this.paused = false;\\n\\n _this.port.onmessage = function (event) {\\n var data = event.data;\\n\\n if (data.name === 'play') {\\n _this.paused = false;\\n } else if (data.name === 'pause') {\\n _this.paused = true;\\n }\\n };\\n\\n return _this;\\n }\\n\\n _createClass(SoundFileProcessor, [{\\n key: \\\"process\\\",\\n value: function process(inputs) {\\n var input = inputs[0];\\n var inputChannel = input[0];\\n var position = inputChannel[inputChannel.length - 1];\\n\\n if (!this.paused) {\\n this.port.postMessage({\\n name: 'position',\\n position: position\\n });\\n }\\n\\n return true;\\n }\\n }]);\\n\\n return SoundFileProcessor;\\n}(_wrapNativeSuper(AudioWorkletProcessor));\\n\\nregisterProcessor(processorNames.soundFileProcessor, SoundFileProcessor);\"","export default \"function _typeof(obj) { if (typeof Symbol === \\\"function\\\" && typeof Symbol.iterator === \\\"symbol\\\") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === \\\"function\\\" && obj.constructor === Symbol && obj !== Symbol.prototype ? \\\"symbol\\\" : typeof obj; }; } return _typeof(obj); }\\n\\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\\\"Cannot call a class as a function\\\"); } }\\n\\nfunction _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if (\\\"value\\\" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }\\n\\nfunction _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }\\n\\nfunction _possibleConstructorReturn(self, call) { if (call && (_typeof(call) === \\\"object\\\" || typeof call === \\\"function\\\")) { return call; } return _assertThisInitialized(self); }\\n\\nfunction _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError(\\\"this hasn't been initialised - super() hasn't been called\\\"); } return self; }\\n\\nfunction _inherits(subClass, superClass) { if (typeof superClass !== \\\"function\\\" && superClass !== null) { throw new TypeError(\\\"Super expression must either be null or a function\\\"); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, writable: true, configurable: true } }); if (superClass) _setPrototypeOf(subClass, superClass); }\\n\\nfunction _wrapNativeSuper(Class) { var _cache = typeof Map === \\\"function\\\" ? new Map() : undefined; _wrapNativeSuper = function _wrapNativeSuper(Class) { if (Class === null || !_isNativeFunction(Class)) return Class; if (typeof Class !== \\\"function\\\") { throw new TypeError(\\\"Super expression must either be null or a function\\\"); } if (typeof _cache !== \\\"undefined\\\") { if (_cache.has(Class)) return _cache.get(Class); _cache.set(Class, Wrapper); } function Wrapper() { return _construct(Class, arguments, _getPrototypeOf(this).constructor); } Wrapper.prototype = Object.create(Class.prototype, { constructor: { value: Wrapper, enumerable: false, writable: true, configurable: true } }); return _setPrototypeOf(Wrapper, Class); }; return _wrapNativeSuper(Class); }\\n\\nfunction isNativeReflectConstruct() { if (typeof Reflect === \\\"undefined\\\" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === \\\"function\\\") return true; try { Date.prototype.toString.call(Reflect.construct(Date, [], function () {})); return true; } catch (e) { return false; } }\\n\\nfunction _construct(Parent, args, Class) { if (isNativeReflectConstruct()) { _construct = Reflect.construct; } else { _construct = function _construct(Parent, args, Class) { var a = [null]; a.push.apply(a, args); var Constructor = Function.bind.apply(Parent, a); var instance = new Constructor(); if (Class) _setPrototypeOf(instance, Class.prototype); return instance; }; } return _construct.apply(null, arguments); }\\n\\nfunction _isNativeFunction(fn) { return Function.toString.call(fn).indexOf(\\\"[native code]\\\") !== -1; }\\n\\nfunction _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); }\\n\\nfunction _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); }; return _getPrototypeOf(o); }\\n\\n// import processor name via preval.require so that it's available as a value at compile time\\nvar processorNames = {\\n \\\"recorderProcessor\\\": \\\"recorder-processor\\\",\\n \\\"soundFileProcessor\\\": \\\"sound-file-processor\\\",\\n \\\"amplitudeProcessor\\\": \\\"amplitude-processor\\\"\\n};\\n\\nvar AmplitudeProcessor =\\n/*#__PURE__*/\\nfunction (_AudioWorkletProcesso) {\\n _inherits(AmplitudeProcessor, _AudioWorkletProcesso);\\n\\n function AmplitudeProcessor(options) {\\n var _this;\\n\\n _classCallCheck(this, AmplitudeProcessor);\\n\\n _this = _possibleConstructorReturn(this, _getPrototypeOf(AmplitudeProcessor).call(this));\\n var processorOptions = options.processorOptions || {};\\n _this.smoothing = processorOptions.smoothing || 0;\\n _this.normalize = processorOptions.normalize || false;\\n _this.stereoVol = [0, 0];\\n _this.stereoVolNorm = [0, 0];\\n _this.volMax = 0.001;\\n\\n _this.port.onmessage = function (event) {\\n var data = event.data;\\n\\n if (data.name === 'toggleNormalize') {\\n _this.normalize = data.normalize;\\n } else if (data.name === 'smoothing') {\\n _this.smoothing = Math.max(0, Math.min(1, data.smoothing));\\n }\\n };\\n\\n return _this;\\n } // TO DO make this stereo / dependent on # of audio channels\\n\\n\\n _createClass(AmplitudeProcessor, [{\\n key: \\\"process\\\",\\n value: function process(inputs, outputs) {\\n var input = inputs[0];\\n var output = outputs[0];\\n var smoothing = this.smoothing;\\n\\n for (var channel = 0; channel < input.length; ++channel) {\\n var inputBuffer = input[channel];\\n var bufLength = inputBuffer.length;\\n var sum = 0;\\n\\n for (var i = 0; i < bufLength; i++) {\\n var x = inputBuffer[i];\\n\\n if (this.normalize) {\\n sum += Math.max(Math.min(x / this.volMax, 1), -1) * Math.max(Math.min(x / this.volMax, 1), -1);\\n } else {\\n sum += x * x;\\n }\\n } // ... then take the square root of the sum.\\n\\n\\n var rms = Math.sqrt(sum / bufLength);\\n this.stereoVol[channel] = Math.max(rms, this.stereoVol[channel] * smoothing);\\n this.volMax = Math.max(this.stereoVol[channel], this.volMax);\\n } // calculate stero normalized volume and add volume from all channels together\\n\\n\\n var volSum = 0;\\n\\n for (var index = 0; index < this.stereoVol.length; index++) {\\n this.stereoVolNorm[index] = Math.max(Math.min(this.stereoVol[index] / this.volMax, 1), 0);\\n volSum += this.stereoVol[index];\\n } // volume is average of channels\\n\\n\\n var volume = volSum / this.stereoVol.length; // normalized value\\n\\n var volNorm = Math.max(Math.min(volume / this.volMax, 1), 0);\\n this.port.postMessage({\\n name: 'amplitude',\\n volume: volume,\\n volNorm: volNorm,\\n stereoVol: this.stereoVol,\\n stereoVolNorm: this.stereoVolNorm\\n }); // pass input through to output\\n\\n for (var _channel = 0; _channel < output.length; ++_channel) {\\n output[_channel].set(input[_channel]);\\n }\\n\\n return true;\\n }\\n }]);\\n\\n return AmplitudeProcessor;\\n}(_wrapNativeSuper(AudioWorkletProcessor));\\n\\nregisterProcessor(processorNames.amplitudeProcessor, AmplitudeProcessor);\"","'use strict';\n\ndefine(function (require) {\n\n var p5sound = require('master');\n var ac = p5sound.audiocontext;\n\n // Stereo panner\n // if there is a stereo panner node use it\n if(typeof ac.createStereoPanner !== 'undefined') {\n p5.Panner = function (input, output) {\n this.stereoPanner = this.input = ac.createStereoPanner();\n input.connect(this.stereoPanner);\n this.stereoPanner.connect(output);\n };\n\n p5.Panner.prototype.pan = function(val, tFromNow) {\n var time = tFromNow || 0;\n var t = ac.currentTime + time;\n\n this.stereoPanner.pan.linearRampToValueAtTime(val, t);\n };\n\n //not implemented because stereopanner\n //node does not require this and will automatically\n //convert single channel or multichannel to stereo.\n //tested with single and stereo, not with (>2) multichannel\n p5.Panner.prototype.inputChannels = function() {};\n\n p5.Panner.prototype.connect = function(obj) {\n this.stereoPanner.connect(obj);\n };\n\n p5.Panner.prototype.disconnect = function() {\n if (this.stereoPanner) {\n this.stereoPanner.disconnect();\n }\n };\n\n } else {\n // if there is no createStereoPanner object\n // such as in safari 7.1.7 at the time of writing this\n // use this method to create the effect\n p5.Panner = function(input, output, numInputChannels) {\n this.input = ac.createGain();\n input.connect(this.input);\n\n this.left = ac.createGain();\n this.right = ac.createGain();\n this.left.channelInterpretation = 'discrete';\n this.right.channelInterpretation = 'discrete';\n\n // if input is stereo\n if (numInputChannels > 1) {\n this.splitter = ac.createChannelSplitter(2);\n this.input.connect(this.splitter);\n\n this.splitter.connect(this.left, 1);\n this.splitter.connect(this.right, 0);\n }\n else {\n this.input.connect(this.left);\n this.input.connect(this.right);\n }\n\n this.output = ac.createChannelMerger(2);\n this.left.connect(this.output, 0, 1);\n this.right.connect(this.output, 0, 0);\n this.output.connect(output);\n };\n\n // -1 is left, +1 is right\n p5.Panner.prototype.pan = function(val, tFromNow) {\n var time = tFromNow || 0;\n var t = ac.currentTime + time;\n var v = (val + 1) / 2;\n var rightVal = Math.cos(v*Math.PI/2);\n var leftVal = Math.sin(v * Math.PI/2);\n this.left.gain.linearRampToValueAtTime(leftVal, t);\n this.right.gain.linearRampToValueAtTime(rightVal, t);\n };\n\n p5.Panner.prototype.inputChannels = function(numChannels) {\n if (numChannels === 1) {\n this.input.disconnect();\n this.input.connect(this.left);\n this.input.connect(this.right);\n } else if (numChannels === 2) {\n if (typeof(this.splitter === 'undefined')) {\n this.splitter = ac.createChannelSplitter(2);\n }\n this.input.disconnect();\n this.input.connect(this.splitter);\n this.splitter.connect(this.left, 1);\n this.splitter.connect(this.right, 0);\n }\n };\n\n p5.Panner.prototype.connect = function(obj) {\n this.output.connect(obj);\n };\n\n p5.Panner.prototype.disconnect = function() {\n if (this.output) {\n this.output.disconnect();\n }\n };\n }\n});\n","'use strict';\n\ndefine(function (require) {\n\n var CustomError = require('errorHandler');\n var p5sound = require('master');\n var ac = p5sound.audiocontext;\n var midiToFreq = require('helpers').midiToFreq;\n var convertToWav = require('helpers').convertToWav;\n var processorNames = require('./audioWorklet/processorNames');\n\n /**\n *
SoundFile object with a path to a file.
\n *\n *
The p5.SoundFile may not be available immediately because\n * it loads the file information asynchronously.
\n *\n *
To do something with the sound as soon as it loads\n * pass the name of a function as the second parameter.
\n *\n *
Only one file path is required. However, audio file formats\n * (i.e. mp3, ogg, wav and m4a/aac) are not supported by all\n * web browsers. If you want to ensure compatability, instead of a single\n * file path, you may include an Array of filepaths, and the browser will\n * choose a format that works.
\n *\n * @class p5.SoundFile\n * @constructor\n * @param {String|Array} path path to a sound file (String). Optionally,\n * you may include multiple file formats in\n * an array. Alternately, accepts an object\n * from the HTML5 File API, or a p5.File.\n * @param {Function} [successCallback] Name of a function to call once file loads\n * @param {Function} [errorCallback] Name of a function to call if file fails to\n * load. This function will receive an error or\n * XMLHttpRequest object with information\n * about what went wrong.\n * @param {Function} [whileLoadingCallback] Name of a function to call while file\n * is loading. That function will\n * receive progress of the request to\n * load the sound file\n * (between 0 and 1) as its first\n * parameter. This progress\n * does not account for the additional\n * time needed to decode the audio data.\n *\n * @example\n *
\n */\n p5.SoundFile = function(paths, onload, onerror, whileLoading) {\n if (typeof paths !== 'undefined') {\n if (typeof paths === 'string' || typeof paths[0] === 'string') {\n var path = p5.prototype._checkFileFormats(paths);\n this.url = path;\n }\n else if(typeof paths === 'object') {\n if (!(window.File && window.FileReader && window.FileList && window.Blob)) {\n // The File API isn't supported in this browser\n throw 'Unable to load file because the File API is not supported';\n }\n }\n\n // if type is a p5.File...get the actual file\n if (paths.file) {\n paths = paths.file;\n }\n\n this.file = paths;\n }\n\n // private _onended callback, set by the method: onended(callback)\n this._onended = function() {};\n\n this._looping = false;\n this._playing = false;\n this._paused = false;\n this._pauseTime = 0;\n\n // cues for scheduling events with addCue() removeCue()\n this._cues = [];\n this._cueIDCounter = 0;\n\n // position of the most recently played sample\n this._lastPos = 0;\n this._counterNode = null;\n this._workletNode = null;\n\n // array of sources so that they can all be stopped!\n this.bufferSourceNodes = [];\n\n // current source\n this.bufferSourceNode = null;\n\n this.buffer = null;\n this.playbackRate = 1;\n\n this.input = p5sound.audiocontext.createGain();\n this.output = p5sound.audiocontext.createGain();\n\n this.reversed = false;\n\n // start and end of playback / loop\n this.startTime = 0;\n this.endTime = null;\n this.pauseTime = 0;\n\n // \"restart\" would stop playback before retriggering\n this.mode = 'sustain';\n\n // time that playback was started, in millis\n this.startMillis = null;\n\n // stereo panning\n this.panPosition = 0.0;\n this.panner = new p5.Panner(this.output, p5sound.input, 2);\n\n // it is possible to instantiate a soundfile with no path\n if (this.url || this.file) {\n this.load(onload, onerror);\n }\n\n // add this p5.SoundFile to the soundArray\n p5sound.soundArray.push(this);\n\n if (typeof whileLoading === 'function') {\n this._whileLoading = whileLoading;\n } else {\n this._whileLoading = function() {};\n }\n\n this._clearOnEnd = _clearOnEnd.bind(this);\n };\n\n // register preload handling of loadSound\n p5.prototype.registerPreloadMethod('loadSound', p5.prototype);\n\n /**\n * loadSound() returns a new p5.SoundFile from a specified\n * path. If called during preload(), the p5.SoundFile will be ready\n * to play in time for setup() and draw(). If called outside of\n * preload, the p5.SoundFile will not be ready immediately, so\n * loadSound accepts a callback as the second parameter. Using a\n * \n * local server is recommended when loading external files.\n *\n * @method loadSound\n * @for p5\n * @param {String|Array} path Path to the sound file, or an array with\n * paths to soundfiles in multiple formats\n * i.e. ['sound.ogg', 'sound.mp3'].\n * Alternately, accepts an object: either\n * from the HTML5 File API, or a p5.File.\n * @param {Function} [successCallback] Name of a function to call once file loads\n * @param {Function} [errorCallback] Name of a function to call if there is\n * an error loading the file.\n * @param {Function} [whileLoading] Name of a function to call while file is loading.\n * This function will receive the percentage loaded\n * so far, from 0.0 to 1.0.\n * @return {SoundFile} Returns a p5.SoundFile\n * @example\n *
\n */\n p5.prototype.loadSound = function(path, callback, onerror, whileLoading) {\n // if loading locally without a server\n if (window.location.origin.indexOf('file://') > -1 && window.cordova === 'undefined' ) {\n window.alert('This sketch may require a server to load external files. Please see http://bit.ly/1qcInwS');\n }\n\n var self = this;\n var s = new p5.SoundFile(path, function() {\n if(typeof callback === 'function') {\n callback.apply(self, arguments);\n }\n\n if (typeof self._decrementPreload === 'function') {\n self._decrementPreload();\n }\n }, onerror, whileLoading);\n\n return s;\n };\n\n /**\n * This is a helper function that the p5.SoundFile calls to load\n * itself. Accepts a callback (the name of another function)\n * as an optional parameter.\n *\n * @private\n * @for p5.SoundFile\n * @param {Function} [successCallback] Name of a function to call once file loads\n * @param {Function} [errorCallback] Name of a function to call if there is an error\n */\n p5.SoundFile.prototype.load = function(callback, errorCallback) {\n var self = this;\n var errorTrace = new Error().stack;\n\n if (this.url !== undefined && this.url !== '') {\n var request = new XMLHttpRequest();\n request.addEventListener('progress', function(evt) {\n self._updateProgress(evt);\n }, false);\n request.open('GET', this.url, true);\n request.responseType = 'arraybuffer';\n\n request.onload = function() {\n if (request.status === 200) {\n // on sucess loading file:\n if (!self.panner) return;\n ac.decodeAudioData(request.response,\n // success decoding buffer:\n function(buff) {\n if (!self.panner) return;\n self.buffer = buff;\n self.panner.inputChannels(buff.numberOfChannels);\n if (callback) {\n callback(self);\n }\n },\n // error decoding buffer. \"e\" is undefined in Chrome 11/22/2015\n function() {\n if (!self.panner) return;\n var err = new CustomError('decodeAudioData', errorTrace, self.url);\n var msg = 'AudioContext error at decodeAudioData for ' + self.url;\n if (errorCallback) {\n err.msg = msg;\n errorCallback(err);\n } else {\n console.error(msg +'\\n The error stack trace includes: \\n' + err.stack);\n }\n }\n );\n }\n // if request status != 200, it failed\n else {\n if (!self.panner) return;\n var err = new CustomError('loadSound', errorTrace, self.url);\n var msg = 'Unable to load ' + self.url + '. The request status was: ' +\n request.status + ' (' + request.statusText + ')';\n\n if (errorCallback) {\n err.message = msg;\n errorCallback(err);\n } else {\n console.error(msg +'\\n The error stack trace includes: \\n' + err.stack);\n }\n }\n };\n\n // if there is another error, aside from 404...\n request.onerror = function() {\n var err = new CustomError('loadSound', errorTrace, self.url);\n var msg = 'There was no response from the server at ' + self.url + '. Check the url and internet connectivity.';\n\n if (errorCallback) {\n err.message = msg;\n errorCallback(err);\n } else {\n console.error(msg +'\\n The error stack trace includes: \\n' + err.stack);\n }\n };\n\n request.send();\n }\n else if (this.file !== undefined) {\n var reader = new FileReader();\n reader.onload = function() {\n if (!self.panner) return;\n ac.decodeAudioData(reader.result, function(buff) {\n if (!self.panner) return;\n self.buffer = buff;\n self.panner.inputChannels(buff.numberOfChannels);\n if (callback) {\n callback(self);\n }\n });\n };\n reader.onerror = function(e) {\n if (!self.panner) return;\n if (onerror) {\n onerror(e);\n }\n };\n reader.readAsArrayBuffer(this.file);\n }\n };\n\n // TO DO: use this method to create a loading bar that shows progress during file upload/decode.\n p5.SoundFile.prototype._updateProgress = function(evt) {\n if (evt.lengthComputable) {\n var percentComplete = evt.loaded / evt.total * 0.99;\n this._whileLoading(percentComplete, evt);\n // ...\n } else {\n // Unable to compute progress information since the total size is unknown\n this._whileLoading('size unknown');\n }\n };\n\n /**\n * Returns true if the sound file finished loading successfully.\n *\n * @method isLoaded\n * @for p5.SoundFile\n * @return {Boolean}\n */\n p5.SoundFile.prototype.isLoaded = function() {\n if (this.buffer) {\n return true;\n } else {\n return false;\n }\n };\n\n /**\n * Play the p5.SoundFile\n *\n * @method play\n * @for p5.SoundFile\n * @param {Number} [startTime] (optional) schedule playback to start (in seconds from now).\n * @param {Number} [rate] (optional) playback rate\n * @param {Number} [amp] (optional) amplitude (volume)\n * of playback\n * @param {Number} [cueStart] (optional) cue start time in seconds\n * @param {Number} [duration] (optional) duration of playback in seconds\n */\n p5.SoundFile.prototype.play = function(startTime, rate, amp, _cueStart, duration) {\n if (!this.output) {\n console.warn('SoundFile.play() called after dispose');\n return;\n }\n\n var now = p5sound.audiocontext.currentTime;\n var cueStart, cueEnd;\n var time = startTime || 0;\n if (time < 0) {\n time = 0;\n }\n\n time = time + now;\n\n if (typeof rate !== 'undefined') {\n this.rate(rate);\n }\n\n if (typeof amp !== 'undefined') {\n this.setVolume(amp);\n }\n\n // TO DO: if already playing, create array of buffers for easy stop()\n if (this.buffer) {\n\n // reset the pause time (if it was paused)\n this._pauseTime = 0;\n\n // handle restart playmode\n if (this.mode === 'restart' && this.buffer && this.bufferSourceNode) {\n this.bufferSourceNode.stop(time);\n this._counterNode.stop(time);\n }\n\n //dont create another instance if already playing\n if (this.mode === 'untildone' && this.isPlaying()) {\n return;\n }\n // make a new source and counter. They are automatically assigned playbackRate and buffer\n this.bufferSourceNode = this._initSourceNode();\n\n // garbage collect counterNode and create a new one\n delete this._counterNode;\n this._counterNode = this._initCounterNode();\n\n if (_cueStart) {\n if (_cueStart >=0 && _cueStart < this.buffer.duration) {\n // this.startTime = cueStart;\n cueStart = _cueStart;\n } else { throw 'start time out of range'; }\n } else {\n cueStart = 0;\n }\n\n if (duration) {\n // if duration is greater than buffer.duration, just play entire file anyway rather than throw an error\n duration = duration <= this.buffer.duration - cueStart ? duration : this.buffer.duration;\n }\n\n // if it was paused, play at the pause position\n if (this._paused) {\n this.bufferSourceNode.start(time, this.pauseTime, duration);\n this._counterNode.start(time, this.pauseTime, duration);\n } else {\n this.bufferSourceNode.start(time, cueStart, duration);\n this._counterNode.start(time, cueStart, duration);\n }\n\n this._playing = true;\n this._paused = false;\n\n // add source to sources array, which is used in stopAll()\n this.bufferSourceNodes.push(this.bufferSourceNode);\n this.bufferSourceNode._arrayIndex = this.bufferSourceNodes.length - 1;\n\n this.bufferSourceNode.addEventListener('ended', this._clearOnEnd);\n }\n // If soundFile hasn't loaded the buffer yet, throw an error\n else {\n throw 'not ready to play file, buffer has yet to load. Try preload()';\n }\n\n // if looping, will restart at original time\n this.bufferSourceNode.loop = this._looping;\n this._counterNode.loop = this._looping;\n\n if (this._looping === true) {\n cueEnd = duration ? duration : cueStart - 0.000000000000001;\n this.bufferSourceNode.loopStart = cueStart;\n this.bufferSourceNode.loopEnd = cueEnd;\n this._counterNode.loopStart = cueStart;\n this._counterNode.loopEnd = cueEnd;\n }\n\n this._workletNode.port.postMessage({ name: 'play' });\n };\n\n\n /**\n * p5.SoundFile has two play modes: restart and\n * sustain. Play Mode determines what happens to a\n * p5.SoundFile if it is triggered while in the middle of playback.\n * In sustain mode, playback will continue simultaneous to the\n * new playback. In restart mode, play() will stop playback\n * and start over. With untilDone, a sound will play only if it's\n * not already playing. Sustain is the default mode.\n *\n * @method playMode\n * @for p5.SoundFile\n * @param {String} str 'restart' or 'sustain' or 'untilDone'\n * @example\n *
\n * var mySound;\n * function preload(){\n * mySound = loadSound('assets/Damscray_DancingTiger.mp3');\n * }\n * function mouseClicked() {\n * mySound.playMode('sustain');\n * mySound.play();\n * }\n * function keyPressed() {\n * mySound.playMode('restart');\n * mySound.play();\n * }\n *\n *
\n */\n p5.SoundFile.prototype.playMode = function(str) {\n var s = str.toLowerCase();\n\n // if restart, stop all other sounds from playing\n if (s === 'restart' && this.buffer && this.bufferSourceNode) {\n for (var i = 0; i < this.bufferSourceNodes.length - 1; i++) {\n var now = p5sound.audiocontext.currentTime;\n this.bufferSourceNodes[i].stop(now);\n }\n }\n\n // set play mode to effect future playback\n if (s === 'restart' || s === 'sustain' || s === 'untildone') {\n this.mode = s;\n } else {\n throw 'Invalid play mode. Must be either \"restart\" or \"sustain\"';\n }\n };\n\n /**\n * Pauses a file that is currently playing. If the file is not\n * playing, then nothing will happen.\n *\n * After pausing, .play() will resume from the paused\n * position.\n * If p5.SoundFile had been set to loop before it was paused,\n * it will continue to loop after it is unpaused with .play().\n *\n * @method pause\n * @for p5.SoundFile\n * @param {Number} [startTime] (optional) schedule event to occur\n * seconds from now\n * @example\n *
\n */\n p5.SoundFile.prototype.pause = function(startTime) {\n var now = p5sound.audiocontext.currentTime;\n var time = startTime || 0;\n var pTime = time + now;\n\n if (this.isPlaying() && this.buffer && this.bufferSourceNode) {\n this._workletNode.port.postMessage({ name: 'pause' });\n\n this.pauseTime = this.currentTime();\n this.bufferSourceNode.stop(pTime);\n this._counterNode.stop(pTime);\n this._paused = true;\n this._playing = false;\n\n this._pauseTime = this.currentTime();\n // TO DO: make sure play() still starts from orig start position\n } else {\n this._pauseTime = 0;\n }\n };\n\n /**\n * Loop the p5.SoundFile. Accepts optional parameters to set the\n * playback rate, playback volume, loopStart, loopEnd.\n *\n * @method loop\n * @for p5.SoundFile\n * @param {Number} [startTime] (optional) schedule event to occur\n * seconds from now\n * @param {Number} [rate] (optional) playback rate\n * @param {Number} [amp] (optional) playback volume\n * @param {Number} [cueLoopStart] (optional) startTime in seconds\n * @param {Number} [duration] (optional) loop duration in seconds\n */\n p5.SoundFile.prototype.loop = function(startTime, rate, amp, loopStart, duration) {\n this._looping = true;\n this.play(startTime, rate, amp, loopStart, duration);\n };\n\n /**\n * Set a p5.SoundFile's looping flag to true or false. If the sound\n * is currently playing, this change will take effect when it\n * reaches the end of the current playback.\n *\n * @method setLoop\n * @for p5.SoundFile\n * @param {Boolean} Boolean set looping to true or false\n */\n p5.SoundFile.prototype.setLoop = function(bool) {\n if (bool === true) {\n this._looping = true;\n }\n else if (bool === false) {\n this._looping = false;\n }\n else {\n throw 'Error: setLoop accepts either true or false';\n }\n if (this.bufferSourceNode) {\n this.bufferSourceNode.loop = this._looping;\n this._counterNode.loop = this._looping;\n }\n };\n\n /**\n * Returns 'true' if a p5.SoundFile is currently looping and playing, 'false' if not.\n *\n * @method isLooping\n * @for p5.SoundFile\n * @return {Boolean}\n */\n p5.SoundFile.prototype.isLooping = function() {\n if (!this.bufferSourceNode) {\n return false;\n }\n if (this._looping === true && this.isPlaying() === true) {\n return true;\n }\n return false;\n };\n\n /**\n * Returns true if a p5.SoundFile is playing, false if not (i.e.\n * paused or stopped).\n *\n * @method isPlaying\n * @for p5.SoundFile\n * @return {Boolean}\n */\n p5.SoundFile.prototype.isPlaying = function() {\n return this._playing;\n };\n\n /**\n * Returns true if a p5.SoundFile is paused, false if not (i.e.\n * playing or stopped).\n *\n * @method isPaused\n * @for p5.SoundFile\n * @return {Boolean}\n */\n p5.SoundFile.prototype.isPaused = function() {\n return this._paused;\n };\n\n /**\n * Stop soundfile playback.\n *\n * @method stop\n * @for p5.SoundFile\n * @param {Number} [startTime] (optional) schedule event to occur\n * in seconds from now\n */\n p5.SoundFile.prototype.stop = function(timeFromNow) {\n var time = timeFromNow || 0;\n\n if (this.mode === 'sustain' || this.mode === 'untildone') {\n this.stopAll(time);\n this._playing = false;\n this.pauseTime = 0;\n this._paused = false;\n }\n else if (this.buffer && this.bufferSourceNode) {\n var now = p5sound.audiocontext.currentTime;\n var t = time || 0;\n this.pauseTime = 0;\n this.bufferSourceNode.stop(now + t);\n this._counterNode.stop(now + t);\n this._playing = false;\n this._paused = false;\n }\n };\n\n /**\n * Stop playback on all of this soundfile's sources.\n * @private\n */\n p5.SoundFile.prototype.stopAll = function(_time) {\n var now = p5sound.audiocontext.currentTime;\n var time = _time || 0;\n if (this.buffer && this.bufferSourceNode) {\n for (var i in this.bufferSourceNodes) {\n const bufferSourceNode = this.bufferSourceNodes[i];\n if (!!bufferSourceNode) {\n try {\n bufferSourceNode.stop(now + time);\n } catch(e) {\n // this was throwing errors only on Safari\n }\n }\n }\n this._counterNode.stop(now + time);\n this._onended(this);\n }\n };\n\n /**\n * Multiply the output volume (amplitude) of a sound file\n * between 0.0 (silence) and 1.0 (full volume).\n * 1.0 is the maximum amplitude of a digital sound, so multiplying\n * by greater than 1.0 may cause digital distortion. To\n * fade, provide a rampTime parameter. For more\n * complex fades, see the Envelope class.\n *\n * Alternately, you can pass in a signal source such as an\n * oscillator to modulate the amplitude with an audio signal.\n *\n * @method setVolume\n * @for p5.SoundFile\n * @param {Number|Object} volume Volume (amplitude) between 0.0\n * and 1.0 or modulating signal/oscillator\n * @param {Number} [rampTime] Fade for t seconds\n * @param {Number} [timeFromNow] Schedule this event to happen at\n * t seconds in the future\n */\n p5.SoundFile.prototype.setVolume = function(vol, _rampTime, _tFromNow) {\n if (typeof vol === 'number') {\n var rampTime = _rampTime || 0;\n var tFromNow = _tFromNow || 0;\n var now = p5sound.audiocontext.currentTime;\n var currentVol = this.output.gain.value;\n this.output.gain.cancelScheduledValues(now + tFromNow);\n this.output.gain.linearRampToValueAtTime(currentVol, now + tFromNow);\n this.output.gain.linearRampToValueAtTime(vol, now + tFromNow + rampTime);\n }\n else if (vol) {\n vol.connect(this.output.gain);\n } else {\n // return the Gain Node\n return this.output.gain;\n }\n };\n\n // same as setVolume, to match Processing Sound\n p5.SoundFile.prototype.amp = p5.SoundFile.prototype.setVolume;\n\n // these are the same thing\n p5.SoundFile.prototype.fade = p5.SoundFile.prototype.setVolume;\n\n p5.SoundFile.prototype.getVolume = function() {\n return this.output.gain.value;\n };\n\n /**\n * Set the stereo panning of a p5.sound object to\n * a floating point number between -1.0 (left) and 1.0 (right).\n * Default is 0.0 (center).\n *\n * @method pan\n * @for p5.SoundFile\n * @param {Number} [panValue] Set the stereo panner\n * @param {Number} [timeFromNow] schedule this event to happen\n * seconds from now\n * @example\n *
\n *\n * var ball = {};\n * var soundFile;\n *\n * function preload() {\n * soundFormats('ogg', 'mp3');\n * soundFile = loadSound('assets/beatbox.mp3');\n * }\n *\n * function draw() {\n * background(0);\n * ball.x = constrain(mouseX, 0, width);\n * ellipse(ball.x, height/2, 20, 20)\n * }\n *\n * function mousePressed(){\n * // map the ball's x location to a panning degree\n * // between -1.0 (left) and 1.0 (right)\n * var panning = map(ball.x, 0., width,-1.0, 1.0);\n * soundFile.pan(panning);\n * soundFile.play();\n * }\n *
\n */\n p5.SoundFile.prototype.pan = function(pval, tFromNow) {\n this.panPosition = pval;\n this.panner.pan(pval, tFromNow);\n };\n\n /**\n * Returns the current stereo pan position (-1.0 to 1.0)\n *\n * @method getPan\n * @for p5.SoundFile\n * @return {Number} Returns the stereo pan setting of the Oscillator\n * as a number between -1.0 (left) and 1.0 (right).\n * 0.0 is center and default.\n */\n p5.SoundFile.prototype.getPan = function() {\n return this.panPosition;\n };\n\n /**\n * Set the playback rate of a sound file. Will change the speed and the pitch.\n * Values less than zero will reverse the audio buffer.\n *\n * @method rate\n * @for p5.SoundFile\n * @param {Number} [playbackRate] Set the playback rate. 1.0 is normal,\n * .5 is half-speed, 2.0 is twice as fast.\n * Values less than zero play backwards.\n * @example\n *
\n * var song;\n *\n * function preload() {\n * song = loadSound('assets/Damscray_DancingTiger.mp3');\n * }\n *\n * function setup() {\n * song.loop();\n * }\n *\n * function draw() {\n * background(200);\n *\n * // Set the rate to a range between 0.1 and 4\n * // Changing the rate also alters the pitch\n * var speed = map(mouseY, 0.1, height, 0, 2);\n * speed = constrain(speed, 0.01, 4);\n * song.rate(speed);\n *\n * // Draw a circle to show what is going on\n * stroke(0);\n * fill(51, 100);\n * ellipse(mouseX, 100, 48, 48);\n * }\n *\n * \n *
\n *\n */\n p5.SoundFile.prototype.rate = function(playbackRate) {\n var reverse = false;\n if (typeof playbackRate === 'undefined') {\n return this.playbackRate;\n }\n\n this.playbackRate = playbackRate;\n\n if (playbackRate === 0) {\n playbackRate = 0.0000000000001;\n }\n\n else if (playbackRate < 0 && !this.reversed) {\n playbackRate = Math.abs(playbackRate);\n reverse = true;\n }\n\n else if (playbackRate > 0 && this.reversed) {\n reverse = true;\n }\n\n if (this.bufferSourceNode) {\n var now = p5sound.audiocontext.currentTime;\n this.bufferSourceNode.playbackRate.cancelScheduledValues(now);\n this.bufferSourceNode.playbackRate.linearRampToValueAtTime(Math.abs(playbackRate), now);\n this._counterNode.playbackRate.cancelScheduledValues(now);\n this._counterNode.playbackRate.linearRampToValueAtTime(Math.abs(playbackRate), now);\n }\n\n if (reverse) {\n this.reverseBuffer();\n }\n return this.playbackRate;\n };\n\n // TO DO: document this\n p5.SoundFile.prototype.setPitch = function(num) {\n var newPlaybackRate = midiToFreq(num) / midiToFreq(60);\n this.rate(newPlaybackRate);\n };\n\n p5.SoundFile.prototype.getPlaybackRate = function() {\n return this.playbackRate;\n };\n\n /**\n * Returns the duration of a sound file in seconds.\n *\n * @method duration\n * @for p5.SoundFile\n * @return {Number} The duration of the soundFile in seconds.\n */\n p5.SoundFile.prototype.duration = function() {\n // Return Duration\n if (this.buffer) {\n return this.buffer.duration;\n } else {\n return 0;\n }\n };\n\n /**\n * Return the current position of the p5.SoundFile playhead, in seconds.\n * Time is relative to the normal buffer direction, so if `reverseBuffer`\n * has been called, currentTime will count backwards.\n *\n * @method currentTime\n * @for p5.SoundFile\n * @return {Number} currentTime of the soundFile in seconds.\n */\n p5.SoundFile.prototype.currentTime = function() {\n return this.reversed\n ? Math.abs(this._lastPos - this.buffer.length) / ac.sampleRate\n : this._lastPos / ac.sampleRate;\n };\n\n /**\n * Move the playhead of the song to a position, in seconds. Start timing\n * and playback duration. If none are given, will reset the file to play\n * entire duration from start to finish.\n *\n * @method jump\n * @for p5.SoundFile\n * @param {Number} cueTime cueTime of the soundFile in seconds.\n * @param {Number} duration duration in seconds.\n */\n p5.SoundFile.prototype.jump = function(cueTime, duration) {\n if (cueTime < 0 || cueTime > this.buffer.duration) {\n throw 'jump time out of range';\n }\n if (duration > this.buffer.duration - cueTime) {\n throw 'end time out of range';\n }\n\n var cTime = cueTime || 0;\n var dur = duration || undefined;\n if (this.isPlaying()) {\n this.stop(0);\n }\n this.play(0, this.playbackRate, this.output.gain.value, cTime, dur);\n };\n\n /**\n * Return the number of channels in a sound file.\n * For example, Mono = 1, Stereo = 2.\n *\n * @method channels\n * @for p5.SoundFile\n * @return {Number} [channels]\n */\n p5.SoundFile.prototype.channels = function() {\n return this.buffer.numberOfChannels;\n };\n\n /**\n * Return the sample rate of the sound file.\n *\n * @method sampleRate\n * @for p5.SoundFile\n * @return {Number} [sampleRate]\n */\n p5.SoundFile.prototype.sampleRate = function() {\n return this.buffer.sampleRate;\n };\n\n /**\n * Return the number of samples in a sound file.\n * Equal to sampleRate * duration.\n *\n * @method frames\n * @for p5.SoundFile\n * @return {Number} [sampleCount]\n */\n p5.SoundFile.prototype.frames = function() {\n return this.buffer.length;\n };\n\n /**\n * Returns an array of amplitude peaks in a p5.SoundFile that can be\n * used to draw a static waveform. Scans through the p5.SoundFile's\n * audio buffer to find the greatest amplitudes. Accepts one\n * parameter, 'length', which determines size of the array.\n * Larger arrays result in more precise waveform visualizations.\n *\n * Inspired by Wavesurfer.js.\n *\n * @method getPeaks\n * @for p5.SoundFile\n * @params {Number} [length] length is the size of the returned array.\n * Larger length results in more precision.\n * Defaults to 5*width of the browser window.\n * @returns {Float32Array} Array of peaks.\n */\n p5.SoundFile.prototype.getPeaks = function(length) {\n\n if (this.buffer) {\n // set length to window's width if no length is provided\n if (!length) {\n length = window.width*5;\n }\n if (this.buffer) {\n var buffer = this.buffer;\n var sampleSize = buffer.length / length;\n var sampleStep = ~~(sampleSize / 10) || 1;\n var channels = buffer.numberOfChannels;\n var peaks = new Float32Array(Math.round(length));\n\n for (var c = 0; c < channels; c++) {\n var chan = buffer.getChannelData(c);\n for (var i = 0; i < length; i++) {\n var start = ~~(i*sampleSize);\n var end = ~~(start + sampleSize);\n var max = 0;\n for (var j = start; j < end; j+= sampleStep) {\n var value = chan[j];\n if (value > max) {\n max = value;\n // faster than Math.abs\n } else if (-value > max) {\n max = value;\n }\n }\n if (c === 0 || Math.abs(max) > peaks[i]) {\n peaks[i] = max;\n }\n }\n }\n\n return peaks;\n }\n }\n\n else {\n throw 'Cannot load peaks yet, buffer is not loaded';\n }\n };\n\n /**\n * Reverses the p5.SoundFile's buffer source.\n * Playback must be handled separately (see example).\n *\n * @method reverseBuffer\n * @for p5.SoundFile\n * @example\n *
\n * var drum;\n *\n * function preload() {\n * drum = loadSound('assets/drum.mp3');\n * }\n *\n * function setup() {\n * drum.reverseBuffer();\n * drum.play();\n * }\n *\n * \n *
\n */\n p5.SoundFile.prototype.reverseBuffer = function() {\n if (this.buffer) {\n var currentPos = this._lastPos / ac.sampleRate;\n var curVol = this.getVolume();\n this.setVolume(0, 0.001);\n\n const numChannels = this.buffer.numberOfChannels;\n for (var i = 0; i < numChannels; i++) {\n this.buffer.getChannelData(i).reverse();\n }\n // set reversed flag\n this.reversed = !this.reversed;\n\n if (currentPos) {\n this.jump(this.duration() - currentPos);\n }\n this.setVolume(curVol, 0.001);\n } else {\n throw 'SoundFile is not done loading';\n }\n };\n\n /**\n * Schedule an event to be called when the soundfile\n * reaches the end of a buffer. If the soundfile is\n * playing through once, this will be called when it\n * ends. If it is looping, it will be called when\n * stop is called.\n *\n * @method onended\n * @for p5.SoundFile\n * @param {Function} callback function to call when the\n * soundfile has ended.\n */\n p5.SoundFile.prototype.onended = function(callback) {\n this._onended = callback;\n return this;\n };\n\n p5.SoundFile.prototype.add = function() {\n // TO DO\n };\n\n p5.SoundFile.prototype.dispose = function() {\n var now = p5sound.audiocontext.currentTime;\n\n // remove reference to soundfile\n var index = p5sound.soundArray.indexOf(this);\n p5sound.soundArray.splice(index, 1);\n\n this.stop(now);\n if (this.buffer && this.bufferSourceNode) {\n for (var i = 0; i < this.bufferSourceNodes.length - 1; i++) {\n if (this.bufferSourceNodes[i] !== null) {\n this.bufferSourceNodes[i].disconnect();\n try {\n this.bufferSourceNodes[i].stop(now);\n } catch(e) {\n console.warning('no buffer source node to dispose');\n }\n this.bufferSourceNodes[i] = null;\n }\n }\n if ( this.isPlaying() ) {\n try {\n this._counterNode.stop(now);\n } catch(e) {\n console.log(e);\n }\n this._counterNode = null;\n }\n }\n if (this.output) {\n this.output.disconnect();\n this.output = null;\n }\n if (this.panner) {\n this.panner.disconnect();\n this.panner = null;\n }\n };\n\n /**\n * Connects the output of a p5sound object to input of another\n * p5.sound object. For example, you may connect a p5.SoundFile to an\n * FFT or an Effect. If no parameter is given, it will connect to\n * the master output. Most p5sound objects connect to the master\n * output when they are created.\n *\n * @method connect\n * @for p5.SoundFile\n * @param {Object} [object] Audio object that accepts an input\n */\n p5.SoundFile.prototype.connect = function(unit) {\n if (!unit) {\n this.panner.connect(p5sound.input);\n }\n else {\n if (unit.hasOwnProperty('input')) {\n this.panner.connect(unit.input);\n } else {\n this.panner.connect(unit);\n }\n }\n };\n\n /**\n * Disconnects the output of this p5sound object.\n *\n * @method disconnect\n * @for p5.SoundFile\n */\n p5.SoundFile.prototype.disconnect = function() {\n if (this.panner) {\n this.panner.disconnect();\n }\n };\n\n /**\n */\n p5.SoundFile.prototype.getLevel = function() {\n console.warn('p5.SoundFile.getLevel has been removed from the library. Use p5.Amplitude instead');\n };\n\n /**\n * Reset the source for this SoundFile to a\n * new path (URL).\n *\n * @method setPath\n * @for p5.SoundFile\n * @param {String} path path to audio file\n * @param {Function} callback Callback\n */\n p5.SoundFile.prototype.setPath = function(p, callback) {\n var path = p5.prototype._checkFileFormats(p);\n this.url = path;\n this.load(callback);\n };\n\n /**\n * Replace the current Audio Buffer with a new Buffer.\n *\n * @method setBuffer\n * @for p5.SoundFile\n * @param {Array} buf Array of Float32 Array(s). 2 Float32 Arrays\n * will create a stereo source. 1 will create\n * a mono source.\n */\n p5.SoundFile.prototype.setBuffer = function(buf) {\n var numChannels = buf.length;\n var size = buf[0].length;\n var newBuffer = ac.createBuffer(numChannels, size, ac.sampleRate);\n\n if (!(buf[0] instanceof Float32Array)) {\n buf[0] = new Float32Array(buf[0]);\n }\n\n for (var channelNum = 0; channelNum < numChannels; channelNum++) {\n var channel = newBuffer.getChannelData( channelNum );\n channel.set(buf[channelNum]);\n }\n\n this.buffer = newBuffer;\n\n // set numbers of channels on input to the panner\n this.panner.inputChannels(numChannels);\n };\n\n //////////////////////////////////////////////////\n // script processor node with an empty buffer to help\n // keep a sample-accurate position in playback buffer.\n // Inspired by Chinmay Pendharkar's technique for Sonoport --> http://bit.ly/1HwdCsV\n // Copyright [2015] [Sonoport (Asia) Pte. Ltd.],\n // Licensed under the Apache License http://apache.org/licenses/LICENSE-2.0\n ////////////////////////////////////////////////////////////////////////////////////\n\n var _createCounterBuffer = function(buffer) {\n const len = buffer.length;\n const audioBuf = ac.createBuffer( 1, buffer.length, ac.sampleRate );\n const arrayBuffer = audioBuf.getChannelData(0);\n for (var index = 0; index < len; index++) {\n arrayBuffer[index] = index;\n }\n return audioBuf;\n };\n\n // initialize counterNode, set its initial buffer and playbackRate\n p5.SoundFile.prototype._initCounterNode = function() {\n var self = this;\n var now = ac.currentTime;\n var cNode = ac.createBufferSource();\n\n // dispose of worklet node if it already exists\n if (self._workletNode) {\n self._workletNode.disconnect();\n delete self._workletNode;\n }\n self._workletNode = new AudioWorkletNode(ac, processorNames.soundFileProcessor);\n self._workletNode.port.onmessage = function(event) {\n if (event.data.name === 'position') {\n this._lastPos = event.data.position;\n\n // do any callbacks that have been scheduled\n this._onTimeUpdate(self._lastPos);\n }\n }.bind(self);\n\n // create counter buffer of the same length as self.buffer\n cNode.buffer = _createCounterBuffer( self.buffer );\n\n cNode.playbackRate.setValueAtTime(self.playbackRate, now);\n\n cNode.connect(self._workletNode);\n self._workletNode.connect(p5.soundOut._silentNode);\n\n return cNode;\n };\n\n // initialize sourceNode, set its initial buffer and playbackRate\n p5.SoundFile.prototype._initSourceNode = function() {\n var bufferSourceNode = ac.createBufferSource();\n bufferSourceNode.buffer = this.buffer;\n bufferSourceNode.playbackRate.value = this.playbackRate;\n bufferSourceNode.connect(this.output);\n return bufferSourceNode;\n };\n\n /**\n * processPeaks returns an array of timestamps where it thinks there is a beat.\n *\n * This is an asynchronous function that processes the soundfile in an offline audio context,\n * and sends the results to your callback function.\n *\n * The process involves running the soundfile through a lowpass filter, and finding all of the\n * peaks above the initial threshold. If the total number of peaks are below the minimum number of peaks,\n * it decreases the threshold and re-runs the analysis until either minPeaks or minThreshold are reached.\n *\n * @method processPeaks\n * @for p5.SoundFile\n * @param {Function} callback a function to call once this data is returned\n * @param {Number} [initThreshold] initial threshold defaults to 0.9\n * @param {Number} [minThreshold] minimum threshold defaults to 0.22\n * @param {Number} [minPeaks] minimum number of peaks defaults to 200\n * @return {Array} Array of timestamped peaks\n */\n p5.SoundFile.prototype.processPeaks = function(callback, _initThreshold, _minThreshold, _minPeaks) {\n var bufLen = this.buffer.length;\n var sampleRate = this.buffer.sampleRate;\n var buffer = this.buffer;\n var allPeaks = [];\n\n var initialThreshold = _initThreshold || 0.9,\n threshold = initialThreshold,\n minThreshold = _minThreshold || 0.22,\n minPeaks = _minPeaks || 200;\n\n // Create offline context\n var offlineContext = new window.OfflineAudioContext(1, bufLen, sampleRate);\n\n // create buffer source\n var source = offlineContext.createBufferSource();\n source.buffer = buffer;\n\n // Create filter. TO DO: allow custom setting of filter\n var filter = offlineContext.createBiquadFilter();\n filter.type = 'lowpass';\n source.connect(filter);\n filter.connect(offlineContext.destination);\n\n // start playing at time:0\n source.start(0);\n offlineContext.startRendering(); // Render the song\n\n // act on the result\n offlineContext.oncomplete = function(e) {\n if (!self.panner) return;\n var filteredBuffer = e.renderedBuffer;\n var bufferData = filteredBuffer.getChannelData(0);\n\n\n // step 1:\n // create Peak instances, add them to array, with strength and sampleIndex\n do {\n allPeaks = getPeaksAtThreshold(bufferData, threshold);\n threshold -= 0.005;\n } while (Object.keys(allPeaks).length < minPeaks && threshold >= minThreshold);\n\n\n // step 2:\n // find intervals for each peak in the sampleIndex, add tempos array\n var intervalCounts = countIntervalsBetweenNearbyPeaks(allPeaks);\n\n // step 3: find top tempos\n var groups = groupNeighborsByTempo(intervalCounts, filteredBuffer.sampleRate);\n\n // sort top intervals\n var topTempos = groups.sort(function(intA, intB) {\n return intB.count - intA.count;\n\n }).splice(0,5);\n\n // set this SoundFile's tempo to the top tempo ??\n this.tempo = topTempos[0].tempo;\n\n // step 4:\n // new array of peaks at top tempo within a bpmVariance\n var bpmVariance = 5;\n var tempoPeaks = getPeaksAtTopTempo(allPeaks, topTempos[0].tempo, filteredBuffer.sampleRate, bpmVariance);\n\n callback(tempoPeaks);\n };\n };\n\n // process peaks\n var Peak = function(amp, i) {\n this.sampleIndex = i;\n this.amplitude = amp;\n this.tempos = [];\n this.intervals = [];\n };\n\n // 1. for processPeaks() Function to identify peaks above a threshold\n // returns an array of peak indexes as frames (samples) of the original soundfile\n function getPeaksAtThreshold(data, threshold) {\n var peaksObj = {};\n var length = data.length;\n\n for (var i = 0; i < length; i++) {\n if (data[i] > threshold) {\n var amp = data[i];\n var peak = new Peak(amp, i);\n peaksObj[i] = peak;\n // Skip forward ~ 1/8s to get past this peak.\n i += 6000;\n }\n i++;\n }\n return peaksObj;\n }\n\n // 2. for processPeaks()\n function countIntervalsBetweenNearbyPeaks(peaksObj) {\n var intervalCounts = [];\n var peaksArray = Object.keys(peaksObj).sort();\n\n for (var index = 0; index < peaksArray.length; index++) {\n\n // find intervals in comparison to nearby peaks\n for (var i = 0; i < 10; i++) {\n var startPeak = peaksObj[peaksArray[index]];\n var endPeak = peaksObj[peaksArray[index + i]];\n\n if (startPeak && endPeak) {\n var startPos = startPeak.sampleIndex;\n var endPos = endPeak.sampleIndex;\n var interval = endPos - startPos;\n\n // add a sample interval to the startPeak in the allPeaks array\n if (interval > 0) {\n startPeak.intervals.push(interval);\n }\n\n // tally the intervals and return interval counts\n var foundInterval = intervalCounts.some(function(intervalCount) {\n if (intervalCount.interval === interval) {\n intervalCount.count++;\n return intervalCount;\n }\n });\n\n // store with JSON like formatting\n if (!foundInterval) {\n intervalCounts.push({\n interval: interval,\n count: 1,\n });\n }\n }\n }\n }\n\n return intervalCounts;\n }\n\n\n // 3. for processPeaks --> find tempo\n function groupNeighborsByTempo(intervalCounts, sampleRate) {\n var tempoCounts = [];\n\n intervalCounts.forEach(function(intervalCount) {\n\n try {\n // Convert an interval to tempo\n var theoreticalTempo = Math.abs( 60 / (intervalCount.interval / sampleRate ) );\n\n theoreticalTempo = mapTempo(theoreticalTempo);\n\n var foundTempo = tempoCounts.some(function(tempoCount) {\n if (tempoCount.tempo === theoreticalTempo)\n return tempoCount.count += intervalCount.count;\n });\n if (!foundTempo) {\n if (isNaN(theoreticalTempo)) {\n return;\n }\n tempoCounts.push({\n tempo: Math.round(theoreticalTempo),\n count: intervalCount.count\n });\n }\n } catch(e) {\n throw e;\n }\n\n });\n\n return tempoCounts;\n }\n\n // 4. for processPeaks - get peaks at top tempo\n function getPeaksAtTopTempo(peaksObj, tempo, sampleRate, bpmVariance) {\n var peaksAtTopTempo = [];\n var peaksArray = Object.keys(peaksObj).sort();\n\n // TO DO: filter out peaks that have the tempo and return\n for (var i = 0; i < peaksArray.length; i++) {\n var key = peaksArray[i];\n var peak = peaksObj[key];\n\n for (var j = 0; j < peak.intervals.length; j++) {\n var intervalBPM = Math.round(Math.abs( 60 / (peak.intervals[j] / sampleRate) ) );\n\n intervalBPM = mapTempo(intervalBPM);\n\n if ( Math.abs(intervalBPM - tempo) < bpmVariance ) {\n // convert sampleIndex to seconds\n peaksAtTopTempo.push(peak.sampleIndex/sampleRate);\n }\n }\n }\n\n // filter out peaks that are very close to each other\n peaksAtTopTempo = peaksAtTopTempo.filter(function(peakTime, index, arr) {\n var dif = arr[index + 1] - peakTime;\n if (dif > 0.01) {\n return true;\n }\n });\n\n return peaksAtTopTempo;\n }\n\n // helper function for processPeaks\n function mapTempo(theoreticalTempo) {\n // these scenarios create infinite while loop\n if (!isFinite(theoreticalTempo) || theoreticalTempo === 0 ) {\n return;\n }\n\n // Adjust the tempo to fit within the 90-180 BPM range\n while (theoreticalTempo < 90) theoreticalTempo *= 2;\n while (theoreticalTempo > 180 && theoreticalTempo > 90) theoreticalTempo /= 2;\n\n return theoreticalTempo;\n }\n\n\n /*** SCHEDULE EVENTS ***/\n\n // Cue inspired by JavaScript setTimeout, and the\n // Tone.js Transport Timeline Event, MIT License Yotam Mann 2015 tonejs.org\n var Cue = function(callback, time, id, val) {\n this.callback = callback;\n this.time = time;\n this.id = id;\n this.val = val;\n };\n\n /**\n * Schedule events to trigger every time a MediaElement\n * (audio/video) reaches a playback cue point.\n *\n * Accepts a callback function, a time (in seconds) at which to trigger\n * the callback, and an optional parameter for the callback.\n *\n * Time will be passed as the first parameter to the callback function,\n * and param will be the second parameter.\n *\n *\n * @method addCue\n * @for p5.SoundFile\n * @param {Number} time Time in seconds, relative to this media\n * element's playback. For example, to trigger\n * an event every time playback reaches two\n * seconds, pass in the number 2. This will be\n * passed as the first parameter to\n * the callback function.\n * @param {Function} callback Name of a function that will be\n * called at the given time. The callback will\n * receive time and (optionally) param as its\n * two parameters.\n * @param {Object} [value] An object to be passed as the\n * second parameter to the\n * callback function.\n * @return {Number} id ID of this cue,\n * useful for removeCue(id)\n * @example\n *
\n */\n p5.SoundFile.prototype.addCue = function(time, callback, val) {\n var id = this._cueIDCounter++;\n\n var cue = new Cue(callback, time, id, val);\n this._cues.push(cue);\n\n // if (!this.elt.ontimeupdate) {\n // this.elt.ontimeupdate = this._onTimeUpdate.bind(this);\n // }\n\n return id;\n };\n\n /**\n * Remove a callback based on its ID. The ID is returned by the\n * addCue method.\n *\n * @method removeCue\n * @for p5.SoundFile\n * @param {Number} id ID of the cue, as returned by addCue\n */\n p5.SoundFile.prototype.removeCue = function(id) {\n var cueLength = this._cues.length;\n for (var i = 0; i < cueLength; i++) {\n var cue = this._cues[i];\n if (cue.id === id) {\n this._cues.splice(i, 1);\n break;\n }\n }\n\n if (this._cues.length === 0) {\n // TO DO: remove callback\n // this.elt.ontimeupdate = null\n }\n };\n\n /**\n * Remove all of the callbacks that had originally been scheduled\n * via the addCue method.\n *\n * @method clearCues\n */\n p5.SoundFile.prototype.clearCues = function() {\n this._cues = [];\n // this.elt.ontimeupdate = null;\n };\n\n // private method that checks for cues to be fired if events\n // have been scheduled using addCue(callback, time).\n p5.SoundFile.prototype._onTimeUpdate = function(position) {\n var playbackTime = position/this.buffer.sampleRate;\n var cueLength = this._cues.length;\n\n for (var i = 0 ; i < cueLength; i++) {\n var cue = this._cues[i];\n var callbackTime = cue.time;\n var val = cue.val;\n\n if (this._prevTime < callbackTime && callbackTime <= playbackTime) {\n\n // pass the scheduled callbackTime as parameter to the callback\n cue.callback(val);\n }\n\n }\n\n this._prevTime = playbackTime;\n };\n\n /**\n * Save a p5.SoundFile as a .wav file. The browser will prompt the user\n * to download the file to their device. To upload a file to a server, see\n * getBlob\n *\n * @method save\n * @for p5.SoundFile\n * @param {String} [fileName] name of the resulting .wav file.\n * @example\n *
\n * var inp, button, mySound;\n * var fileName = 'cool';\n * function preload() {\n * mySound = loadSound('assets/doorbell.mp3');\n * }\n * function setup() {\n * btn = createButton('click to save file');\n * btn.position(0, 0);\n * btn.mouseClicked(handleMouseClick);\n * }\n *\n * function handleMouseClick() {\n * mySound.save(fileName);\n * }\n *
\n */\n p5.SoundFile.prototype.save = function(fileName) {\n const dataView = convertToWav(this.buffer);\n p5.prototype.saveSound([dataView], fileName, 'wav');\n };\n\n /**\n * This method is useful for sending a SoundFile to a server. It returns the\n * .wav-encoded audio data as a \"Blob\".\n * A Blob is a file-like data object that can be uploaded to a server\n * with an http request. We'll\n * use the `httpDo` options object to send a POST request with some\n * specific options: we encode the request as `multipart/form-data`,\n * and attach the blob as one of the form values using `FormData`.\n *\n *\n * @method getBlob\n * @for p5.SoundFile\n * @returns {Blob} A file-like data object\n * @example\n *
\n *\n * function preload() {\n * mySound = loadSound('assets/doorbell.mp3');\n * }\n *\n * function setup() {\n * noCanvas();\n * var soundBlob = mySound.getBlob();\n *\n * // Now we can send the blob to a server...\n * var serverUrl = 'https://jsonplaceholder.typicode.com/posts';\n * var httpRequestOptions = {\n * method: 'POST',\n * body: new FormData().append('soundBlob', soundBlob),\n * headers: new Headers({\n * 'Content-Type': 'multipart/form-data'\n * })\n * };\n * httpDo(serverUrl, httpRequestOptions);\n *\n * // We can also create an `ObjectURL` pointing to the Blob\n * var blobUrl = URL.createObjectURL(soundBlob);\n *\n * // The `
\n */\n p5.SoundFile.prototype.getBlob = function() {\n const dataView = convertToWav(this.buffer);\n return new Blob([dataView], { type: 'audio/wav' });\n };\n\n // event handler to remove references to the bufferSourceNode when it is done playing\n function _clearOnEnd(e) {\n const thisBufferSourceNode = e.target;\n const soundFile = this;\n\n // delete this.bufferSourceNode from the sources array when it is done playing:\n thisBufferSourceNode._playing = false;\n thisBufferSourceNode.removeEventListener('ended', soundFile._clearOnEnd);\n\n // call the onended callback\n soundFile._onended(soundFile);\n\n soundFile.bufferSourceNodes.forEach(function (n, i) {\n if (n._playing === false) {\n soundFile.bufferSourceNodes.splice(i);\n }\n });\n\n if (soundFile.bufferSourceNodes.length === 0) {\n soundFile._playing = false;\n }\n }\n});\n","'use strict';\n\ndefine(function (require) {\n var p5sound = require('master');\n var processorNames = require('./audioWorklet/processorNames');\n\n /**\n * Amplitude measures volume between 0.0 and 1.0.\n * Listens to all p5sound by default, or use setInput()\n * to listen to a specific sound source. Accepts an optional\n * smoothing value, which defaults to 0.\n *\n * @class p5.Amplitude\n * @constructor\n * @param {Number} [smoothing] between 0.0 and .999 to smooth\n * amplitude readings (defaults to 0)\n * @example\n *
\n * var sound, amplitude, cnv;\n *\n * function preload(){\n * sound = loadSound('assets/beat.mp3');\n * }\n * function setup() {\n * cnv = createCanvas(100,100);\n * amplitude = new p5.Amplitude();\n *\n * // start / stop the sound when canvas is clicked\n * cnv.mouseClicked(function() {\n * if (sound.isPlaying() ){\n * sound.stop();\n * } else {\n * sound.play();\n * }\n * });\n * }\n * function draw() {\n * background(0);\n * fill(255);\n * var level = amplitude.getLevel();\n * var size = map(level, 0, 1, 0, 200);\n * ellipse(width/2, height/2, size, size);\n * }\n *\n *
\n */\n p5.Amplitude = function(smoothing) {\n\n // Set to 2048 for now. In future iterations, this should be inherited or parsed from p5sound's default\n this.bufferSize = 2048;\n\n // set audio context\n this.audiocontext = p5sound.audiocontext;\n this._workletNode = new AudioWorkletNode(this.audiocontext, processorNames.amplitudeProcessor, {\n outputChannelCount: [1],\n processorOptions: {\n normalize: false,\n smoothing: smoothing || 0\n }\n });\n\n this._workletNode.port.onmessage = function(event) {\n if (event.data.name === 'amplitude') {\n this.volume = event.data.volume;\n this.volNorm = event.data.volNorm;\n this.stereoVol = event.data.stereoVol;\n this.stereoVolNorm = event.data.stereoVolNorm;\n }\n }.bind(this);\n\n // for connections\n this.input = this._workletNode;\n\n this.output = this.audiocontext.createGain();\n\n // the variables to return\n this.volume = 0;\n this.volNorm = 0;\n this.stereoVol = [0, 0];\n this.stereoVolNorm = [0, 0];\n\n this.normalize = false;\n\n this._workletNode.connect(this.output);\n this.output.gain.value = 0;\n\n // this may only be necessary because of a Chrome bug\n this.output.connect(this.audiocontext.destination);\n\n // connect to p5sound master output by default, unless set by input()\n p5sound.meter.connect(this._workletNode);\n\n // add this p5.SoundFile to the soundArray\n p5sound.soundArray.push(this);\n };\n\n /**\n * Connects to the p5sound instance (master output) by default.\n * Optionally, you can pass in a specific source (i.e. a soundfile).\n *\n * @method setInput\n * @for p5.Amplitude\n * @param {soundObject|undefined} [snd] set the sound source\n * (optional, defaults to\n * master output)\n * @param {Number|undefined} [smoothing] a range between 0.0 and 1.0\n * to smooth amplitude readings\n * @example\n *
\n * function preload(){\n * sound1 = loadSound('assets/beat.mp3');\n * sound2 = loadSound('assets/drum.mp3');\n * }\n * function setup(){\n * amplitude = new p5.Amplitude();\n * sound1.play();\n * sound2.play();\n * amplitude.setInput(sound2);\n * }\n * function draw() {\n * background(0);\n * fill(255);\n * var level = amplitude.getLevel();\n * var size = map(level, 0, 1, 0, 200);\n * ellipse(width/2, height/2, size, size);\n * }\n * function mouseClicked(){\n * sound1.stop();\n * sound2.stop();\n * }\n *
\n */\n p5.Amplitude.prototype.setInput = function(source, smoothing) {\n\n p5sound.meter.disconnect();\n\n if (smoothing) {\n this._workletNode.parameters.get('smoothing').value = smoothing;\n }\n\n // connect to the master out of p5s instance if no snd is provided\n if (source == null) {\n console.log('Amplitude input source is not ready! Connecting to master output instead');\n p5sound.meter.connect(this._workletNode);\n }\n\n // if it is a p5.Signal\n else if (source instanceof p5.Signal) {\n source.output.connect(this._workletNode);\n }\n // connect to the sound if it is available\n else if (source) {\n source.connect(this._workletNode);\n this._workletNode.disconnect();\n this._workletNode.connect(this.output);\n }\n\n // otherwise, connect to the master out of p5s instance (default)\n else {\n p5sound.meter.connect(this._workletNode);\n }\n };\n\n p5.Amplitude.prototype.connect = function(unit) {\n if (unit) {\n if (unit.hasOwnProperty('input')) {\n this.output.connect(unit.input);\n } else {\n this.output.connect(unit);\n }\n } else {\n this.output.connect(this.panner.connect(p5sound.input));\n }\n };\n\n p5.Amplitude.prototype.disconnect = function() {\n if (this.output) {\n this.output.disconnect();\n }\n };\n\n /**\n * Returns a single Amplitude reading at the moment it is called.\n * For continuous readings, run in the draw loop.\n *\n * @method getLevel\n * @for p5.Amplitude\n * @param {Number} [channel] Optionally return only channel 0 (left) or 1 (right)\n * @return {Number} Amplitude as a number between 0.0 and 1.0\n * @example\n *
\n * function preload(){\n * sound = loadSound('assets/beat.mp3');\n * }\n * function setup() {\n * amplitude = new p5.Amplitude();\n * sound.play();\n * }\n * function draw() {\n * background(0);\n * fill(255);\n * var level = amplitude.getLevel();\n * var size = map(level, 0, 1, 0, 200);\n * ellipse(width/2, height/2, size, size);\n * }\n * function mouseClicked(){\n * sound.stop();\n * }\n *
\n */\n p5.Amplitude.prototype.getLevel = function(channel) {\n if (typeof channel !== 'undefined') {\n if (this.normalize) {\n return this.stereoVolNorm[channel];\n } else {\n return this.stereoVol[channel];\n }\n }\n else if (this.normalize) {\n return this.volNorm;\n }\n else {\n return this.volume;\n }\n };\n\n /**\n * Determines whether the results of Amplitude.process() will be\n * Normalized. To normalize, Amplitude finds the difference the\n * loudest reading it has processed and the maximum amplitude of\n * 1.0. Amplitude adds this difference to all values to produce\n * results that will reliably map between 0.0 and 1.0. However,\n * if a louder moment occurs, the amount that Normalize adds to\n * all the values will change. Accepts an optional boolean parameter\n * (true or false). Normalizing is off by default.\n *\n * @method toggleNormalize\n * @for p5.Amplitude\n * @param {boolean} [boolean] set normalize to true (1) or false (0)\n */\n p5.Amplitude.prototype.toggleNormalize = function(bool) {\n if (typeof bool === 'boolean') {\n this.normalize = bool;\n }\n else {\n this.normalize = !this.normalize;\n }\n this._workletNode.port.postMessage({ name: 'toggleNormalize', normalize: this.normalize });\n };\n\n /**\n * Smooth Amplitude analysis by averaging with the last analysis\n * frame. Off by default.\n *\n * @method smooth\n * @for p5.Amplitude\n * @param {Number} set smoothing from 0.0 <= 1\n */\n p5.Amplitude.prototype.smooth = function(s) {\n if (s >= 0 && s < 1) {\n this._workletNode.port.postMessage({ name: 'smoothing', smoothing: s });\n } else {\n console.log('Error: smoothing must be between 0 and 1');\n }\n };\n\n p5.Amplitude.prototype.dispose = function() {\n // remove reference from soundArray\n var index = p5sound.soundArray.indexOf(this);\n p5sound.soundArray.splice(index, 1);\n\n if (this.input) {\n this.input.disconnect();\n delete this.input;\n }\n if (this.output) {\n this.output.disconnect();\n delete this.output;\n }\n\n this._workletNode.disconnect();\n delete this._workletNode;\n };\n\n});\n","'use strict';\n\ndefine(function(require) {\n var p5sound = require('master');\n\n /**\n *
FFT (Fast Fourier Transform) is an analysis algorithm that\n * isolates individual\n * \n * audio frequencies within a waveform.
\n *\n *
Once instantiated, a p5.FFT object can return an array based on\n * two types of analyses: • FFT.waveform() computes\n * amplitude values along the time domain. The array indices correspond\n * to samples across a brief moment in time. Each value represents\n * amplitude of the waveform at that sample of time. \n * • FFT.analyze() computes amplitude values along the\n * frequency domain. The array indices correspond to frequencies (i.e.\n * pitches), from the lowest to the highest that humans can hear. Each\n * value represents amplitude at that slice of the frequency spectrum.\n * Use with getEnergy() to measure amplitude at specific\n * frequencies, or within a range of frequencies.
\n *\n *
FFT analyzes a very short snapshot of sound called a sample\n * buffer. It returns an array of amplitude measurements, referred\n * to as bins. The array is 1024 bins long by default.\n * You can change the bin array length, but it must be a power of 2\n * between 16 and 1024 in order for the FFT algorithm to function\n * correctly. The actual size of the FFT buffer is twice the\n * number of bins, so given a standard sample rate, the buffer is\n * 2048/44100 seconds long.
\n *\n *\n * @class p5.FFT\n * @constructor\n * @param {Number} [smoothing] Smooth results of Freq Spectrum.\n * 0.0 < smoothing < 1.0.\n * Defaults to 0.8.\n * @param {Number} [bins] Length of resulting array.\n * Must be a power of two between\n * 16 and 1024. Defaults to 1024.\n * @example\n *
\n * function preload(){\n * sound = loadSound('assets/Damscray_DancingTiger.mp3');\n * }\n *\n * function setup(){\n * var cnv = createCanvas(100,100);\n * cnv.mouseClicked(togglePlay);\n * fft = new p5.FFT();\n * sound.amp(0.2);\n * }\n *\n * function draw(){\n * background(0);\n *\n * var spectrum = fft.analyze();\n * noStroke();\n * fill(0,255,0); // spectrum is green\n * for (var i = 0; i< spectrum.length; i++){\n * var x = map(i, 0, spectrum.length, 0, width);\n * var h = -height + map(spectrum[i], 0, 255, height, 0);\n * rect(x, height, width / spectrum.length, h )\n * }\n *\n * var waveform = fft.waveform();\n * noFill();\n * beginShape();\n * stroke(255,0,0); // waveform is red\n * strokeWeight(1);\n * for (var i = 0; i< waveform.length; i++){\n * var x = map(i, 0, waveform.length, 0, width);\n * var y = map( waveform[i], -1, 1, 0, height);\n * vertex(x,y);\n * }\n * endShape();\n *\n * text('click to play/pause', 4, 10);\n * }\n *\n * // fade sound if mouse is over canvas\n * function togglePlay() {\n * if (sound.isPlaying()) {\n * sound.pause();\n * } else {\n * sound.loop();\n * }\n * }\n *
\n */\n p5.FFT = function(smoothing, bins) {\n this.input = this.analyser = p5sound.audiocontext.createAnalyser();\n\n Object.defineProperties(this, {\n bins: {\n get: function() {\n return this.analyser.fftSize / 2;\n },\n set: function(b) {\n this.analyser.fftSize = b * 2;\n },\n configurable: true,\n enumerable: true\n },\n smoothing: {\n get: function() {\n return this.analyser.smoothingTimeConstant;\n },\n set: function(s) {\n this.analyser.smoothingTimeConstant = s;\n },\n configurable: true,\n enumerable: true\n }\n });\n\n // set default smoothing and bins\n this.smooth(smoothing);\n this.bins = bins || 1024;\n\n // default connections to p5sound fftMeter\n p5sound.fftMeter.connect(this.analyser);\n\n this.freqDomain = new Uint8Array(this.analyser.frequencyBinCount);\n this.timeDomain = new Uint8Array(this.analyser.frequencyBinCount);\n\n // predefined frequency ranges, these will be tweakable\n this.bass = [20, 140];\n this.lowMid = [140, 400];\n this.mid = [400, 2600];\n this.highMid = [2600, 5200];\n this.treble = [5200, 14000];\n\n // add this p5.SoundFile to the soundArray\n p5sound.soundArray.push(this);\n };\n\n /**\n * Set the input source for the FFT analysis. If no source is\n * provided, FFT will analyze all sound in the sketch.\n *\n * @method setInput\n * @for p5.FFT\n * @param {Object} [source] p5.sound object (or web audio API source node)\n */\n p5.FFT.prototype.setInput = function(source) {\n if (!source) {\n p5sound.fftMeter.connect(this.analyser);\n } else {\n if (source.output) {\n source.output.connect(this.analyser);\n } else if (source.connect) {\n source.connect(this.analyser);\n }\n p5sound.fftMeter.disconnect();\n }\n };\n\n /**\n * Returns an array of amplitude values (between -1.0 and +1.0) that represent\n * a snapshot of amplitude readings in a single buffer. Length will be\n * equal to bins (defaults to 1024). Can be used to draw the waveform\n * of a sound.\n *\n * @method waveform\n * @for p5.FFT\n * @param {Number} [bins] Must be a power of two between\n * 16 and 1024. Defaults to 1024.\n * @param {String} [precision] If any value is provided, will return results\n * in a Float32 Array which is more precise\n * than a regular array.\n * @return {Array} Array Array of amplitude values (-1 to 1)\n * over time. Array length = bins.\n *\n */\n p5.FFT.prototype.waveform = function() {\n var bins, mode, normalArray;\n\n for (var i = 0; i < arguments.length; i++) {\n if (typeof arguments[i] === 'number') {\n bins = arguments[i];\n this.analyser.fftSize = bins * 2;\n }\n if (typeof arguments[i] === 'string') {\n mode = arguments[i];\n }\n }\n\n // getFloatFrequencyData doesnt work in Safari as of 5/2015\n if (mode && !p5.prototype._isSafari()) {\n timeToFloat(this, this.timeDomain);\n this.analyser.getFloatTimeDomainData(this.timeDomain);\n return this.timeDomain;\n } else {\n timeToInt(this, this.timeDomain);\n this.analyser.getByteTimeDomainData(this.timeDomain);\n var normalArray = new Array();\n for (var j = 0; j < this.timeDomain.length; j++) {\n var scaled = p5.prototype.map(this.timeDomain[j], 0, 255, -1, 1);\n normalArray.push(scaled);\n }\n return normalArray;\n }\n };\n\n /**\n * Returns an array of amplitude values (between 0 and 255)\n * across the frequency spectrum. Length is equal to FFT bins\n * (1024 by default). The array indices correspond to frequencies\n * (i.e. pitches), from the lowest to the highest that humans can\n * hear. Each value represents amplitude at that slice of the\n * frequency spectrum. Must be called prior to using\n * getEnergy().\n *\n * @method analyze\n * @for p5.FFT\n * @param {Number} [bins] Must be a power of two between\n * 16 and 1024. Defaults to 1024.\n * @param {Number} [scale] If \"dB,\" returns decibel\n * float measurements between\n * -140 and 0 (max).\n * Otherwise returns integers from 0-255.\n * @return {Array} spectrum Array of energy (amplitude/volume)\n * values across the frequency spectrum.\n * Lowest energy (silence) = 0, highest\n * possible is 255.\n * @example\n *
\n * var osc;\n * var fft;\n *\n * function setup(){\n * createCanvas(100,100);\n * osc = new p5.Oscillator();\n * osc.amp(0);\n * osc.start();\n * fft = new p5.FFT();\n * }\n *\n * function draw(){\n * background(0);\n *\n * var freq = map(mouseX, 0, 800, 20, 15000);\n * freq = constrain(freq, 1, 20000);\n * osc.freq(freq);\n *\n * var spectrum = fft.analyze();\n * noStroke();\n * fill(0,255,0); // spectrum is green\n * for (var i = 0; i< spectrum.length; i++){\n * var x = map(i, 0, spectrum.length, 0, width);\n * var h = -height + map(spectrum[i], 0, 255, height, 0);\n * rect(x, height, width / spectrum.length, h );\n * }\n *\n * stroke(255);\n * text('Freq: ' + round(freq)+'Hz', 10, 10);\n *\n * isMouseOverCanvas();\n * }\n *\n * // only play sound when mouse is over canvas\n * function isMouseOverCanvas() {\n * var mX = mouseX, mY = mouseY;\n * if (mX > 0 && mX < width && mY < height && mY > 0) {\n * osc.amp(0.5, 0.2);\n * } else {\n * osc.amp(0, 0.2);\n * }\n * }\n *
\n *\n *\n */\n p5.FFT.prototype.analyze = function() {\n var mode;\n\n for (var i = 0; i < arguments.length; i++) {\n if (typeof arguments[i] === 'number') {\n this.bins = arguments[i];\n this.analyser.fftSize = this.bins * 2;\n }\n if (typeof arguments[i] === 'string') {\n mode = arguments[i];\n }\n }\n\n if (mode && mode.toLowerCase() === 'db') {\n freqToFloat(this);\n this.analyser.getFloatFrequencyData(this.freqDomain);\n return this.freqDomain;\n } else {\n freqToInt(this, this.freqDomain);\n this.analyser.getByteFrequencyData(this.freqDomain);\n var normalArray = Array.apply([], this.freqDomain);\n \n return normalArray;\n }\n };\n\n /**\n * Returns the amount of energy (volume) at a specific\n * \n * frequency, or the average amount of energy between two\n * frequencies. Accepts Number(s) corresponding\n * to frequency (in Hz), or a String corresponding to predefined\n * frequency ranges (\"bass\", \"lowMid\", \"mid\", \"highMid\", \"treble\").\n * Returns a range between 0 (no energy/volume at that frequency) and\n * 255 (maximum energy).\n * NOTE: analyze() must be called prior to getEnergy(). Analyze()\n * tells the FFT to analyze frequency data, and getEnergy() uses\n * the results determine the value at a specific frequency or\n * range of frequencies.\n *\n * @method getEnergy\n * @for p5.FFT\n * @param {Number|String} frequency1 Will return a value representing\n * energy at this frequency. Alternately,\n * the strings \"bass\", \"lowMid\" \"mid\",\n * \"highMid\", and \"treble\" will return\n * predefined frequency ranges.\n * @param {Number} [frequency2] If a second frequency is given,\n * will return average amount of\n * energy that exists between the\n * two frequencies.\n * @return {Number} Energy Energy (volume/amplitude) from\n * 0 and 255.\n *\n */\n p5.FFT.prototype.getEnergy = function(frequency1, frequency2) {\n var nyquist = p5sound.audiocontext.sampleRate / 2;\n\n if (frequency1 === 'bass') {\n frequency1 = this.bass[0];\n frequency2 = this.bass[1];\n } else if (frequency1 === 'lowMid') {\n frequency1 = this.lowMid[0];\n frequency2 = this.lowMid[1];\n } else if (frequency1 === 'mid') {\n frequency1 = this.mid[0];\n frequency2 = this.mid[1];\n } else if (frequency1 === 'highMid') {\n frequency1 = this.highMid[0];\n frequency2 = this.highMid[1];\n } else if (frequency1 === 'treble') {\n frequency1 = this.treble[0];\n frequency2 = this.treble[1];\n }\n\n if (typeof frequency1 !== 'number') {\n throw 'invalid input for getEnergy()';\n } else if (!frequency2) {\n // if only one parameter:\n var index = Math.round(frequency1 / nyquist * this.freqDomain.length);\n return this.freqDomain[index];\n } else if (frequency1 && frequency2) {\n // if two parameters:\n // if second is higher than first\n if (frequency1 > frequency2) {\n var swap = frequency2;\n frequency2 = frequency1;\n frequency1 = swap;\n }\n var lowIndex = Math.round(frequency1 / nyquist * this.freqDomain.length);\n var highIndex = Math.round(frequency2 / nyquist * this.freqDomain.length);\n\n var total = 0;\n var numFrequencies = 0;\n // add up all of the values for the frequencies\n for (var i = lowIndex; i <= highIndex; i++) {\n total += this.freqDomain[i];\n numFrequencies += 1;\n }\n // divide by total number of frequencies\n var toReturn = total / numFrequencies;\n return toReturn;\n } else {\n throw 'invalid input for getEnergy()';\n }\n };\n\n // compatability with v.012, changed to getEnergy in v.0121. Will be deprecated...\n p5.FFT.prototype.getFreq = function(freq1, freq2) {\n console.log('getFreq() is deprecated. Please use getEnergy() instead.');\n var x = this.getEnergy(freq1, freq2);\n return x;\n };\n\n /**\n * Returns the\n * \n * spectral centroid of the input signal.\n * NOTE: analyze() must be called prior to getCentroid(). Analyze()\n * tells the FFT to analyze frequency data, and getCentroid() uses\n * the results determine the spectral centroid.\n *\n * @method getCentroid\n * @for p5.FFT\n * @return {Number} Spectral Centroid Frequency Frequency of the spectral centroid in Hz.\n *\n *\n * @example\n *
\n *\n *\n *function setup(){\n * cnv = createCanvas(100,100);\n * sound = new p5.AudioIn();\n * sound.start();\n * fft = new p5.FFT();\n * sound.connect(fft);\n *}\n *\n *\n *function draw(){\n *\n * var centroidplot = 0.0;\n * var spectralCentroid = 0;\n *\n *\n * background(0);\n * stroke(0,255,0);\n * var spectrum = fft.analyze();\n * fill(0,255,0); // spectrum is green\n *\n * //draw the spectrum\n * for (var i = 0; i< spectrum.length; i++){\n * var x = map(log(i), 0, log(spectrum.length), 0, width);\n * var h = map(spectrum[i], 0, 255, 0, height);\n * var rectangle_width = (log(i+1)-log(i))*(width/log(spectrum.length));\n * rect(x, height, rectangle_width, -h )\n * }\n\n * var nyquist = 22050;\n *\n * // get the centroid\n * spectralCentroid = fft.getCentroid();\n *\n * // the mean_freq_index calculation is for the display.\n * var mean_freq_index = spectralCentroid/(nyquist/spectrum.length);\n *\n * centroidplot = map(log(mean_freq_index), 0, log(spectrum.length), 0, width);\n *\n *\n * stroke(255,0,0); // the line showing where the centroid is will be red\n *\n * rect(centroidplot, 0, width / spectrum.length, height)\n * noStroke();\n * fill(255,255,255); // text is white\n * text(\"centroid: \", 10, 20);\n * text(round(spectralCentroid)+\" Hz\", 10, 40);\n *}\n *
\n */\n p5.FFT.prototype.getCentroid = function() {\n var nyquist = p5sound.audiocontext.sampleRate / 2;\n var cumulative_sum = 0;\n var centroid_normalization = 0;\n\n for (var i = 0; i < this.freqDomain.length; i++) {\n cumulative_sum += i * this.freqDomain[i];\n centroid_normalization += this.freqDomain[i];\n }\n\n var mean_freq_index = 0;\n\n if (centroid_normalization !== 0) {\n mean_freq_index = cumulative_sum / centroid_normalization;\n }\n\n var spec_centroid_freq =\n mean_freq_index * (nyquist / this.freqDomain.length);\n return spec_centroid_freq;\n };\n\n /**\n * Smooth FFT analysis by averaging with the last analysis frame.\n *\n * @method smooth\n * @param {Number} smoothing 0.0 < smoothing < 1.0.\n * Defaults to 0.8.\n */\n p5.FFT.prototype.smooth = function(s) {\n if (typeof s !== 'undefined') {\n this.smoothing = s;\n }\n return this.smoothing;\n };\n\n p5.FFT.prototype.dispose = function() {\n // remove reference from soundArray\n var index = p5sound.soundArray.indexOf(this);\n p5sound.soundArray.splice(index, 1);\n\n if (this.analyser) {\n this.analyser.disconnect();\n delete this.analyser;\n }\n };\n\n /**\n * Returns an array of average amplitude values for a given number\n * of frequency bands split equally. N defaults to 16.\n * NOTE: analyze() must be called prior to linAverages(). Analyze()\n * tells the FFT to analyze frequency data, and linAverages() uses\n * the results to group them into a smaller set of averages.\n *\n * @method linAverages\n * @for p5.FFT\n * @param {Number} N Number of returned frequency groups\n * @return {Array} linearAverages Array of average amplitude values for each group\n */\n p5.FFT.prototype.linAverages = function(N) {\n var N = N || 16; // This prevents undefined, null or 0 values of N\n\n var spectrum = this.freqDomain;\n var spectrumLength = spectrum.length;\n var spectrumStep = Math.floor(spectrumLength / N);\n\n var linearAverages = new Array(N);\n // Keep a second index for the current average group and place the values accordingly\n // with only one loop in the spectrum data\n var groupIndex = 0;\n\n for (var specIndex = 0; specIndex < spectrumLength; specIndex++) {\n linearAverages[groupIndex] =\n linearAverages[groupIndex] !== undefined\n ? (linearAverages[groupIndex] + spectrum[specIndex]) / 2\n : spectrum[specIndex];\n\n // Increase the group index when the last element of the group is processed\n if (specIndex % spectrumStep === spectrumStep - 1) {\n groupIndex++;\n }\n }\n\n return linearAverages;\n };\n\n /**\n * Returns an array of average amplitude values of the spectrum, for a given\n * set of \n * Octave Bands\n * NOTE: analyze() must be called prior to logAverages(). Analyze()\n * tells the FFT to analyze frequency data, and logAverages() uses\n * the results to group them into a smaller set of averages.\n *\n * @method logAverages\n * @for p5.FFT\n * @param {Array} octaveBands Array of Octave Bands objects for grouping\n * @return {Array} logAverages Array of average amplitude values for each group\n */\n p5.FFT.prototype.logAverages = function(octaveBands) {\n var nyquist = p5sound.audiocontext.sampleRate / 2;\n var spectrum = this.freqDomain;\n var spectrumLength = spectrum.length;\n\n var logAverages = new Array(octaveBands.length);\n // Keep a second index for the current average group and place the values accordingly\n // With only one loop in the spectrum data\n var octaveIndex = 0;\n\n for (var specIndex = 0; specIndex < spectrumLength; specIndex++) {\n var specIndexFrequency = Math.round(\n specIndex * nyquist / this.freqDomain.length\n );\n\n // Increase the group index if the current frequency exceeds the limits of the band\n if (specIndexFrequency > octaveBands[octaveIndex].hi) {\n octaveIndex++;\n }\n\n logAverages[octaveIndex] =\n logAverages[octaveIndex] !== undefined\n ? (logAverages[octaveIndex] + spectrum[specIndex]) / 2\n : spectrum[specIndex];\n }\n\n return logAverages;\n };\n\n /**\n * Calculates and Returns the 1/N\n * Octave Bands\n * N defaults to 3 and minimum central frequency to 15.625Hz.\n * (1/3 Octave Bands ~= 31 Frequency Bands)\n * Setting fCtr0 to a central value of a higher octave will ignore the lower bands\n * and produce less frequency groups.\n *\n * @method getOctaveBands\n * @for p5.FFT\n * @param {Number} N Specifies the 1/N type of generated octave bands\n * @param {Number} fCtr0 Minimum central frequency for the lowest band\n * @return {Array} octaveBands Array of octave band objects with their bounds\n */\n p5.FFT.prototype.getOctaveBands = function(N, fCtr0) {\n var N = N || 3; // Default to 1/3 Octave Bands\n var fCtr0 = fCtr0 || 15.625; // Minimum central frequency, defaults to 15.625Hz\n\n var octaveBands = [];\n var lastFrequencyBand = {\n lo: fCtr0 / Math.pow(2, 1 / (2 * N)),\n ctr: fCtr0,\n hi: fCtr0 * Math.pow(2, 1 / (2 * N))\n };\n octaveBands.push(lastFrequencyBand);\n\n var nyquist = p5sound.audiocontext.sampleRate / 2;\n while (lastFrequencyBand.hi < nyquist) {\n var newFrequencyBand = {};\n newFrequencyBand.lo = lastFrequencyBand.hi;\n newFrequencyBand.ctr = lastFrequencyBand.ctr * Math.pow(2, 1 / N);\n newFrequencyBand.hi = newFrequencyBand.ctr * Math.pow(2, 1 / (2 * N));\n\n octaveBands.push(newFrequencyBand);\n lastFrequencyBand = newFrequencyBand;\n }\n\n return octaveBands;\n };\n\n // helper methods to convert type from float (dB) to int (0-255)\n var freqToFloat = function(fft) {\n if (fft.freqDomain instanceof Float32Array === false) {\n fft.freqDomain = new Float32Array(fft.analyser.frequencyBinCount);\n }\n };\n var freqToInt = function(fft) {\n if (fft.freqDomain instanceof Uint8Array === false) {\n fft.freqDomain = new Uint8Array(fft.analyser.frequencyBinCount);\n }\n };\n var timeToFloat = function(fft) {\n if (fft.timeDomain instanceof Float32Array === false) {\n fft.timeDomain = new Float32Array(fft.analyser.frequencyBinCount);\n }\n };\n var timeToInt = function(fft) {\n if (fft.timeDomain instanceof Uint8Array === false) {\n fft.timeDomain = new Uint8Array(fft.analyser.frequencyBinCount);\n }\n };\n});\n","'use strict';\n\ndefine(function (require) {\n\n // Signal is built with the Tone.js signal by Yotam Mann\n // https://github.com/TONEnoTONE/Tone.js/\n var Signal = require('Tone/signal/Signal');\n var Add = require('Tone/signal/Add');\n var Mult = require('Tone/signal/Multiply');\n var Scale = require('Tone/signal/Scale');\n\n /**\n *
p5.Signal is a constant audio-rate signal used by p5.Oscillator\n * and p5.Envelope for modulation math.
\n *\n *
This is necessary because Web Audio is processed on a seprate clock.\n * For example, the p5 draw loop runs about 60 times per second. But\n * the audio clock must process samples 44100 times per second. If we\n * want to add a value to each of those samples, we can't do it in the\n * draw loop, but we can do it by adding a constant-rate audio signal.This class mostly functions behind the scenes in p5.sound, and returns\n * a Tone.Signal from the Tone.js library by Yotam Mann.\n * If you want to work directly with audio signals for modular\n * synthesis, check out\n * tone.js.
\n *\n * @class p5.Signal\n * @constructor\n * @return {Tone.Signal} A Signal object from the Tone.js library\n * @example\n *
\n * function setup() {\n * carrier = new p5.Oscillator('sine');\n * carrier.amp(1); // set amplitude\n * carrier.freq(220); // set frequency\n * carrier.start(); // start oscillating\n *\n * modulator = new p5.Oscillator('sawtooth');\n * modulator.disconnect();\n * modulator.amp(1);\n * modulator.freq(4);\n * modulator.start();\n *\n * // Modulator's default amplitude range is -1 to 1.\n * // Multiply it by -200, so the range is -200 to 200\n * // then add 220 so the range is 20 to 420\n * carrier.freq( modulator.mult(-200).add(220) );\n * }\n *
\n */\n p5.Signal = function(value) {\n var s = new Signal(value);\n // p5sound.soundArray.push(s);\n return s; // TODO: is this really a constructor?\n };\n\n /**\n * Fade to value, for smooth transitions\n *\n * @method fade\n * @for p5.Signal\n * @param {Number} value Value to set this signal\n * @param {Number} [secondsFromNow] Length of fade, in seconds from now\n */\n Signal.prototype.fade = Signal.prototype.linearRampToValueAtTime;\n Mult.prototype.fade = Signal.prototype.fade;\n Add.prototype.fade = Signal.prototype.fade;\n Scale.prototype.fade = Signal.prototype.fade;\n\n\n /**\n * Connect a p5.sound object or Web Audio node to this\n * p5.Signal so that its amplitude values can be scaled.\n *\n * @method setInput\n * @for p5.Signal\n * @param {Object} input\n */\n Signal.prototype.setInput = function(_input) {\n _input.connect(this);\n };\n Mult.prototype.setInput = Signal.prototype.setInput;\n Add.prototype.setInput = Signal.prototype.setInput;\n Scale.prototype.setInput = Signal.prototype.setInput;\n\n\n // signals can add / mult / scale themselves\n\n /**\n * Add a constant value to this audio signal,\n * and return the resulting audio signal. Does\n * not change the value of the original signal,\n * instead it returns a new p5.SignalAdd.\n *\n * @method add\n * @for p5.Signal\n * @param {Number} number\n * @return {p5.Signal} object\n */\n Signal.prototype.add = function(num) {\n var add = new Add(num);\n // add.setInput(this);\n this.connect(add);\n return add;\n };\n Mult.prototype.add = Signal.prototype.add;\n Add.prototype.add = Signal.prototype.add;\n Scale.prototype.add = Signal.prototype.add;\n\n /**\n * Multiply this signal by a constant value,\n * and return the resulting audio signal. Does\n * not change the value of the original signal,\n * instead it returns a new p5.SignalMult.\n *\n * @method mult\n * @for p5.Signal\n * @param {Number} number to multiply\n * @return {p5.Signal} object\n */\n Signal.prototype.mult = function(num) {\n var mult = new Mult(num);\n // mult.setInput(this);\n this.connect(mult);\n return mult;\n };\n Mult.prototype.mult = Signal.prototype.mult;\n Add.prototype.mult = Signal.prototype.mult;\n Scale.prototype.mult = Signal.prototype.mult;\n\n /**\n * Scale this signal value to a given range,\n * and return the result as an audio signal. Does\n * not change the value of the original signal,\n * instead it returns a new p5.SignalScale.\n *\n * @method scale\n * @for p5.Signal\n * @param {Number} number to multiply\n * @param {Number} inMin input range minumum\n * @param {Number} inMax input range maximum\n * @param {Number} outMin input range minumum\n * @param {Number} outMax input range maximum\n * @return {p5.Signal} object\n */\n Signal.prototype.scale = function(inMin, inMax, outMin, outMax) {\n var mapOutMin, mapOutMax;\n if (arguments.length === 4) {\n mapOutMin = p5.prototype.map(outMin, inMin, inMax, 0, 1) - 0.5;\n mapOutMax = p5.prototype.map(outMax, inMin, inMax, 0, 1) - 0.5;\n }\n else {\n mapOutMin = arguments[0];\n mapOutMax = arguments[1];\n }\n var scale = new Scale(mapOutMin, mapOutMax);\n this.connect(scale);\n return scale;\n };\n Mult.prototype.scale = Signal.prototype.scale;\n Add.prototype.scale = Signal.prototype.scale;\n Scale.prototype.scale = Signal.prototype.scale;\n\n});\n\n\n","define([\"Tone/core/Tone\", \"Tone/type/TimeBase\"], function (Tone) {\n\n\t/**\n\t * @class Tone.Frequency is a primitive type for encoding Frequency values. \n\t * Eventually all time values are evaluated to hertz\n\t * using the `eval` method. \n\t * @constructor\n\t * @extends {Tone.TimeBase}\n\t * @param {String|Number} val The time value.\n\t * @param {String=} units The units of the value.\n\t * @example\n\t * Tone.Frequency(\"C3\") // 261\n\t * Tone.Frequency(38, \"midi\") //\n\t * Tone.Frequency(\"C3\").transpose(4);\n\t */\n\tTone.Frequency = function(val, units){\n\t\tif (this instanceof Tone.Frequency){\n\t\t\t\n\t\t\tTone.TimeBase.call(this, val, units);\n\n\t\t} else {\n\t\t\treturn new Tone.Frequency(val, units);\n\t\t}\n\t};\n\n\tTone.extend(Tone.Frequency, Tone.TimeBase);\n\n\t///////////////////////////////////////////////////////////////////////////\n\t//\tAUGMENT BASE EXPRESSIONS\n\t///////////////////////////////////////////////////////////////////////////\n\n\t//clone the expressions so that \n\t//we can add more without modifying the original\n\tTone.Frequency.prototype._primaryExpressions = Object.create(Tone.TimeBase.prototype._primaryExpressions);\n\n\t/*\n\t * midi type primary expression\n\t * @type {Object}\n\t * @private\n\t */\n\tTone.Frequency.prototype._primaryExpressions.midi = {\n\t\tregexp : /^(\\d+(?:\\.\\d+)?midi)/,\n\t\tmethod : function(value){\n\t\t\treturn this.midiToFrequency(value);\n\t\t}\t\n\t};\n\n\t/*\n\t * note type primary expression\n\t * @type {Object}\n\t * @private\n\t */\n\tTone.Frequency.prototype._primaryExpressions.note = {\n\t\tregexp : /^([a-g]{1}(?:b|#|x|bb)?)(-?[0-9]+)/i,\n\t\tmethod : function(pitch, octave){\n\t\t\tvar index = noteToScaleIndex[pitch.toLowerCase()];\n\t\t\tvar noteNumber = index + (parseInt(octave) + 1) * 12;\n\t\t\treturn this.midiToFrequency(noteNumber);\n\t\t}\t\n\t};\n\n\t/*\n\t * BeatsBarsSixteenths type primary expression\n\t * @type {Object}\n\t * @private\n\t */\n\tTone.Frequency.prototype._primaryExpressions.tr = {\n\t\t\tregexp : /^(\\d+(?:\\.\\d+)?):(\\d+(?:\\.\\d+)?):?(\\d+(?:\\.\\d+)?)?/,\n\t\t\tmethod : function(m, q, s){\n\t\t\tvar total = 1;\n\t\t\tif (m && m !== \"0\"){\n\t\t\t\ttotal *= this._beatsToUnits(this._timeSignature() * parseFloat(m));\n\t\t\t}\n\t\t\tif (q && q !== \"0\"){\n\t\t\t\ttotal *= this._beatsToUnits(parseFloat(q));\n\t\t\t}\n\t\t\tif (s && s !== \"0\"){\n\t\t\t\ttotal *= this._beatsToUnits(parseFloat(s) / 4);\n\t\t\t}\n\t\t\treturn total;\n\t\t}\n\t};\n\n\t///////////////////////////////////////////////////////////////////////////\n\t//\tEXPRESSIONS\n\t///////////////////////////////////////////////////////////////////////////\n\n\t/**\n\t * Transposes the frequency by the given number of semitones.\n\t * @param {Interval} interval\n\t * @return {Tone.Frequency} this\n\t * @example\n\t * Tone.Frequency(\"A4\").transpose(3); //\"C5\"\n\t */\n\tTone.Frequency.prototype.transpose = function(interval){\n\t\tthis._expr = function(expr, interval){\n\t\t\tvar val = expr();\n\t\t\treturn val * this.intervalToFrequencyRatio(interval);\n\t\t}.bind(this, this._expr, interval);\n\t\treturn this;\n\t};\n\n\t/**\n\t * Takes an array of semitone intervals and returns\n\t * an array of frequencies transposed by those intervals.\n\t * @param {Array} intervals\n\t * @return {Tone.Frequency} this\n\t * @example\n\t * Tone.Frequency(\"A4\").harmonize([0, 3, 7]); //[\"A4\", \"C5\", \"E5\"]\n\t */\n\tTone.Frequency.prototype.harmonize = function(intervals){\n\t\tthis._expr = function(expr, intervals){\n\t\t\tvar val = expr();\n\t\t\tvar ret = [];\n\t\t\tfor (var i = 0; i < intervals.length; i++){\n\t\t\t\tret[i] = val * this.intervalToFrequencyRatio(intervals[i]);\n\t\t\t}\n\t\t\treturn ret;\n\t\t}.bind(this, this._expr, intervals);\n\t\treturn this;\n\t};\n\n\t///////////////////////////////////////////////////////////////////////////\n\t//\tUNIT CONVERSIONS\n\t///////////////////////////////////////////////////////////////////////////\n\n\t/**\n\t * Return the value of the frequency as a MIDI note\n\t * @return {MIDI}\n\t * @example\n\t * Tone.Frequency(\"C4\").toMidi(); //60\n\t */\n\tTone.Frequency.prototype.toMidi = function(){\n\t\treturn this.frequencyToMidi(this.valueOf());\n\t};\n\n\t/**\n\t * Return the value of the frequency in Scientific Pitch Notation\n\t * @return {Note}\n\t * @example\n\t * Tone.Frequency(69, \"midi\").toNote(); //\"A4\"\n\t */\n\tTone.Frequency.prototype.toNote = function(){\n\t\tvar freq = this.valueOf();\n\t\tvar log = Math.log(freq / Tone.Frequency.A4) / Math.LN2;\n\t\tvar noteNumber = Math.round(12 * log) + 57;\n\t\tvar octave = Math.floor(noteNumber/12);\n\t\tif(octave < 0){\n\t\t\tnoteNumber += -12 * octave;\n\t\t}\n\t\tvar noteName = scaleIndexToNote[noteNumber % 12];\n\t\treturn noteName + octave.toString();\n\t};\n\n\t/**\n\t * Return the duration of one cycle in seconds.\n\t * @return {Seconds}\n\t */\n\tTone.Frequency.prototype.toSeconds = function(){\n\t\treturn 1 / this.valueOf();\n\t};\n\n\t/**\n\t * Return the value in Hertz\n\t * @return {Frequency}\n\t */\n\tTone.Frequency.prototype.toFrequency = function(){\n\t\treturn this.valueOf();\n\t};\n\n\t/**\n\t * Return the duration of one cycle in ticks\n\t * @return {Ticks}\n\t */\n\tTone.Frequency.prototype.toTicks = function(){\n\t\tvar quarterTime = this._beatsToUnits(1);\n\t\tvar quarters = this.valueOf() / quarterTime;\n\t\treturn Math.floor(quarters * Tone.Transport.PPQ);\n\t};\n\n\t///////////////////////////////////////////////////////////////////////////\n\t//\tUNIT CONVERSIONS HELPERS\n\t///////////////////////////////////////////////////////////////////////////\n\n\t/**\n\t * Returns the value of a frequency in the current units\n\t * @param {Frequency} freq\n\t * @return {Number}\n\t * @private\n\t */\n\tTone.Frequency.prototype._frequencyToUnits = function(freq){\n\t\treturn freq;\n\t};\n\n\t/**\n\t * Returns the value of a tick in the current time units\n\t * @param {Ticks} ticks\n\t * @return {Number}\n\t * @private\n\t */\n\tTone.Frequency.prototype._ticksToUnits = function(ticks){\n\t\treturn 1 / ((ticks * 60) / (Tone.Transport.bpm.value * Tone.Transport.PPQ));\n\t};\n\n\t/**\n\t * Return the value of the beats in the current units\n\t * @param {Number} beats\n\t * @return {Number}\n\t * @private\n\t */\n\tTone.Frequency.prototype._beatsToUnits = function(beats){\n\t\treturn 1 / Tone.TimeBase.prototype._beatsToUnits.call(this, beats);\n\t};\n\n\t/**\n\t * Returns the value of a second in the current units\n\t * @param {Seconds} seconds\n\t * @return {Number}\n\t * @private\n\t */\n\tTone.Frequency.prototype._secondsToUnits = function(seconds){\n\t\treturn 1 / seconds;\n\t};\n\n\t/**\n\t * The default units if none are given.\n\t * @private\n\t */\n\tTone.Frequency.prototype._defaultUnits = \"hz\";\n\n\t///////////////////////////////////////////////////////////////////////////\n\t//\tFREQUENCY CONVERSIONS\n\t///////////////////////////////////////////////////////////////////////////\n\n\t/**\n\t * Note to scale index\n\t * @type {Object}\n\t */\n\tvar noteToScaleIndex = {\n\t\t\"cbb\" : -2, \"cb\" : -1, \"c\" : 0, \"c#\" : 1, \"cx\" : 2, \n\t\t\"dbb\" : 0, \"db\" : 1, \"d\" : 2, \"d#\" : 3, \"dx\" : 4,\n\t\t\"ebb\" : 2, \"eb\" : 3, \"e\" : 4, \"e#\" : 5, \"ex\" : 6, \n\t\t\"fbb\" : 3, \"fb\" : 4, \"f\" : 5, \"f#\" : 6, \"fx\" : 7,\n\t\t\"gbb\" : 5, \"gb\" : 6, \"g\" : 7, \"g#\" : 8, \"gx\" : 9,\n\t\t\"abb\" : 7, \"ab\" : 8, \"a\" : 9, \"a#\" : 10, \"ax\" : 11,\n\t\t\"bbb\" : 9, \"bb\" : 10, \"b\" : 11, \"b#\" : 12, \"bx\" : 13,\n\t};\n\n\t/**\n\t * scale index to note (sharps)\n\t * @type {Array}\n\t */\n\tvar scaleIndexToNote = [\"C\", \"C#\", \"D\", \"D#\", \"E\", \"F\", \"F#\", \"G\", \"G#\", \"A\", \"A#\", \"B\"];\n\n\t/**\n\t * The [concert pitch](https://en.wikipedia.org/wiki/Concert_pitch)\n\t * A4's values in Hertz. \n\t * @type {Frequency}\n\t * @static\n\t */\n\tTone.Frequency.A4 = 440;\n\n\t/**\n\t * Convert a MIDI note to frequency value. \n\t * @param {MIDI} midi The midi number to convert.\n\t * @return {Frequency} the corresponding frequency value\n\t * @example\n\t * tone.midiToFrequency(69); // returns 440\n\t */\n\tTone.Frequency.prototype.midiToFrequency = function(midi){\n\t\treturn Tone.Frequency.A4 * Math.pow(2, (midi - 69) / 12);\n\t};\n\n\t/**\n\t * Convert a frequency value to a MIDI note.\n\t * @param {Frequency} frequency The value to frequency value to convert.\n\t * @returns {MIDI}\n\t * @example\n\t * tone.midiToFrequency(440); // returns 69\n\t */\n\tTone.Frequency.prototype.frequencyToMidi = function(frequency){\n\t\treturn 69 + 12 * Math.log(frequency / Tone.Frequency.A4) / Math.LN2;\n\t};\n\n\treturn Tone.Frequency;\n});","define([\"Tone/core/Tone\", \"Tone/type/Time\"], function (Tone) {\n\n\t/**\n\t * @class Tone.TransportTime is a the time along the Transport's\n\t * timeline. It is similar to Tone.Time, but instead of evaluating\n\t * against the AudioContext's clock, it is evaluated against\n\t * the Transport's position. See [TransportTime wiki](https://github.com/Tonejs/Tone.js/wiki/TransportTime).\n\t * @constructor\n\t * @param {Time} val The time value as a number or string\n\t * @param {String=} units Unit values\n\t * @extends {Tone.Time}\n\t */\n\tTone.TransportTime = function(val, units){\n\t\tif (this instanceof Tone.TransportTime){\n\t\t\t\n\t\t\tTone.Time.call(this, val, units);\n\n\t\t} else {\n\t\t\treturn new Tone.TransportTime(val, units);\n\t\t}\n\t};\n\n\tTone.extend(Tone.TransportTime, Tone.Time);\n\n\t//clone the expressions so that \n\t//we can add more without modifying the original\n\tTone.TransportTime.prototype._unaryExpressions = Object.create(Tone.Time.prototype._unaryExpressions);\n\n\t/**\n\t * Adds an additional unary expression\n\t * which quantizes values to the next subdivision\n\t * @type {Object}\n\t * @private\n\t */\n\tTone.TransportTime.prototype._unaryExpressions.quantize = {\n\t\tregexp : /^@/,\n\t\tmethod : function(rh){\n\t\t\tvar subdivision = this._secondsToTicks(rh());\n\t\t\tvar multiple = Math.ceil(Tone.Transport.ticks / subdivision);\n\t\t\treturn this._ticksToUnits(multiple * subdivision);\n\t\t}\n\t};\n\n\t/**\n\t * Convert seconds into ticks\n\t * @param {Seconds} seconds\n\t * @return {Ticks}\n\t * @private\n\t */\n\tTone.TransportTime.prototype._secondsToTicks = function(seconds){\n\t\tvar quarterTime = this._beatsToUnits(1);\n\t\tvar quarters = seconds / quarterTime;\n\t\treturn Math.round(quarters * Tone.Transport.PPQ);\n\t};\n\n\t/**\n\t * Evaluate the time expression. Returns values in ticks\n\t * @return {Ticks}\n\t */\n\tTone.TransportTime.prototype.valueOf = function(){\n\t\tvar val = this._secondsToTicks(this._expr());\n\t\treturn val + (this._plusNow ? Tone.Transport.ticks : 0);\n\t};\n\n\t/**\n\t * Return the time in ticks.\n\t * @return {Ticks}\n\t */\n\tTone.TransportTime.prototype.toTicks = function(){\n\t\treturn this.valueOf();\n\t};\n\n\t/**\n\t * Return the time in seconds.\n\t * @return {Seconds}\n\t */\n\tTone.TransportTime.prototype.toSeconds = function(){\n\t\tvar val = this._expr();\n\t\treturn val + (this._plusNow ? Tone.Transport.seconds : 0);\n\t};\n\n\t/**\n\t * Return the time as a frequency value\n\t * @return {Frequency} \n\t */\n\tTone.TransportTime.prototype.toFrequency = function(){\n\t\treturn 1/this.toSeconds();\n\t};\n\n\treturn Tone.TransportTime;\n});","'use strict';\n\ndefine(function (require) {\n\n var p5sound = require('master');\n var Add = require('Tone/signal/Add');\n var Mult = require('Tone/signal/Multiply');\n var Scale = require('Tone/signal/Scale');\n var TimelineSignal = require('Tone/signal/TimelineSignal');\n\n /**\n *
Envelopes are pre-defined amplitude distribution over time.\n * Typically, envelopes are used to control the output volume\n * of an object, a series of fades referred to as Attack, Decay,\n * Sustain and Release (\n * ADSR\n * ). Envelopes can also control other Web Audio Parameters—for example, a p5.Envelope can\n * control an Oscillator's frequency like this: osc.freq(env).
\n *
Use setRange to change the attack/release level.\n * Use setADSR to change attackTime, decayTime, sustainPercent and releaseTime.
\n *
Use the play method to play the entire envelope,\n * the ramp method for a pingable trigger,\n * or triggerAttack/\n * triggerRelease to trigger noteOn/noteOff.
\n * var attackLevel = 1.0;\n * var releaseLevel = 0;\n *\n * var attackTime = 0.001;\n * var decayTime = 0.2;\n * var susPercent = 0.2;\n * var releaseTime = 0.5;\n *\n * var env, triOsc;\n *\n * function setup() {\n * var cnv = createCanvas(100, 100);\n *\n * textAlign(CENTER);\n * text('click to play', width/2, height/2);\n *\n * env = new p5.Envelope();\n * env.setADSR(attackTime, decayTime, susPercent, releaseTime);\n * env.setRange(attackLevel, releaseLevel);\n *\n * triOsc = new p5.Oscillator('triangle');\n * triOsc.amp(env);\n * triOsc.start();\n * triOsc.freq(220);\n *\n * cnv.mousePressed(playEnv);\n * }\n *\n * function playEnv() {\n * env.play();\n * }\n *
\n */\n p5.Envelope = function(t1, l1, t2, l2, t3, l3) {\n /**\n * Time until envelope reaches attackLevel\n * @property attackTime\n */\n this.aTime = t1 || 0.1;\n /**\n * Level once attack is complete.\n * @property attackLevel\n */\n this.aLevel = l1 || 1;\n /**\n * Time until envelope reaches decayLevel.\n * @property decayTime\n */\n this.dTime = t2 || 0.5;\n /**\n * Level after decay. The envelope will sustain here until it is released.\n * @property decayLevel\n */\n this.dLevel = l2 || 0;\n /**\n * Duration of the release portion of the envelope.\n * @property releaseTime\n */\n this.rTime = t3 || 0;\n /**\n * Level at the end of the release.\n * @property releaseLevel\n */\n this.rLevel = l3 || 0;\n\n this._rampHighPercentage = 0.98;\n\n this._rampLowPercentage = 0.02;\n\n\n this.output = p5sound.audiocontext.createGain();\n\n this.control = new TimelineSignal();\n\n this._init(); // this makes sure the envelope starts at zero\n\n this.control.connect(this.output); // connect to the output\n\n this.connection = null; // store connection\n\n //array of math operation signal chaining\n this.mathOps = [this.control];\n\n //whether envelope should be linear or exponential curve\n this.isExponential = false;\n\n // oscillator or buffer source to clear on env complete\n // to save resources if/when it is retriggered\n this.sourceToClear = null;\n\n // set to true if attack is set, then false on release\n this.wasTriggered = false;\n\n\n // add to the soundArray so we can dispose of the env later\n p5sound.soundArray.push(this);\n };\n\n // this init function just smooths the starting value to zero and gives a start point for the timeline\n // - it was necessary to remove glitches at the beginning.\n p5.Envelope.prototype._init = function () {\n var now = p5sound.audiocontext.currentTime;\n var t = now;\n this.control.setTargetAtTime(0.00001, t, .001);\n //also, compute the correct time constants\n this._setRampAD(this.aTime, this.dTime);\n };\n\n /**\n * Reset the envelope with a series of time/value pairs.\n *\n * @method set\n * @for p5.Envelope\n * @param {Number} attackTime Time (in seconds) before level\n * reaches attackLevel\n * @param {Number} attackLevel Typically an amplitude between\n * 0.0 and 1.0\n * @param {Number} decayTime Time\n * @param {Number} decayLevel Amplitude (In a standard ADSR envelope,\n * decayLevel = sustainLevel)\n * @param {Number} releaseTime Release Time (in seconds)\n * @param {Number} releaseLevel Amplitude\n * @example\n *
\n * var t1 = 0.1; // attack time in seconds\n * var l1 = 0.7; // attack level 0.0 to 1.0\n * var t2 = 0.3; // decay time in seconds\n * var l2 = 0.1; // decay level 0.0 to 1.0\n * var t3 = 0.2; // sustain time in seconds\n * var l3 = 0.5; // sustain level 0.0 to 1.0\n * // release level defaults to zero\n *\n * var env;\n * var triOsc;\n *\n * function setup() {\n * background(0);\n * noStroke();\n * fill(255);\n * textAlign(CENTER);\n * text('click to play', width/2, height/2);\n *\n * env = new p5.Envelope(t1, l1, t2, l2, t3, l3);\n * triOsc = new p5.Oscillator('triangle');\n * triOsc.amp(env); // give the env control of the triOsc's amp\n * triOsc.start();\n * }\n *\n * // mouseClick triggers envelope if over canvas\n * function mouseClicked() {\n * // is mouse over canvas?\n * if (mouseX > 0 && mouseX < width && mouseY > 0 && mouseY < height) {\n * env.play(triOsc);\n * }\n * }\n *
\n *\n */\n p5.Envelope.prototype.set = function(t1, l1, t2, l2, t3, l3) {\n this.aTime = t1;\n this.aLevel = l1;\n this.dTime = t2 || 0;\n this.dLevel = l2 || 0;\n this.rTime = t3 || 0;\n this.rLevel = l3 || 0;\n\n // set time constants for ramp\n this._setRampAD(t1, t2);\n };\n\n /**\n * Set values like a traditional\n * \n * ADSR envelope\n * .\n *\n * @method setADSR\n * @for p5.Envelope\n * @param {Number} attackTime Time (in seconds before envelope\n * reaches Attack Level\n * @param {Number} [decayTime] Time (in seconds) before envelope\n * reaches Decay/Sustain Level\n * @param {Number} [susRatio] Ratio between attackLevel and releaseLevel, on a scale from 0 to 1,\n * where 1.0 = attackLevel, 0.0 = releaseLevel.\n * The susRatio determines the decayLevel and the level at which the\n * sustain portion of the envelope will sustain.\n * For example, if attackLevel is 0.4, releaseLevel is 0,\n * and susAmt is 0.5, the decayLevel would be 0.2. If attackLevel is\n * increased to 1.0 (using setRange),\n * then decayLevel would increase proportionally, to become 0.5.\n * @param {Number} [releaseTime] Time in seconds from now (defaults to 0)\n * @example\n *
\n * var attackLevel = 1.0;\n * var releaseLevel = 0;\n *\n * var attackTime = 0.001;\n * var decayTime = 0.2;\n * var susPercent = 0.2;\n * var releaseTime = 0.5;\n *\n * var env, triOsc;\n *\n * function setup() {\n * var cnv = createCanvas(100, 100);\n *\n * textAlign(CENTER);\n * text('click to play', width/2, height/2);\n *\n * env = new p5.Envelope();\n * env.setADSR(attackTime, decayTime, susPercent, releaseTime);\n * env.setRange(attackLevel, releaseLevel);\n *\n * triOsc = new p5.Oscillator('triangle');\n * triOsc.amp(env);\n * triOsc.start();\n * triOsc.freq(220);\n *\n * cnv.mousePressed(playEnv);\n * }\n *\n * function playEnv() {\n * env.play();\n * }\n *
\n */\n p5.Envelope.prototype.setADSR = function(aTime, dTime, sPercent, rTime) {\n this.aTime = aTime;\n this.dTime = dTime || 0;\n\n // lerp\n this.sPercent = sPercent || 0;\n this.dLevel = typeof sPercent !== 'undefined' ? sPercent * (this.aLevel - this.rLevel) + this.rLevel : 0;\n\n this.rTime = rTime || 0;\n\n // also set time constants for ramp\n this._setRampAD(aTime, dTime);\n };\n\n /**\n * Set max (attackLevel) and min (releaseLevel) of envelope.\n *\n * @method setRange\n * @for p5.Envelope\n * @param {Number} aLevel attack level (defaults to 1)\n * @param {Number} rLevel release level (defaults to 0)\n * @example\n *
\n * var attackLevel = 1.0;\n * var releaseLevel = 0;\n *\n * var attackTime = 0.001;\n * var decayTime = 0.2;\n * var susPercent = 0.2;\n * var releaseTime = 0.5;\n *\n * var env, triOsc;\n *\n * function setup() {\n * var cnv = createCanvas(100, 100);\n *\n * textAlign(CENTER);\n * text('click to play', width/2, height/2);\n *\n * env = new p5.Envelope();\n * env.setADSR(attackTime, decayTime, susPercent, releaseTime);\n * env.setRange(attackLevel, releaseLevel);\n *\n * triOsc = new p5.Oscillator('triangle');\n * triOsc.amp(env);\n * triOsc.start();\n * triOsc.freq(220);\n *\n * cnv.mousePressed(playEnv);\n * }\n *\n * function playEnv() {\n * env.play();\n * }\n *
\n */\n p5.Envelope.prototype.setRange = function(aLevel, rLevel) {\n this.aLevel = aLevel || 1;\n this.rLevel = rLevel || 0;\n\n // not sure if this belongs here:\n\n // {Number} [dLevel] decay/sustain level (optional)\n // if (typeof(dLevel) !== 'undefined') {\n // this.dLevel = dLevel\n // } else if (this.sPercent) {\n // this.dLevel = this.sPercent ? this.sPercent * (this.aLevel - this.rLevel) + this.rLevel : 0;\n // }\n };\n\n // private (undocumented) method called when ADSR is set to set time constants for ramp\n //\n // Set the \n // time constants for simple exponential ramps.\n // The larger the time constant value, the slower the\n // transition will be.\n //\n // method _setRampAD\n // param {Number} attackTimeConstant attack time constant\n // param {Number} decayTimeConstant decay time constant\n //\n p5.Envelope.prototype._setRampAD = function(t1, t2) {\n this._rampAttackTime = this.checkExpInput(t1);\n this._rampDecayTime = this.checkExpInput(t2);\n\n var TCDenominator = 1.0;\n /// Aatish Bhatia's calculation for time constant for rise(to adjust 1/1-e calculation to any percentage)\n TCDenominator = Math.log(1.0 / this.checkExpInput(1.0 - this._rampHighPercentage));\n this._rampAttackTC = t1 / this.checkExpInput(TCDenominator);\n TCDenominator = Math.log(1.0 / this._rampLowPercentage);\n this._rampDecayTC = t2 / this.checkExpInput(TCDenominator);\n };\n\n // private method\n p5.Envelope.prototype.setRampPercentages = function(p1, p2) {\n //set the percentages that the simple exponential ramps go to\n this._rampHighPercentage = this.checkExpInput(p1);\n this._rampLowPercentage = this.checkExpInput(p2);\n var TCDenominator = 1.0;\n //now re-compute the time constants based on those percentages\n /// Aatish Bhatia's calculation for time constant for rise(to adjust 1/1-e calculation to any percentage)\n TCDenominator = Math.log(1.0 / this.checkExpInput(1.0 - this._rampHighPercentage));\n this._rampAttackTC = this._rampAttackTime / this.checkExpInput(TCDenominator);\n TCDenominator = Math.log(1.0 / this._rampLowPercentage);\n this._rampDecayTC = this._rampDecayTime / this.checkExpInput(TCDenominator);\n };\n\n\n /**\n * Assign a parameter to be controlled by this envelope.\n * If a p5.Sound object is given, then the p5.Envelope will control its\n * output gain. If multiple inputs are provided, the env will\n * control all of them.\n *\n * @method setInput\n * @for p5.Envelope\n * @param {Object} [...inputs] A p5.sound object or\n * Web Audio Param.\n */\n p5.Envelope.prototype.setInput = function() {\n for (var i = 0; i\n * Web Audio Audio Param.\n *\n * @method play\n * @for p5.Envelope\n * @param {Object} unit A p5.sound object or\n * Web Audio Param.\n * @param {Number} [startTime] time from now (in seconds) at which to play\n * @param {Number} [sustainTime] time to sustain before releasing the envelope\n * @example\n *
\n * var attackLevel = 1.0;\n * var releaseLevel = 0;\n *\n * var attackTime = 0.001;\n * var decayTime = 0.2;\n * var susPercent = 0.2;\n * var releaseTime = 0.5;\n *\n * var env, triOsc;\n *\n * function setup() {\n * var cnv = createCanvas(100, 100);\n *\n * textAlign(CENTER);\n * text('click to play', width/2, height/2);\n *\n * env = new p5.Envelope();\n * env.setADSR(attackTime, decayTime, susPercent, releaseTime);\n * env.setRange(attackLevel, releaseLevel);\n *\n * triOsc = new p5.Oscillator('triangle');\n * triOsc.amp(env);\n * triOsc.start();\n * triOsc.freq(220);\n *\n * cnv.mousePressed(playEnv);\n * }\n *\n * function playEnv() {\n * // trigger env on triOsc, 0 seconds from now\n * // After decay, sustain for 0.2 seconds before release\n * env.play(triOsc, 0, 0.2);\n * }\n *
\n */\n p5.Envelope.prototype.play = function(unit, secondsFromNow, susTime) {\n var tFromNow = secondsFromNow || 0;\n var susTime = susTime || 0;\n\n if (unit) {\n if (this.connection !== unit) {\n this.connect(unit);\n }\n }\n\n this.triggerAttack(unit, tFromNow);\n\n this.triggerRelease(unit, tFromNow + this.aTime + this.dTime + susTime);\n\n };\n\n /**\n * Trigger the Attack, and Decay portion of the Envelope.\n * Similar to holding down a key on a piano, but it will\n * hold the sustain level until you let go. Input can be\n * any p5.sound object, or a \n * Web Audio Param.\n *\n * @method triggerAttack\n * @for p5.Envelope\n * @param {Object} unit p5.sound Object or Web Audio Param\n * @param {Number} secondsFromNow time from now (in seconds)\n * @example\n *
\n *\n * var attackLevel = 1.0;\n * var releaseLevel = 0;\n *\n * var attackTime = 0.001;\n * var decayTime = 0.3;\n * var susPercent = 0.4;\n * var releaseTime = 0.5;\n *\n * var env, triOsc;\n *\n * function setup() {\n * var cnv = createCanvas(100, 100);\n * background(200);\n * textAlign(CENTER);\n * text('click to play', width/2, height/2);\n *\n * env = new p5.Envelope();\n * env.setADSR(attackTime, decayTime, susPercent, releaseTime);\n * env.setRange(attackLevel, releaseLevel);\n *\n * triOsc = new p5.Oscillator('triangle');\n * triOsc.amp(env);\n * triOsc.start();\n * triOsc.freq(220);\n *\n * cnv.mousePressed(envAttack);\n * }\n *\n * function envAttack() {\n * console.log('trigger attack');\n * env.triggerAttack();\n *\n * background(0,255,0);\n * text('attack!', width/2, height/2);\n * }\n *\n * function mouseReleased() {\n * env.triggerRelease();\n *\n * background(200);\n * text('click to play', width/2, height/2);\n * }\n *
\n */\n p5.Envelope.prototype.triggerAttack = function(unit, secondsFromNow) {\n var now = p5sound.audiocontext.currentTime;\n var tFromNow = secondsFromNow || 0;\n var t = now + tFromNow;\n this.lastAttack = t;\n this.wasTriggered = true;\n\n if (unit) {\n if (this.connection !== unit) {\n this.connect(unit);\n }\n }\n\n // get and set value (with linear ramp) to anchor automation\n var valToSet = this.control.getValueAtTime(t);\n\n if (this.isExponential === true)\n {\n this.control.exponentialRampToValueAtTime(this.checkExpInput(valToSet), t);\n }\n else\n {\n this.control.linearRampToValueAtTime(valToSet, t);\n }\n\n // after each ramp completes, cancel scheduled values\n // (so they can be overridden in case env has been re-triggered)\n // then, set current value (with linearRamp to avoid click)\n // then, schedule the next automation...\n\n // attack\n t += this.aTime;\n if (this.isExponential === true)\n {\n this.control.exponentialRampToValueAtTime(this.checkExpInput(this.aLevel), t);\n valToSet = this.checkExpInput(this.control.getValueAtTime(t));\n this.control.cancelScheduledValues(t);\n this.control.exponentialRampToValueAtTime(valToSet, t);\n }\n else\n {\n this.control.linearRampToValueAtTime(this.aLevel, t);\n valToSet = this.control.getValueAtTime(t);\n this.control.cancelScheduledValues(t);\n this.control.linearRampToValueAtTime(valToSet, t);\n\n }\n\n // decay to decay level (if using ADSR, then decay level == sustain level)\n t += this.dTime;\n if (this.isExponential === true)\n {\n this.control.exponentialRampToValueAtTime(this.checkExpInput(this.dLevel), t);\n valToSet = this.checkExpInput(this.control.getValueAtTime(t));\n this.control.cancelScheduledValues(t);\n this.control.exponentialRampToValueAtTime(valToSet, t);\n }\n else\n {\n this.control.linearRampToValueAtTime(this.dLevel, t);\n valToSet = this.control.getValueAtTime(t);\n this.control.cancelScheduledValues(t);\n this.control.linearRampToValueAtTime(valToSet, t);\n }\n };\n\n /**\n * Trigger the Release of the Envelope. This is similar to releasing\n * the key on a piano and letting the sound fade according to the\n * release level and release time.\n *\n * @method triggerRelease\n * @for p5.Envelope\n * @param {Object} unit p5.sound Object or Web Audio Param\n * @param {Number} secondsFromNow time to trigger the release\n * @example\n *
\n *\n * var attackLevel = 1.0;\n * var releaseLevel = 0;\n *\n * var attackTime = 0.001;\n * var decayTime = 0.3;\n * var susPercent = 0.4;\n * var releaseTime = 0.5;\n *\n * var env, triOsc;\n *\n * function setup() {\n * var cnv = createCanvas(100, 100);\n * background(200);\n * textAlign(CENTER);\n * text('click to play', width/2, height/2);\n *\n * env = new p5.Envelope();\n * env.setADSR(attackTime, decayTime, susPercent, releaseTime);\n * env.setRange(attackLevel, releaseLevel);\n *\n * triOsc = new p5.Oscillator('triangle');\n * triOsc.amp(env);\n * triOsc.start();\n * triOsc.freq(220);\n *\n * cnv.mousePressed(envAttack);\n * }\n *\n * function envAttack() {\n * console.log('trigger attack');\n * env.triggerAttack();\n *\n * background(0,255,0);\n * text('attack!', width/2, height/2);\n * }\n *\n * function mouseReleased() {\n * env.triggerRelease();\n *\n * background(200);\n * text('click to play', width/2, height/2);\n * }\n *
\n */\n p5.Envelope.prototype.triggerRelease = function(unit, secondsFromNow) {\n\n // only trigger a release if an attack was triggered\n if (!this.wasTriggered) {\n // this currently causes a bit of trouble:\n // if a later release has been scheduled (via the play function)\n // a new earlier release won't interrupt it, because\n // this.wasTriggered has already been set to false.\n // If we want new earlier releases to override, then we need to\n // keep track of the last release time, and if the new release time is\n // earlier, then use it.\n return;\n }\n\n var now = p5sound.audiocontext.currentTime;\n var tFromNow = secondsFromNow || 0;\n var t = now + tFromNow;\n\n if (unit) {\n if (this.connection !== unit) {\n this.connect(unit);\n }\n }\n\n // get and set value (with linear or exponential ramp) to anchor automation\n var valToSet = this.control.getValueAtTime(t);\n if (this.isExponential === true)\n {\n this.control.exponentialRampToValueAtTime(this.checkExpInput(valToSet), t);\n }\n else\n {\n this.control.linearRampToValueAtTime(valToSet, t);\n }\n\n // release\n t += this.rTime;\n\n if (this.isExponential === true)\n {\n this.control.exponentialRampToValueAtTime(this.checkExpInput(this.rLevel), t);\n valToSet = this.checkExpInput(this.control.getValueAtTime(t));\n this.control.cancelScheduledValues(t);\n this.control.exponentialRampToValueAtTime(valToSet, t);\n }\n else\n {\n this.control.linearRampToValueAtTime(this.rLevel, t);\n valToSet = this.control.getValueAtTime(t);\n this.control.cancelScheduledValues(t);\n this.control.linearRampToValueAtTime(valToSet, t);\n }\n\n this.wasTriggered = false;\n };\n\n /**\n * Exponentially ramp to a value using the first two\n * values from setADSR(attackTime, decayTime)\n * as \n * time constants for simple exponential ramps.\n * If the value is higher than current value, it uses attackTime,\n * while a decrease uses decayTime.\n *\n * @method ramp\n * @for p5.Envelope\n * @param {Object} unit p5.sound Object or Web Audio Param\n * @param {Number} secondsFromNow When to trigger the ramp\n * @param {Number} v Target value\n * @param {Number} [v2] Second target value (optional)\n * @example\n *
\n * var env, osc, amp, cnv;\n *\n * var attackTime = 0.001;\n * var decayTime = 0.2;\n * var attackLevel = 1;\n * var decayLevel = 0;\n *\n * function setup() {\n * cnv = createCanvas(100, 100);\n * fill(0,255,0);\n * noStroke();\n *\n * env = new p5.Envelope();\n * env.setADSR(attackTime, decayTime);\n *\n * osc = new p5.Oscillator();\n * osc.amp(env);\n * osc.start();\n *\n * amp = new p5.Amplitude();\n *\n * cnv.mousePressed(triggerRamp);\n * }\n *\n * function triggerRamp() {\n * env.ramp(osc, 0, attackLevel, decayLevel);\n * }\n *\n * function draw() {\n * background(20,20,20);\n * text('click me', 10, 20);\n * var h = map(amp.getLevel(), 0, 0.4, 0, height);;\n *\n * rect(0, height, width, -h);\n * }\n *
\n */\n p5.Envelope.prototype.ramp = function(unit, secondsFromNow, v1, v2) {\n\n var now = p5sound.audiocontext.currentTime;\n var tFromNow = secondsFromNow || 0;\n var t = now + tFromNow;\n var destination1 = this.checkExpInput(v1);\n var destination2 = typeof v2 !== 'undefined' ? this.checkExpInput(v2) : undefined;\n\n // connect env to unit if not already connected\n if (unit) {\n if (this.connection !== unit) {\n this.connect(unit);\n }\n }\n\n //get current value\n var currentVal = this.checkExpInput(this.control.getValueAtTime(t));\n // this.control.cancelScheduledValues(t);\n\n //if it's going up\n if (destination1 > currentVal) {\n this.control.setTargetAtTime(destination1, t, this._rampAttackTC);\n t += this._rampAttackTime;\n }\n\n //if it's going down\n else if (destination1 < currentVal) {\n this.control.setTargetAtTime(destination1, t, this._rampDecayTC);\n t += this._rampDecayTime;\n }\n\n // Now the second part of envelope begins\n if (destination2 === undefined) return;\n\n //if it's going up\n if (destination2 > destination1) {\n this.control.setTargetAtTime(destination2, t, this._rampAttackTC);\n }\n\n //if it's going down\n else if (destination2 < destination1) {\n this.control.setTargetAtTime(destination2, t, this._rampDecayTC);\n }\n };\n\n\n p5.Envelope.prototype.connect = function(unit) {\n this.connection = unit;\n\n // assume we're talking about output gain\n // unless given a different audio param\n if (unit instanceof p5.Oscillator ||\n unit instanceof p5.SoundFile ||\n unit instanceof p5.AudioIn ||\n unit instanceof p5.Reverb ||\n unit instanceof p5.Noise ||\n unit instanceof p5.Filter ||\n unit instanceof p5.Delay\n ) {\n unit = unit.output.gain;\n }\n if (unit instanceof AudioParam) {\n //set the initial value\n unit.setValueAtTime(0, p5sound.audiocontext.currentTime);\n }\n if (unit instanceof p5.Signal) {\n unit.setValue(0);\n }\n this.output.connect(unit);\n };\n\n p5.Envelope.prototype.disconnect = function() {\n if (this.output) {\n this.output.disconnect();\n }\n };\n\n\n // Signal Math\n\n /**\n * Add a value to the p5.Oscillator's output amplitude,\n * and return the oscillator. Calling this method\n * again will override the initial add() with new values.\n *\n * @method add\n * @for p5.Envelope\n * @param {Number} number Constant number to add\n * @return {p5.Envelope} Envelope Returns this envelope\n * with scaled output\n */\n p5.Envelope.prototype.add = function(num) {\n var add = new Add(num);\n var thisChain = this.mathOps.length;\n var nextChain = this.output;\n return p5.prototype._mathChain(this, add, thisChain, nextChain, Add);\n };\n\n /**\n * Multiply the p5.Envelope's output amplitude\n * by a fixed value. Calling this method\n * again will override the initial mult() with new values.\n *\n * @method mult\n * @for p5.Envelope\n * @param {Number} number Constant number to multiply\n * @return {p5.Envelope} Envelope Returns this envelope\n * with scaled output\n */\n p5.Envelope.prototype.mult = function(num) {\n var mult = new Mult(num);\n var thisChain = this.mathOps.length;\n var nextChain = this.output;\n return p5.prototype._mathChain(this, mult, thisChain, nextChain, Mult);\n };\n\n /**\n * Scale this envelope's amplitude values to a given\n * range, and return the envelope. Calling this method\n * again will override the initial scale() with new values.\n *\n * @method scale\n * @for p5.Envelope\n * @param {Number} inMin input range minumum\n * @param {Number} inMax input range maximum\n * @param {Number} outMin input range minumum\n * @param {Number} outMax input range maximum\n * @return {p5.Envelope} Envelope Returns this envelope\n * with scaled output\n */\n p5.Envelope.prototype.scale = function(inMin, inMax, outMin, outMax) {\n var scale = new Scale(inMin, inMax, outMin, outMax);\n var thisChain = this.mathOps.length;\n var nextChain = this.output;\n return p5.prototype._mathChain(this, scale, thisChain, nextChain, Scale);\n };\n\n\n // get rid of the oscillator\n p5.Envelope.prototype.dispose = function() {\n // remove reference from soundArray\n var index = p5sound.soundArray.indexOf(this);\n p5sound.soundArray.splice(index, 1);\n\n this.disconnect();\n if (this.control) {\n this.control.dispose();\n this.control = null;\n }\n for (var i = 1; i < this.mathOps.length; i++) {\n this.mathOps[i].dispose();\n }\n };\n\n // Different name for backwards compatibility, replicates p5.Envelope class\n p5.Env = function(t1, l1, t2, l2, t3, l3) {\n console.warn('WARNING: p5.Env is now deprecated and may be removed in future versions. ' +\n 'Please use the new p5.Envelope instead.');\n p5.Envelope.call(this, t1, l1, t2, l2, t3, l3);\n };\n p5.Env.prototype = Object.create(p5.Envelope.prototype);\n\n});\n","'use strict';\n\ndefine(function (require) {\n\n var p5sound = require('master');\n require('oscillator');\n\n /**\n * Creates a Pulse object, an oscillator that implements\n * Pulse Width Modulation.\n * The pulse is created with two oscillators.\n * Accepts a parameter for frequency, and to set the\n * width between the pulses. See \n * p5.Oscillator for a full list of methods.\n *\n * @class p5.Pulse\n * @extends p5.Oscillator\n * @constructor\n * @param {Number} [freq] Frequency in oscillations per second (Hz)\n * @param {Number} [w] Width between the pulses (0 to 1.0,\n * defaults to 0)\n * @example\n *
Note: This uses the getUserMedia/\n * Stream API, which is not supported by certain browsers. Access in Chrome browser\n * is limited to localhost and https, but access over http may be limited.
\n *\n * @class p5.AudioIn\n * @constructor\n * @param {Function} [errorCallback] A function to call if there is an error\n * accessing the AudioIn. For example,\n * Safari and iOS devices do not\n * currently allow microphone access.\n * @example\n *
\n * var mic;\n * function setup(){\n * mic = new p5.AudioIn()\n * mic.start();\n * }\n * function draw(){\n * background(0);\n * micLevel = mic.getLevel();\n * ellipse(width/2, constrain(height-micLevel*height*5, 0, height), 10, 10);\n * }\n *
\n */\n p5.AudioIn = function(errorCallback) {\n // set up audio input\n /**\n * @property {GainNode} input\n */\n this.input = p5sound.audiocontext.createGain();\n /**\n * @property {GainNode} output\n */\n this.output = p5sound.audiocontext.createGain();\n\n /**\n * @property {MediaStream|null} stream\n */\n this.stream = null;\n /**\n * @property {MediaStreamAudioSourceNode|null} mediaStream\n */\n this.mediaStream = null;\n /**\n * @property {Number|null} currentSource\n */\n this.currentSource = null;\n\n /**\n * Client must allow browser to access their microphone / audioin source.\n * Default: false. Will become true when the client enables acces.\n *\n * @property {Boolean} enabled\n */\n this.enabled = false;\n\n /**\n * Input amplitude, connect to it by default but not to master out\n *\n * @property {p5.Amplitude} amplitude\n */\n this.amplitude = new p5.Amplitude();\n this.output.connect(this.amplitude.input);\n\n if (!window.MediaStreamTrack || !window.navigator.mediaDevices || !window.navigator.mediaDevices.getUserMedia) {\n errorCallback ? errorCallback() : window.alert('This browser does not support MediaStreamTrack and mediaDevices');\n }\n\n // add to soundArray so we can dispose on close\n p5sound.soundArray.push(this);\n };\n\n /**\n * Start processing audio input. This enables the use of other\n * AudioIn methods like getLevel(). Note that by default, AudioIn\n * is not connected to p5.sound's output. So you won't hear\n * anything unless you use the connect() method. \n *\n * Certain browsers limit access to the user's microphone. For example,\n * Chrome only allows access from localhost and over https. For this reason,\n * you may want to include an errorCallback—a function that is called in case\n * the browser won't provide mic access.\n *\n * @method start\n * @for p5.AudioIn\n * @param {Function} [successCallback] Name of a function to call on\n * success.\n * @param {Function} [errorCallback] Name of a function to call if\n * there was an error. For example,\n * some browsers do not support\n * getUserMedia.\n */\n p5.AudioIn.prototype.start = function(successCallback, errorCallback) {\n var self = this;\n\n if (this.stream) {\n this.stop();\n }\n\n // set the audio source\n var audioSource = p5sound.inputSources[self.currentSource];\n var constraints = {\n audio: {\n sampleRate: p5sound.audiocontext.sampleRate,\n echoCancellation: false\n }\n };\n\n // if developers determine which source to use\n if (p5sound.inputSources[this.currentSource]) {\n constraints.audio.deviceId = audioSource.deviceId;\n }\n\n window.navigator.mediaDevices.getUserMedia( constraints )\n .then( function(stream) {\n self.stream = stream;\n self.enabled = true;\n // Wrap a MediaStreamSourceNode around the live input\n self.mediaStream = p5sound.audiocontext.createMediaStreamSource(stream);\n self.mediaStream.connect(self.output);\n // only send to the Amplitude reader, so we can see it but not hear it.\n self.amplitude.setInput(self.output);\n if (successCallback) successCallback();\n })\n .catch( function(err) {\n if (errorCallback) errorCallback(err);\n else console.error(err);\n });\n };\n\n /**\n * Turn the AudioIn off. If the AudioIn is stopped, it cannot getLevel().\n * If re-starting, the user may be prompted for permission access.\n *\n * @method stop\n * @for p5.AudioIn\n */\n p5.AudioIn.prototype.stop = function() {\n if (this.stream) {\n this.stream.getTracks().forEach(function(track) {\n track.stop();\n });\n\n this.mediaStream.disconnect();\n\n delete this.mediaStream;\n delete this.stream;\n }\n };\n\n /**\n * Connect to an audio unit. If no parameter is provided, will\n * connect to the master output (i.e. your speakers). \n *\n * @method connect\n * @for p5.AudioIn\n * @param {Object} [unit] An object that accepts audio input,\n * such as an FFT\n */\n p5.AudioIn.prototype.connect = function(unit) {\n if (unit) {\n if (unit.hasOwnProperty('input')) {\n this.output.connect(unit.input);\n }\n else if (unit.hasOwnProperty('analyser')) {\n this.output.connect(unit.analyser);\n }\n else {\n this.output.connect(unit);\n }\n }\n else {\n this.output.connect(p5sound.input);\n }\n };\n\n /**\n * Disconnect the AudioIn from all audio units. For example, if\n * connect() had been called, disconnect() will stop sending\n * signal to your speakers. \n *\n * @method disconnect\n * @for p5.AudioIn\n */\n p5.AudioIn.prototype.disconnect = function() {\n if (this.output) {\n this.output.disconnect();\n // stay connected to amplitude even if not outputting to p5\n this.output.connect(this.amplitude.input);\n }\n };\n\n /**\n * Read the Amplitude (volume level) of an AudioIn. The AudioIn\n * class contains its own instance of the Amplitude class to help\n * make it easy to get a microphone's volume level. Accepts an\n * optional smoothing value (0.0 < 1.0). NOTE: AudioIn must\n * .start() before using .getLevel(). \n *\n * @method getLevel\n * @for p5.AudioIn\n * @param {Number} [smoothing] Smoothing is 0.0 by default.\n * Smooths values based on previous values.\n * @return {Number} Volume level (between 0.0 and 1.0)\n */\n p5.AudioIn.prototype.getLevel = function(smoothing) {\n if (smoothing) {\n this.amplitude.smoothing = smoothing;\n }\n return this.amplitude.getLevel();\n };\n\n /**\n * Set amplitude (volume) of a mic input between 0 and 1.0. \n *\n * @method amp\n * @for p5.AudioIn\n * @param {Number} vol between 0 and 1.0\n * @param {Number} [time] ramp time (optional)\n */\n p5.AudioIn.prototype.amp = function(vol, t) {\n if (t) {\n var rampTime = t || 0;\n var currentVol = this.output.gain.value;\n this.output.gain.cancelScheduledValues(p5sound.audiocontext.currentTime);\n this.output.gain.setValueAtTime(currentVol, p5sound.audiocontext.currentTime);\n this.output.gain.linearRampToValueAtTime(vol, rampTime + p5sound.audiocontext.currentTime);\n } else {\n this.output.gain.cancelScheduledValues(p5sound.audiocontext.currentTime);\n this.output.gain.setValueAtTime(vol, p5sound.audiocontext.currentTime);\n }\n };\n\n /**\n * Returns a list of available input sources. This is a wrapper\n * for and it returns a Promise.\n *\n * @method getSources\n * @for p5.AudioIn\n * @param {Function} [successCallback] This callback function handles the sources when they\n * have been enumerated. The callback function\n * receives the deviceList array as its only argument\n * @param {Function} [errorCallback] This optional callback receives the error\n * message as its argument.\n * @returns {Promise} Returns a Promise that can be used in place of the callbacks, similar\n * to the enumerateDevices() method\n * @example\n *
\n */\n p5.AudioIn.prototype.getSources = function (onSuccess, onError) {\n return new Promise( function(resolve, reject) {\n window.navigator.mediaDevices.enumerateDevices()\n .then( function(devices) {\n p5sound.inputSources = devices.filter(function(device) {\n return device.kind === 'audioinput';\n });\n resolve(p5sound.inputSources);\n if (onSuccess) {\n onSuccess(p5sound.inputSources);\n }\n })\n .catch( function(error) {\n reject(error);\n if (onError) {\n onError(error);\n } else {\n console.error('This browser does not support MediaStreamTrack.getSources()');\n }\n });\n });\n };\n\n /**\n * Set the input source. Accepts a number representing a\n * position in the array returned by getSources().\n * This is only available in browsers that support\n * navigator.mediaDevices.enumerateDevices(). \n *\n * @method setSource\n * @for p5.AudioIn\n * @param {number} num position of input source in the array\n */\n p5.AudioIn.prototype.setSource = function(num) {\n if (p5sound.inputSources.length > 0 && num < p5sound.inputSources.length) {\n // set the current source\n this.currentSource = num;\n console.log('set source to ', p5sound.inputSources[this.currentSource]);\n } else {\n console.log('unable to set input source');\n }\n\n // restart stream if currently active\n if (this.stream && this.stream.active) {\n this.start();\n }\n };\n\n // private method\n p5.AudioIn.prototype.dispose = function() {\n // remove reference from soundArray\n var index = p5sound.soundArray.indexOf(this);\n p5sound.soundArray.splice(index, 1);\n\n this.stop();\n\n if (this.output) {\n this.output.disconnect();\n }\n if (this.amplitude) {\n this.amplitude.disconnect();\n }\n delete this.amplitude;\n delete this.output;\n };\n\n});\n","define([\"Tone/core/Tone\", \"Tone/signal/Signal\", \"Tone/signal/Expr\", \n\t\"Tone/signal/EqualPowerGain\", \"Tone/core/Gain\"], function(Tone){\n\n\t\"use strict\";\n\n\t/**\n\t * @class Tone.Crossfade provides equal power fading between two inputs. \n\t * More on crossfading technique [here](https://en.wikipedia.org/wiki/Fade_(audio_engineering)#Crossfading).\n\t *\n\t * @constructor\n\t * @extends {Tone}\n\t * @param {NormalRange} [initialFade=0.5]\n\t * @example\n\t * var crossFade = new Tone.CrossFade(0.5);\n\t * //connect effect A to crossfade from\n\t * //effect output 0 to crossfade input 0\n\t * effectA.connect(crossFade, 0, 0);\n\t * //connect effect B to crossfade from\n\t * //effect output 0 to crossfade input 1\n\t * effectB.connect(crossFade, 0, 1);\n\t * crossFade.fade.value = 0;\n\t * // ^ only effectA is output\n\t * crossFade.fade.value = 1;\n\t * // ^ only effectB is output\n\t * crossFade.fade.value = 0.5;\n\t * // ^ the two signals are mixed equally. \n\t */\t\t\n\tTone.CrossFade = function(initialFade){\n\n\t\tthis.createInsOuts(2, 1);\n\n\t\t/**\n\t\t * Alias for input[0]. \n\t\t * @type {Tone.Gain}\n\t\t */\n\t\tthis.a = this.input[0] = new Tone.Gain();\n\n\t\t/**\n\t\t * Alias for input[1]. \n\t\t * @type {Tone.Gain}\n\t\t */\n\t\tthis.b = this.input[1] = new Tone.Gain();\n\n\t\t/**\n\t\t * \tThe mix between the two inputs. A fade value of 0\n\t\t * \twill output 100% input[0] and \n\t\t * \ta value of 1 will output 100% input[1]. \n\t\t * @type {NormalRange}\n\t\t * @signal\n\t\t */\n\t\tthis.fade = new Tone.Signal(this.defaultArg(initialFade, 0.5), Tone.Type.NormalRange);\n\n\t\t/**\n\t\t * equal power gain cross fade\n\t\t * @private\n\t\t * @type {Tone.EqualPowerGain}\n\t\t */\n\t\tthis._equalPowerA = new Tone.EqualPowerGain();\n\n\t\t/**\n\t\t * equal power gain cross fade\n\t\t * @private\n\t\t * @type {Tone.EqualPowerGain}\n\t\t */\n\t\tthis._equalPowerB = new Tone.EqualPowerGain();\n\t\t\n\t\t/**\n\t\t * invert the incoming signal\n\t\t * @private\n\t\t * @type {Tone}\n\t\t */\n\t\tthis._invert = new Tone.Expr(\"1 - $0\");\n\n\t\t//connections\n\t\tthis.a.connect(this.output);\n\t\tthis.b.connect(this.output);\n\t\tthis.fade.chain(this._equalPowerB, this.b.gain);\n\t\tthis.fade.chain(this._invert, this._equalPowerA, this.a.gain);\n\t\tthis._readOnly(\"fade\");\n\t};\n\n\tTone.extend(Tone.CrossFade);\n\n\t/**\n\t * clean up\n\t * @returns {Tone.CrossFade} this\n\t */\n\tTone.CrossFade.prototype.dispose = function(){\n\t\tTone.prototype.dispose.call(this);\n\t\tthis._writable(\"fade\");\n\t\tthis._equalPowerA.dispose();\n\t\tthis._equalPowerA = null;\n\t\tthis._equalPowerB.dispose();\n\t\tthis._equalPowerB = null;\n\t\tthis.fade.dispose();\n\t\tthis.fade = null;\n\t\tthis._invert.dispose();\n\t\tthis._invert = null;\n\t\tthis.a.dispose();\n\t\tthis.a = null;\n\t\tthis.b.dispose();\n\t\tthis.b = null;\n\t\treturn this;\n\t};\n\n\treturn Tone.CrossFade;\n});\n","define([\"Tone/core/Tone\", \"Tone/signal/Add\", \"Tone/signal/Subtract\", \"Tone/signal/Multiply\", \n\t\"Tone/signal/GreaterThan\", \"Tone/signal/GreaterThanZero\", \"Tone/signal/Abs\", \"Tone/signal/Negate\", \n\t\"Tone/signal/Modulo\", \"Tone/signal/Pow\", \"Tone/signal/AudioToGain\"], \n\tfunction(Tone){\n\n\t\"use strict\";\n\n\t/**\n\t * @class Evaluate an expression at audio rate.
\n\t * Parsing code modified from https://code.google.com/p/tapdigit/\n\t * Copyright 2011 2012 Ariya Hidayat, New BSD License\n\t *\n\t * @extends {Tone.SignalBase}\n\t * @constructor\n\t * @param {string} expr the expression to generate\n\t * @example\n\t * //adds the signals from input[0] and input[1].\n\t * var expr = new Tone.Expr(\"$0 + $1\");\n\t */\n\tTone.Expr = function(){\n\n\t\tvar expr = this._replacements(Array.prototype.slice.call(arguments));\n\t\tvar inputCount = this._parseInputs(expr);\n\n\t\t/**\n\t\t * hold onto all of the nodes for disposal\n\t\t * @type {Array}\n\t\t * @private\n\t\t */\n\t\tthis._nodes = [];\n\n\t\t/**\n\t\t * The inputs. The length is determined by the expression. \n\t\t * @type {Array}\n\t\t */\n\t\tthis.input = new Array(inputCount);\n\n\t\t//create a gain for each input\n\t\tfor (var i = 0; i < inputCount; i++){\n\t\t\tthis.input[i] = this.context.createGain();\n\t\t}\n\n\t\t//parse the syntax tree\n\t\tvar tree = this._parseTree(expr);\n\t\t//evaluate the results\n\t\tvar result;\n\t\ttry {\n\t\t\tresult = this._eval(tree);\n\t\t} catch (e){\n\t\t\tthis._disposeNodes();\n\t\t\tthrow new Error(\"Tone.Expr: Could evaluate expression: \"+expr);\n\t\t}\n\n\t\t/**\n\t\t * The output node is the result of the expression\n\t\t * @type {Tone}\n\t\t */\n\t\tthis.output = result;\n\t};\n\n\tTone.extend(Tone.Expr, Tone.SignalBase);\n\n\t//some helpers to cut down the amount of code\n\tfunction applyBinary(Constructor, args, self){\n\t\tvar op = new Constructor();\n\t\tself._eval(args[0]).connect(op, 0, 0);\n\t\tself._eval(args[1]).connect(op, 0, 1);\n\t\treturn op;\n\t}\n\tfunction applyUnary(Constructor, args, self){\n\t\tvar op = new Constructor();\n\t\tself._eval(args[0]).connect(op, 0, 0);\n\t\treturn op;\n\t}\n\tfunction getNumber(arg){\n\t\treturn arg ? parseFloat(arg) : undefined;\n\t}\n\tfunction literalNumber(arg){\n\t\treturn arg && arg.args ? parseFloat(arg.args) : undefined;\n\t}\n\n\t/*\n\t * the Expressions that Tone.Expr can parse.\n\t *\n\t * each expression belongs to a group and contains a regexp \n\t * for selecting the operator as well as that operators method\n\t * \n\t * @type {Object}\n\t * @private\n\t */\n\tTone.Expr._Expressions = {\n\t\t//values\n\t\t\"value\" : {\n\t\t\t\"signal\" : {\n\t\t\t\tregexp : /^\\d+\\.\\d+|^\\d+/,\n\t\t\t\tmethod : function(arg){\n\t\t\t\t\tvar sig = new Tone.Signal(getNumber(arg));\n\t\t\t\t\treturn sig;\n\t\t\t\t}\n\t\t\t},\n\t\t\t\"input\" : {\n\t\t\t\tregexp : /^\\$\\d/,\n\t\t\t\tmethod : function(arg, self){\n\t\t\t\t\treturn self.input[getNumber(arg.substr(1))];\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\t\t//syntactic glue\n\t\t\"glue\" : {\n\t\t\t\"(\" : {\n\t\t\t\tregexp : /^\\(/,\n\t\t\t},\n\t\t\t\")\" : {\n\t\t\t\tregexp : /^\\)/,\n\t\t\t},\n\t\t\t\",\" : {\n\t\t\t\tregexp : /^,/,\n\t\t\t}\n\t\t},\n\t\t//functions\n\t\t\"func\" : {\n\t\t\t\"abs\" : {\n\t\t\t\tregexp : /^abs/,\n\t\t\t\tmethod : applyUnary.bind(this, Tone.Abs)\n\t\t\t},\n\t\t\t\"mod\" : {\n\t\t\t\tregexp : /^mod/,\n\t\t\t\tmethod : function(args, self){\n\t\t\t\t\tvar modulus = literalNumber(args[1]);\n\t\t\t\t\tvar op = new Tone.Modulo(modulus);\n\t\t\t\t\tself._eval(args[0]).connect(op);\n\t\t\t\t\treturn op;\n\t\t\t\t}\n\t\t\t},\n\t\t\t\"pow\" : {\n\t\t\t\tregexp : /^pow/,\n\t\t\t\tmethod : function(args, self){\n\t\t\t\t\tvar exp = literalNumber(args[1]);\n\t\t\t\t\tvar op = new Tone.Pow(exp);\n\t\t\t\t\tself._eval(args[0]).connect(op);\n\t\t\t\t\treturn op;\n\t\t\t\t}\n\t\t\t},\n\t\t\t\"a2g\" : {\n\t\t\t\tregexp : /^a2g/,\n\t\t\t\tmethod : function(args, self){\n\t\t\t\t\tvar op = new Tone.AudioToGain();\n\t\t\t\t\tself._eval(args[0]).connect(op);\n\t\t\t\t\treturn op;\n\t\t\t\t}\n\t\t\t},\n\t\t},\n\t\t//binary expressions\n\t\t\"binary\" : {\n\t\t\t\"+\" : {\n\t\t\t\tregexp : /^\\+/,\n\t\t\t\tprecedence : 1,\n\t\t\t\tmethod : applyBinary.bind(this, Tone.Add)\n\t\t\t},\n\t\t\t\"-\" : {\n\t\t\t\tregexp : /^\\-/,\n\t\t\t\tprecedence : 1,\n\t\t\t\tmethod : function(args, self){\n\t\t\t\t\t//both unary and binary op\n\t\t\t\t\tif (args.length === 1){\n\t\t\t\t\t\treturn applyUnary(Tone.Negate, args, self);\n\t\t\t\t\t} else {\n\t\t\t\t\t\treturn applyBinary(Tone.Subtract, args, self);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t},\n\t\t\t\"*\" : {\n\t\t\t\tregexp : /^\\*/,\n\t\t\t\tprecedence : 0,\n\t\t\t\tmethod : applyBinary.bind(this, Tone.Multiply)\n\t\t\t}\n\t\t},\n\t\t//unary expressions\n\t\t\"unary\" : {\n\t\t\t\"-\" : {\n\t\t\t\tregexp : /^\\-/,\n\t\t\t\tmethod : applyUnary.bind(this, Tone.Negate)\n\t\t\t},\n\t\t\t\"!\" : {\n\t\t\t\tregexp : /^\\!/,\n\t\t\t\tmethod : applyUnary.bind(this, Tone.NOT)\n\t\t\t},\n\t\t},\n\t};\n\t\t\n\t/**\n\t * @param {string} expr the expression string\n\t * @return {number} the input count\n\t * @private\n\t */\n\tTone.Expr.prototype._parseInputs = function(expr){\n\t\tvar inputArray = expr.match(/\\$\\d/g);\n\t\tvar inputMax = 0;\n\t\tif (inputArray !== null){\n\t\t\tfor (var i = 0; i < inputArray.length; i++){\n\t\t\t\tvar inputNum = parseInt(inputArray[i].substr(1)) + 1;\n\t\t\t\tinputMax = Math.max(inputMax, inputNum);\n\t\t\t}\n\t\t}\n\t\treturn inputMax;\n\t};\n\n\t/**\n\t * @param {Array} args \tan array of arguments\n\t * @return {string} the results of the replacements being replaced\n\t * @private\n\t */\n\tTone.Expr.prototype._replacements = function(args){\n\t\tvar expr = args.shift();\n\t\tfor (var i = 0; i < args.length; i++){\n\t\t\texpr = expr.replace(/\\%/i, args[i]);\n\t\t}\n\t\treturn expr;\n\t};\n\n\t/**\n\t * tokenize the expression based on the Expressions object\n\t * @param {string} expr \n\t * @return {Object} returns two methods on the tokenized list, next and peek\n\t * @private\n\t */\n\tTone.Expr.prototype._tokenize = function(expr){\n\t\tvar position = -1;\n\t\tvar tokens = [];\n\n\t\twhile(expr.length > 0){\n\t\t\texpr = expr.trim();\n\t\t\tvar token = getNextToken(expr);\n\t\t\ttokens.push(token);\n\t\t\texpr = expr.substr(token.value.length);\n\t\t}\n\n\t\tfunction getNextToken(expr){\n\t\t\tfor (var type in Tone.Expr._Expressions){\n\t\t\t\tvar group = Tone.Expr._Expressions[type];\n\t\t\t\tfor (var opName in group){\n\t\t\t\t\tvar op = group[opName];\n\t\t\t\t\tvar reg = op.regexp;\n\t\t\t\t\tvar match = expr.match(reg);\n\t\t\t\t\tif (match !== null){\n\t\t\t\t\t\treturn {\n\t\t\t\t\t\t\ttype : type,\n\t\t\t\t\t\t\tvalue : match[0],\n\t\t\t\t\t\t\tmethod : op.method\n\t\t\t\t\t\t};\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\tthrow new SyntaxError(\"Tone.Expr: Unexpected token \"+expr);\n\t\t}\n\n\t\treturn {\n\t\t\tnext : function(){\n\t\t\t\treturn tokens[++position];\n\t\t\t},\n\t\t\tpeek : function(){\n\t\t\t\treturn tokens[position + 1];\n\t\t\t}\n\t\t};\n\t};\n\n\t/**\n\t * recursively parse the string expression into a syntax tree\n\t * \n\t * @param {string} expr \n\t * @return {Object}\n\t * @private\n\t */\n\tTone.Expr.prototype._parseTree = function(expr){\n\t\tvar lexer = this._tokenize(expr);\n\t\tvar isUndef = this.isUndef.bind(this);\n\n\t\tfunction matchSyntax(token, syn) {\n\t\t\treturn !isUndef(token) && \n\t\t\t\ttoken.type === \"glue\" &&\n\t\t\t\ttoken.value === syn;\n\t\t}\n\n\t\tfunction matchGroup(token, groupName, prec) {\n\t\t\tvar ret = false;\n\t\t\tvar group = Tone.Expr._Expressions[groupName];\n\t\t\tif (!isUndef(token)){\n\t\t\t\tfor (var opName in group){\n\t\t\t\t\tvar op = group[opName];\n\t\t\t\t\tif (op.regexp.test(token.value)){\n\t\t\t\t\t\tif (!isUndef(prec)){\n\t\t\t\t\t\t\tif(op.precedence === prec){\t\n\t\t\t\t\t\t\t\treturn true;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\treturn true;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn ret;\n\t\t}\n\n\t\tfunction parseExpression(precedence) {\n\t\t\tif (isUndef(precedence)){\n\t\t\t\tprecedence = 5;\n\t\t\t}\n\t\t\tvar expr;\n\t\t\tif (precedence < 0){\n\t\t\t\texpr = parseUnary();\n\t\t\t} else {\n\t\t\t\texpr = parseExpression(precedence-1);\n\t\t\t}\n\t\t\tvar token = lexer.peek();\n\t\t\twhile (matchGroup(token, \"binary\", precedence)) {\n\t\t\t\ttoken = lexer.next();\n\t\t\t\texpr = {\n\t\t\t\t\toperator: token.value,\n\t\t\t\t\tmethod : token.method,\n\t\t\t\t\targs : [\n\t\t\t\t\t\texpr,\n\t\t\t\t\t\tparseExpression(precedence-1)\n\t\t\t\t\t]\n\t\t\t\t};\n\t\t\t\ttoken = lexer.peek();\n\t\t\t}\n\t\t\treturn expr;\n\t\t}\n\n\t\tfunction parseUnary() {\n\t\t\tvar token, expr;\n\t\t\ttoken = lexer.peek();\n\t\t\tif (matchGroup(token, \"unary\")) {\n\t\t\t\ttoken = lexer.next();\n\t\t\t\texpr = parseUnary();\n\t\t\t\treturn {\n\t\t\t\t\toperator: token.value,\n\t\t\t\t\tmethod : token.method,\n\t\t\t\t\targs : [expr]\n\t\t\t\t};\n\t\t\t}\n\t\t\treturn parsePrimary();\n\t\t}\n\n\t\tfunction parsePrimary() {\n\t\t\tvar token, expr;\n\t\t\ttoken = lexer.peek();\n\t\t\tif (isUndef(token)) {\n\t\t\t\tthrow new SyntaxError(\"Tone.Expr: Unexpected termination of expression\");\n\t\t\t}\n\t\t\tif (token.type === \"func\") {\n\t\t\t\ttoken = lexer.next();\n\t\t\t\treturn parseFunctionCall(token);\n\t\t\t}\n\t\t\tif (token.type === \"value\") {\n\t\t\t\ttoken = lexer.next();\n\t\t\t\treturn {\n\t\t\t\t\tmethod : token.method,\n\t\t\t\t\targs : token.value\n\t\t\t\t};\n\t\t\t}\n\t\t\tif (matchSyntax(token, \"(\")) {\n\t\t\t\tlexer.next();\n\t\t\t\texpr = parseExpression();\n\t\t\t\ttoken = lexer.next();\n\t\t\t\tif (!matchSyntax(token, \")\")) {\n\t\t\t\t\tthrow new SyntaxError(\"Expected )\");\n\t\t\t\t}\n\t\t\t\treturn expr;\n\t\t\t}\n\t\t\tthrow new SyntaxError(\"Tone.Expr: Parse error, cannot process token \" + token.value);\n\t\t}\n\n\t\tfunction parseFunctionCall(func) {\n\t\t\tvar token, args = [];\n\t\t\ttoken = lexer.next();\n\t\t\tif (!matchSyntax(token, \"(\")) {\n\t\t\t\tthrow new SyntaxError(\"Tone.Expr: Expected ( in a function call \\\"\" + func.value + \"\\\"\");\n\t\t\t}\n\t\t\ttoken = lexer.peek();\n\t\t\tif (!matchSyntax(token, \")\")) {\n\t\t\t\targs = parseArgumentList();\n\t\t\t}\n\t\t\ttoken = lexer.next();\n\t\t\tif (!matchSyntax(token, \")\")) {\n\t\t\t\tthrow new SyntaxError(\"Tone.Expr: Expected ) in a function call \\\"\" + func.value + \"\\\"\");\n\t\t\t}\n\t\t\treturn {\n\t\t\t\tmethod : func.method,\n\t\t\t\targs : args,\n\t\t\t\tname : name\n\t\t\t};\n\t\t}\n\n\t\tfunction parseArgumentList() {\n\t\t\tvar token, expr, args = [];\n\t\t\twhile (true) {\n\t\t\t\texpr = parseExpression();\n\t\t\t\tif (isUndef(expr)) {\n\t\t\t\t\t// TODO maybe throw exception?\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\targs.push(expr);\n\t\t\t\ttoken = lexer.peek();\n\t\t\t\tif (!matchSyntax(token, \",\")) {\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tlexer.next();\n\t\t\t}\n\t\t\treturn args;\n\t\t}\n\n\t\treturn parseExpression();\n\t};\n\n\t/**\n\t * recursively evaluate the expression tree\n\t * @param {Object} tree \n\t * @return {AudioNode} the resulting audio node from the expression\n\t * @private\n\t */\n\tTone.Expr.prototype._eval = function(tree){\n\t\tif (!this.isUndef(tree)){\n\t\t\tvar node = tree.method(tree.args, this);\n\t\t\tthis._nodes.push(node);\n\t\t\treturn node;\n\t\t} \n\t};\n\n\t/**\n\t * dispose all the nodes\n\t * @private\n\t */\n\tTone.Expr.prototype._disposeNodes = function(){\n\t\tfor (var i = 0; i < this._nodes.length; i++){\n\t\t\tvar node = this._nodes[i];\n\t\t\tif (this.isFunction(node.dispose)) {\n\t\t\t\tnode.dispose();\n\t\t\t} else if (this.isFunction(node.disconnect)) {\n\t\t\t\tnode.disconnect();\n\t\t\t}\n\t\t\tnode = null;\n\t\t\tthis._nodes[i] = null;\n\t\t}\n\t\tthis._nodes = null;\n\t};\n\n\t/**\n\t * clean up\n\t */\n\tTone.Expr.prototype.dispose = function(){\n\t\tTone.prototype.dispose.call(this);\n\t\tthis._disposeNodes();\n\t};\n\n\treturn Tone.Expr;\n});","define([\"Tone/core/Tone\", \"Tone/signal/GreaterThanZero\", \"Tone/signal/Subtract\", \"Tone/signal/Signal\"], \n\tfunction(Tone){\n\n\t\"use strict\";\n\n\t/**\n\t * @class Output 1 if the signal is greater than the value, otherwise outputs 0.\n\t * can compare two signals or a signal and a number. \n\t * \n\t * @constructor\n\t * @extends {Tone.Signal}\n\t * @param {number} [value=0] the value to compare to the incoming signal\n\t * @example\n\t * var gt = new Tone.GreaterThan(2);\n\t * var sig = new Tone.Signal(4).connect(gt);\n\t * //output of gt is equal 1. \n\t */\n\tTone.GreaterThan = function(value){\n\n\t\tthis.createInsOuts(2, 0);\n\t\t\n\t\t/**\n\t\t * subtract the amount from the incoming signal\n\t\t * @type {Tone.Subtract}\n\t\t * @private\n\t\t */\n\t\tthis._param = this.input[0] = new Tone.Subtract(value);\n\t\tthis.input[1] = this._param.input[1];\n\n\t\t/**\n\t\t * compare that amount to zero\n\t\t * @type {Tone.GreaterThanZero}\n\t\t * @private\n\t\t */\n\t\tthis._gtz = this.output = new Tone.GreaterThanZero();\n\n\t\t//connect\n\t\tthis._param.connect(this._gtz);\n\t};\n\n\tTone.extend(Tone.GreaterThan, Tone.Signal);\n\n\t/**\n\t * dispose method\n\t * @returns {Tone.GreaterThan} this\n\t */\n\tTone.GreaterThan.prototype.dispose = function(){\n\t\tTone.prototype.dispose.call(this);\n\t\tthis._param.dispose();\n\t\tthis._param = null;\n\t\tthis._gtz.dispose();\n\t\tthis._gtz = null;\n\t\treturn this;\n\t};\n\n\treturn Tone.GreaterThan;\n});","define([\"Tone/core/Tone\", \"Tone/signal/WaveShaper\", \"Tone/signal/SignalBase\"], \nfunction(Tone){\n\n\t\"use strict\";\n\n\t/**\n\t * @class Return the absolute value of an incoming signal. \n\t * \n\t * @constructor\n\t * @extends {Tone.SignalBase}\n\t * @example\n\t * var signal = new Tone.Signal(-1);\n\t * var abs = new Tone.Abs();\n\t * signal.connect(abs);\n\t * //the output of abs is 1. \n\t */\n\tTone.Abs = function(){\n\t\t/**\n\t\t * @type {Tone.LessThan}\n\t\t * @private\n\t\t */\n\t\tthis._abs = this.input = this.output = new Tone.WaveShaper(function(val){\n\t\t\tif (val === 0){\n\t\t\t\treturn 0;\n\t\t\t} else {\n\t\t\t\treturn Math.abs(val);\n\t\t\t}\n\t\t}, 127);\n\t};\n\n\tTone.extend(Tone.Abs, Tone.SignalBase);\n\n\t/**\n\t * dispose method\n\t * @returns {Tone.Abs} this\n\t */\n\tTone.Abs.prototype.dispose = function(){\n\t\tTone.prototype.dispose.call(this);\n\t\tthis._abs.dispose();\n\t\tthis._abs = null;\n\t\treturn this;\n\t}; \n\n\treturn Tone.Abs;\n});","define([\"Tone/core/Tone\", \"Tone/signal/WaveShaper\", \"Tone/signal/Multiply\", \"Tone/signal/Subtract\"], \nfunction(Tone){\n\n\t\"use strict\";\n\n\t/**\n\t * @class Signal-rate modulo operator. Only works in AudioRange [-1, 1] and for modulus\n\t * values in the NormalRange. \n\t *\n\t * @constructor\n\t * @extends {Tone.SignalBase}\n\t * @param {NormalRange} modulus The modulus to apply.\n\t * @example\n\t * var mod = new Tone.Modulo(0.2)\n\t * var sig = new Tone.Signal(0.5).connect(mod);\n\t * //mod outputs 0.1\n\t */\n\tTone.Modulo = function(modulus){\n\n\t\tthis.createInsOuts(1, 0);\n\n\t\t/**\n\t\t * A waveshaper gets the integer multiple of \n\t\t * the input signal and the modulus.\n\t\t * @private\n\t\t * @type {Tone.WaveShaper}\n\t\t */\n\t\tthis._shaper = new Tone.WaveShaper(Math.pow(2, 16));\n\n\t\t/**\n\t\t * the integer multiple is multiplied by the modulus\n\t\t * @type {Tone.Multiply}\n\t\t * @private\n\t\t */\n\t\tthis._multiply = new Tone.Multiply();\n\n\t\t/**\n\t\t * and subtracted from the input signal\n\t\t * @type {Tone.Subtract}\n\t\t * @private\n\t\t */\n\t\tthis._subtract = this.output = new Tone.Subtract();\n\n\t\t/**\n\t\t * the modulus signal\n\t\t * @type {Tone.Signal}\n\t\t * @private\n\t\t */\n\t\tthis._modSignal = new Tone.Signal(modulus);\n\n\t\t//connections\n\t\tthis.input.fan(this._shaper, this._subtract);\n\t\tthis._modSignal.connect(this._multiply, 0, 0);\n\t\tthis._shaper.connect(this._multiply, 0, 1);\n\t\tthis._multiply.connect(this._subtract, 0, 1);\n\t\tthis._setWaveShaper(modulus);\n\t};\n\n\tTone.extend(Tone.Modulo, Tone.SignalBase);\n\n\t/**\n\t * @param {number} mod the modulus to apply\n\t * @private\n\t */\n\tTone.Modulo.prototype._setWaveShaper = function(mod){\n\t\tthis._shaper.setMap(function(val){\n\t\t\tvar multiple = Math.floor((val + 0.0001) / mod);\n\t\t\treturn multiple;\n\t\t});\n\t};\n\n\t/**\n\t * The modulus value.\n\t * @memberOf Tone.Modulo#\n\t * @type {NormalRange}\n\t * @name value\n\t */\n\tObject.defineProperty(Tone.Modulo.prototype, \"value\", {\n\t\tget : function(){\n\t\t\treturn this._modSignal.value;\n\t\t},\n\t\tset : function(mod){\n\t\t\tthis._modSignal.value = mod;\n\t\t\tthis._setWaveShaper(mod);\n\t\t}\n\t});\n\n\t/**\n\t * clean up\n\t * @returns {Tone.Modulo} this\n\t */\n\tTone.Modulo.prototype.dispose = function(){\n\t\tTone.prototype.dispose.call(this);\n\t\tthis._shaper.dispose();\n\t\tthis._shaper = null;\n\t\tthis._multiply.dispose();\n\t\tthis._multiply = null;\n\t\tthis._subtract.dispose();\n\t\tthis._subtract = null;\n\t\tthis._modSignal.dispose();\n\t\tthis._modSignal = null;\n\t\treturn this;\n\t};\n\n\treturn Tone.Modulo;\n});","define([\"Tone/core/Tone\", \"Tone/signal/WaveShaper\"], function(Tone){\n\n\t\"use strict\";\n\n\t/**\n\t * @class Pow applies an exponent to the incoming signal. The incoming signal\n\t * must be AudioRange.\n\t *\n\t * @extends {Tone.SignalBase}\n\t * @constructor\n\t * @param {Positive} exp The exponent to apply to the incoming signal, must be at least 2. \n\t * @example\n\t * var pow = new Tone.Pow(2);\n\t * var sig = new Tone.Signal(0.5).connect(pow);\n\t * //output of pow is 0.25. \n\t */\n\tTone.Pow = function(exp){\n\n\t\t/**\n\t\t * the exponent\n\t\t * @private\n\t\t * @type {number}\n\t\t */\n\t\tthis._exp = this.defaultArg(exp, 1);\n\n\t\t/**\n\t\t * @type {WaveShaperNode}\n\t\t * @private\n\t\t */\n\t\tthis._expScaler = this.input = this.output = new Tone.WaveShaper(this._expFunc(this._exp), 8192);\n\t};\n\n\tTone.extend(Tone.Pow, Tone.SignalBase);\n\n\t/**\n\t * The value of the exponent.\n\t * @memberOf Tone.Pow#\n\t * @type {number}\n\t * @name value\n\t */\n\tObject.defineProperty(Tone.Pow.prototype, \"value\", {\n\t\tget : function(){\n\t\t\treturn this._exp;\n\t\t},\n\t\tset : function(exp){\n\t\t\tthis._exp = exp;\n\t\t\tthis._expScaler.setMap(this._expFunc(this._exp));\n\t\t}\n\t});\n\n\n\t/**\n\t * the function which maps the waveshaper\n\t * @param {number} exp\n\t * @return {function}\n\t * @private\n\t */\n\tTone.Pow.prototype._expFunc = function(exp){\n\t\treturn function(val){\n\t\t\treturn Math.pow(Math.abs(val), exp);\n\t\t};\n\t};\n\n\t/**\n\t * Clean up.\n\t * @returns {Tone.Pow} this\n\t */\n\tTone.Pow.prototype.dispose = function(){\n\t\tTone.prototype.dispose.call(this);\n\t\tthis._expScaler.dispose();\n\t\tthis._expScaler = null;\n\t\treturn this;\n\t};\n\n\treturn Tone.Pow;\n});","define([\"Tone/core/Tone\", \"Tone/signal/WaveShaper\", \"Tone/signal/Signal\"], function(Tone){\n\n\t\"use strict\";\n\n\t/**\n\t * @class AudioToGain converts an input in AudioRange [-1,1] to NormalRange [0,1]. \n\t * See Tone.GainToAudio.\n\t *\n\t * @extends {Tone.SignalBase}\n\t * @constructor\n\t * @example\n\t * var a2g = new Tone.AudioToGain();\n\t */\n\tTone.AudioToGain = function(){\n\n\t\t/**\n\t\t * @type {WaveShaperNode}\n\t\t * @private\n\t\t */\n\t\tthis._norm = this.input = this.output = new Tone.WaveShaper(function(x){\n\t\t\treturn (x + 1) / 2;\n\t\t});\n\t};\n\n\tTone.extend(Tone.AudioToGain, Tone.SignalBase);\n\n\t/**\n\t * clean up\n\t * @returns {Tone.AudioToGain} this\n\t */\n\tTone.AudioToGain.prototype.dispose = function(){\n\t\tTone.prototype.dispose.call(this);\n\t\tthis._norm.dispose();\n\t\tthis._norm = null;\n\t\treturn this;\n\t};\n\n\treturn Tone.AudioToGain;\n});","define([\"Tone/core/Tone\", \"Tone/signal/WaveShaper\"], function(Tone){\n\n\t\"use strict\";\n\n\t/**\n\t * @class Convert an incoming signal between 0, 1 to an equal power gain scale.\n\t *\n\t * @extends {Tone.SignalBase}\n\t * @constructor\n\t * @example\n\t * var eqPowGain = new Tone.EqualPowerGain();\n\t */\n\tTone.EqualPowerGain = function(){\n\n\t\t/**\n\t\t * @type {Tone.WaveShaper}\n\t\t * @private\n\t\t */\n\t\tthis._eqPower = this.input = this.output = new Tone.WaveShaper(function(val){\n\t\t\tif (Math.abs(val) < 0.001){\n\t\t\t\t//should output 0 when input is 0\n\t\t\t\treturn 0;\n\t\t\t} else {\n\t\t\t\treturn this.equalPowerScale(val);\n\t\t\t}\n\t\t}.bind(this), 4096);\n\t};\n\n\tTone.extend(Tone.EqualPowerGain, Tone.SignalBase);\n\n\t/**\n\t * clean up\n\t * @returns {Tone.EqualPowerGain} this\n\t */\n\tTone.EqualPowerGain.prototype.dispose = function(){\n\t\tTone.prototype.dispose.call(this);\n\t\tthis._eqPower.dispose();\n\t\tthis._eqPower = null;\n\t\treturn this;\n\t};\n\n\treturn Tone.EqualPowerGain;\n});","'use strict';\n\ndefine(function (require) {\n\n var Effect = require('effect');\n var EQFilter = require('eqFilter');\n\n /**\n * p5.EQ is an audio effect that performs the function of a multiband\n * audio equalizer. Equalization is used to adjust the balance of\n * frequency compoenents of an audio signal. This process is commonly used\n * in sound production and recording to change the waveform before it reaches\n * a sound output device. EQ can also be used as an audio effect to create\n * interesting distortions by filtering out parts of the spectrum. p5.EQ is\n * built using a chain of Web Audio Biquad Filter Nodes and can be\n * instantiated with 3 or 8 bands. Bands can be added or removed from\n * the EQ by directly modifying p5.EQ.bands (the array that stores filters).\n *\n * This class extends p5.Effect.\n * Methods amp(), chain(),\n * drywet(), connect(), and\n * disconnect() are available.\n *\n * @class p5.EQ\n * @constructor\n * @extends p5.Effect\n * @param {Number} [_eqsize] Constructor will accept 3 or 8, defaults to 3\n * @return {Object} p5.EQ object\n *\n * @example\n *
\n * var eq;\n * var band_names;\n * var band_index;\n *\n * var soundFile, play;\n *\n * function preload() {\n * soundFormats('mp3', 'ogg');\n * soundFile = loadSound('assets/beat');\n * }\n *\n * function setup() {\n * eq = new p5.EQ(3);\n * soundFile.disconnect();\n * eq.process(soundFile);\n *\n * band_names = ['lows','mids','highs'];\n * band_index = 0;\n * play = false;\n * textAlign(CENTER);\n * }\n *\n * function draw() {\n * background(30);\n * noStroke();\n * fill(255);\n * text('click to kill',50,25);\n *\n * fill(255, 40, 255);\n * textSize(26);\n * text(band_names[band_index],50,55);\n *\n * fill(255);\n * textSize(9);\n * text('space = play/pause',50,80);\n * }\n *\n * //If mouse is over canvas, cycle to the next band and kill the frequency\n * function mouseClicked() {\n * for (var i = 0; i < eq.bands.length; i++) {\n * eq.bands[i].gain(0);\n * }\n * eq.bands[band_index].gain(-40);\n * if (mouseX > 0 && mouseX < width && mouseY < height && mouseY > 0) {\n * band_index === 2 ? band_index = 0 : band_index++;\n * }\n * }\n *\n * //use space bar to trigger play / pause\n * function keyPressed() {\n * if (key===' ') {\n * play = !play\n * play ? soundFile.loop() : soundFile.pause();\n * }\n * }\n *
\n */\n p5.EQ = function(_eqsize) {\n Effect.call(this);\n\n //p5.EQ can be of size (3) or (8), defaults to 3\n _eqsize = _eqsize === 3 || _eqsize === 8 ? _eqsize : 3;\n\n var factor;\n _eqsize === 3 ? factor = Math.pow(2,3) : factor = 2;\n\n /**\n * The p5.EQ is built with abstracted p5.Filter objects.\n * To modify any bands, use methods of the \n * p5.Filter API, especially `gain` and `freq`.\n * Bands are stored in an array, with indices 0 - 3, or 0 - 7\n * @property {Array} bands\n *\n */\n this.bands = [];\n\n\n var freq, res;\n for (var i = 0; i < _eqsize; i++) {\n if (i === _eqsize - 1) {\n freq = 21000;\n res = .01;\n } else if (i === 0) {\n freq = 100;\n res = .1;\n }\n else if (i===1) {\n freq = _eqsize === 3 ? 360 * factor : 360;\n res = 1;\n }else {\n freq = this.bands[i-1].freq() * factor;\n res = 1;\n }\n this.bands[i] = this._newBand(freq, res);\n\n if (i>0) {\n this.bands[i-1].connect(this.bands[i].biquad);\n } else {\n this.input.connect(this.bands[i].biquad);\n }\n }\n this.bands[_eqsize-1].connect(this.output);\n };\n p5.EQ.prototype = Object.create(Effect.prototype);\n\n /**\n * Process an input by connecting it to the EQ\n * @method process\n * @param {Object} src Audio source\n */\n p5.EQ.prototype.process = function (src) {\n src.connect(this.input);\n };\n\n // /**\n // * Set the frequency and gain of each band in the EQ. This method should be\n // * called with 3 or 8 frequency and gain pairs, depending on the size of the EQ.\n // * ex. eq.set(freq0, gain0, freq1, gain1, freq2, gain2);\n // *\n // * @method set\n // * @for p5.EQ\n // * @param {Number} [freq0] Frequency value for band with index 0\n // * @param {Number} [gain0] Gain value for band with index 0\n // * @param {Number} [freq1] Frequency value for band with index 1\n // * @param {Number} [gain1] Gain value for band with index 1\n // * @param {Number} [freq2] Frequency value for band with index 2\n // * @param {Number} [gain2] Gain value for band with index 2\n // * @param {Number} [freq3] Frequency value for band with index 3\n // * @param {Number} [gain3] Gain value for band with index 3\n // * @param {Number} [freq4] Frequency value for band with index 4\n // * @param {Number} [gain4] Gain value for band with index 4\n // * @param {Number} [freq5] Frequency value for band with index 5\n // * @param {Number} [gain5] Gain value for band with index 5\n // * @param {Number} [freq6] Frequency value for band with index 6\n // * @param {Number} [gain6] Gain value for band with index 6\n // * @param {Number} [freq7] Frequency value for band with index 7\n // * @param {Number} [gain7] Gain value for band with index 7\n // */\n p5.EQ.prototype.set = function() {\n if (arguments.length === this.bands.length * 2) {\n for (var i = 0; i < arguments.length; i+=2) {\n this.bands[i/2].freq(arguments[i]);\n this.bands[i/2].gain(arguments[i+1]);\n }\n }\n else {\n console.error('Argument mismatch. .set() should be called with ' + this.bands.length*2 +\n ' arguments. (one frequency and gain value pair for each band of the eq)');\n }\n };\n\n /**\n * Add a new band. Creates a p5.Filter and strips away everything but\n * the raw biquad filter. This method returns an abstracted p5.Filter,\n * which can be added to p5.EQ.bands, in order to create new EQ bands.\n * @private\n * @for p5.EQ\n * @method _newBand\n * @param {Number} freq\n * @param {Number} res\n * @return {Object} Abstracted Filter\n */\n p5.EQ.prototype._newBand = function(freq, res) {\n return new EQFilter(freq, res);\n };\n\n p5.EQ.prototype.dispose = function () {\n Effect.prototype.dispose.apply(this);\n\n if (this.bands) {\n while (this.bands.length > 0) {\n delete this.bands.pop().dispose();\n }\n delete this.bands;\n }\n };\n\n return p5.EQ;\n});\n","'use strict';\n\ndefine(function (require) {\n var Filter = require('filter');\n var p5sound = require('master');\n\n /**\n * EQFilter extends p5.Filter with constraints\n * necessary for the p5.EQ\n *\n * @private\n */\n var EQFilter = function(freq, res) {\n Filter.call(this, 'peaking');\n this.disconnect();\n this.set(freq, res);\n this.biquad.gain.value = 0;\n delete this.input;\n delete this.output;\n delete this._drywet;\n delete this.wet;\n\n };\n EQFilter.prototype = Object.create(Filter.prototype);\n\n EQFilter.prototype.amp = function() {\n console.warn('`amp()` is not available for p5.EQ bands. Use `.gain()`');\n };\n EQFilter.prototype.drywet = function() {\n console.warn('`drywet()` is not available for p5.EQ bands.');\n };\n EQFilter.prototype.connect = function(unit) {\n var u = unit || p5.soundOut.input;\n if (this.biquad) {\n this.biquad.connect(u.input ? u.input : u);\n } else {\n this.output.connect(u.input ? u.input : u);\n }\n };\n\n EQFilter.prototype.disconnect = function() {\n if (this.biquad) {\n this.biquad.disconnect();\n }\n };\n EQFilter.prototype.dispose = function() {\n // remove reference form soundArray\n var index = p5sound.soundArray.indexOf(this);\n p5sound.soundArray.splice(index, 1);\n this.disconnect();\n delete this.biquad;\n };\n\n return EQFilter;\n});\n","'use strict'\n\ndefine(function (require) {\n var p5sound = require('master');\n var Effect = require('effect');\n\n /**\n * Panner3D is based on the \n * Web Audio Spatial Panner Node.\n * This panner is a spatial processing node that allows audio to be positioned\n * and oriented in 3D space.\n *\n * The position is relative to an \n * Audio Context Listener, which can be accessed\n * by p5.soundOut.audiocontext.listener\n *\n *\n * @class p5.Panner3D\n * @constructor\n */\n\tp5.Panner3D = function() {\n Effect.call(this);\n\n /**\n * \n * Web Audio Spatial Panner Node\n *\n * Properties include\n * - panningModel: \"equal power\" or \"HRTF\"\n * - distanceModel: \"linear\", \"inverse\", or \"exponential\"\n *\n * @property {AudioNode} panner\n *\n */\n this.panner = this.ac.createPanner();\n this.panner.panningModel = 'HRTF';\n this.panner.distanceModel = 'linear';\n this.panner.connect(this.output);\n this.input.connect(this.panner);\n\t};\n\n p5.Panner3D.prototype = Object.create(Effect.prototype);\n\n\n /**\n * Connect an audio sorce\n *\n * @method process\n * @for p5.Panner3D\n * @param {Object} src Input source\n */\n p5.Panner3D.prototype.process = function(src) {\n src.connect(this.input);\n }\n /**\n * Set the X,Y,Z position of the Panner\n * @method set\n * @for p5.Panner3D\n * @param {Number} xVal\n * @param {Number} yVal\n * @param {Number} zVal\n * @param {Number} time\n * @return {Array} Updated x, y, z values as an array\n */\n p5.Panner3D.prototype.set = function(xVal, yVal, zVal, time) {\n this.positionX(xVal,time);\n this.positionY(yVal,time);\n this.positionZ(zVal,time);\n return [this.panner.positionX.value,\n this.panner.positionY.value,\n this.panner.positionZ.value];\n };\n\n /**\n * Getter and setter methods for position coordinates\n * @method positionX\n * @for p5.Panner3D\n * @return {Number} updated coordinate value\n */\n /**\n * Getter and setter methods for position coordinates\n * @method positionY\n * @for p5.Panner3D\n * @return {Number} updated coordinate value\n */\n /**\n * Getter and setter methods for position coordinates\n * @method positionZ\n * @for p5.Panner3D\n * @return {Number} updated coordinate value\n */\n p5.Panner3D.prototype.positionX = function(xVal, time) {\n var t = time || 0;\n if (typeof xVal === 'number') {\n this.panner.positionX.value = xVal;\n this.panner.positionX.cancelScheduledValues(this.ac.currentTime + 0.01 + t);\n this.panner.positionX.linearRampToValueAtTime(xVal, this.ac.currentTime + 0.02 + t);\n } else if (xVal) {\n xVal.connect(this.panner.positionX);\n }\n return this.panner.positionX.value;\n };\n p5.Panner3D.prototype.positionY = function(yVal, time) {\n var t = time || 0;\n if (typeof yVal === 'number') {\n this.panner.positionY.value = yVal;\n this.panner.positionY.cancelScheduledValues(this.ac.currentTime + 0.01 + t);\n this.panner.positionY.linearRampToValueAtTime(yVal, this.ac.currentTime + 0.02 + t);\n } else if (yVal) {\n yVal.connect(this.panner.positionY);\n }\n return this.panner.positionY.value;\n };\n p5.Panner3D.prototype.positionZ = function(zVal, time) {\n var t = time || 0;\n if (typeof zVal === 'number') {\n this.panner.positionZ.value = zVal;\n this.panner.positionZ.cancelScheduledValues(this.ac.currentTime + 0.01 + t);\n this.panner.positionZ.linearRampToValueAtTime(zVal, this.ac.currentTime + 0.02 + t);\n } else if (zVal) {\n zVal.connect(this.panner.positionZ);\n }\n return this.panner.positionZ.value;\n };\n\n /**\n * Set the X,Y,Z position of the Panner\n * @method orient\n * @for p5.Panner3D\n * @param {Number} xVal\n * @param {Number} yVal\n * @param {Number} zVal\n * @param {Number} time\n * @return {Array} Updated x, y, z values as an array\n */\n p5.Panner3D.prototype.orient = function(xVal, yVal, zVal, time) {\n this.orientX(xVal,time);\n this.orientY(yVal,time);\n this.orientZ(zVal,time);\n return [this.panner.orientationX.value,\n this.panner.orientationY.value,\n this.panner.orientationZ.value];\n };\n\n /**\n * Getter and setter methods for orient coordinates\n * @method orientX\n * @for p5.Panner3D\n * @return {Number} updated coordinate value\n */\n /**\n * Getter and setter methods for orient coordinates\n * @method orientY\n * @for p5.Panner3D\n * @return {Number} updated coordinate value\n */\n /**\n * Getter and setter methods for orient coordinates\n * @method orientZ\n * @for p5.Panner3D\n * @return {Number} updated coordinate value\n */\n p5.Panner3D.prototype.orientX = function(xVal, time) {\n var t = time || 0;\n if (typeof xVal === 'number') {\n this.panner.orientationX.value = xVal;\n this.panner.orientationX.cancelScheduledValues(this.ac.currentTime + 0.01 + t);\n this.panner.orientationX.linearRampToValueAtTime(xVal, this.ac.currentTime + 0.02 + t);\n } else if (xVal) {\n xVal.connect(this.panner.orientationX);\n }\n return this.panner.orientationX.value;\n };\n p5.Panner3D.prototype.orientY = function(yVal, time) {\n var t = time || 0;\n if (typeof yVal === 'number') {\n this.panner.orientationY.value = yVal;\n this.panner.orientationY.cancelScheduledValues(this.ac.currentTime + 0.01 + t);\n this.panner.orientationY.linearRampToValueAtTime(yVal, this.ac.currentTime + 0.02 + t);\n } else if (yVal) {\n yVal.connect(this.panner.orientationY);\n }\n return this.panner.orientationY.value;\n };\n p5.Panner3D.prototype.orientZ = function(zVal, time) {\n var t = time || 0;\n if (typeof zVal === 'number') {\n this.panner.orientationZ.value = zVal;\n this.panner.orientationZ.cancelScheduledValues(this.ac.currentTime + 0.01 + t);\n this.panner.orientationZ.linearRampToValueAtTime(zVal, this.ac.currentTime + 0.02 + t);\n } else if (zVal) {\n zVal.connect(this.panner.orientationZ);\n }\n return this.panner.orientationZ.value;\n };\n\n /**\n * Set the rolloff factor and max distance\n * @method setFalloff\n * @for p5.Panner3D\n * @param {Number} [maxDistance]\n * @param {Number} [rolloffFactor]\n */\n p5.Panner3D.prototype.setFalloff = function(maxDistance, rolloffFactor) {\n this.maxDist(maxDistance);\n this.rolloff(rolloffFactor);\n };\n /**\n * Maxium distance between the source and the listener\n * @method maxDist\n * @for p5.Panner3D\n * @param {Number} maxDistance\n * @return {Number} updated value\n */\n p5.Panner3D.prototype.maxDist = function(maxDistance){\n if (typeof maxDistance === 'number') {\n this.panner.maxDistance = maxDistance;\n }\n return this.panner.maxDistance;\n };\n\n /**\n * How quickly the volume is reduced as the source moves away from the listener\n * @method rollof\n * @for p5.Panner3D\n * @param {Number} rolloffFactor\n * @return {Number} updated value\n */\n p5.Panner3D.prototype.rolloff = function(rolloffFactor){\n if (typeof rolloffFactor === 'number') {\n this.panner.rolloffFactor = rolloffFactor;\n }\n return this.panner.rolloffFactor;\n };\n\n p5.Panner3D.dispose = function() {\n Effect.prototype.dispose.apply(this);\n if (this.panner) {\n this.panner.disconnect();\n delete this.panner;\n }\n };\n\n return p5.Panner3D;\n\n});\n","'use strict'\n\ndefine(function (require) {\n var p5sound = require('master');\n var Effect = require('effect');\n\n// /**\n// * listener is a class that can construct both a Spatial Panner\n// * and a Spatial Listener. The panner is based on the \n// * Web Audio Spatial Panner Node\n// * https://www.w3.org/TR/webaudio/#the-listenernode-interface\n// * This panner is a spatial processing node that allows audio to be positioned\n// * and oriented in 3D space. \n// *\n// * The Listener modifies the properties of the Audio Context Listener. \n// * Both objects types use the same methods. The default is a spatial panner.\n// *\n// * p5.Panner3D - Constructs a Spatial Panner \n// * p5.Listener3D - Constructs a Spatial Listener \n// *\n// * @class listener\n// * @constructor\n// * @return {Object} p5.Listener3D Object\n// *\n// * @param {Web Audio Node} listener Web Audio Spatial Panning Node\n// * @param {AudioParam} listener.panningModel \"equal power\" or \"HRTF\"\n// * @param {AudioParam} listener.distanceModel \"linear\", \"inverse\", or \"exponential\"\n// * @param {String} [type] [Specify construction of a spatial panner or listener]\n// */\n \n\tp5.Listener3D = function(type) {\n this.ac = p5sound.audiocontext;\n this.listener = this.ac.listener;\n\t}; \n\n// /**\n// * Connect an audio sorce\n// * @param {Object} src Input source\n// */\n p5.Listener3D.prototype.process = function(src) {\n src.connect(this.input);\n }\n// /**\n// * Set the X,Y,Z position of the Panner\n// * @param {[Number]} xVal\n// * @param {[Number]} yVal\n// * @param {[Number]} zVal\n// * @param {[Number]} time\n// * @return {[Array]} [Updated x, y, z values as an array]\n// */\n p5.Listener3D.prototype.position = function(xVal, yVal, zVal, time) {\n this.positionX(xVal,time);\n this.positionY(yVal,time);\n this.positionZ(zVal,time);\n return [this.listener.positionX.value, \n this.listener.positionY.value,\n this.listener.positionZ.value];\n };\n\n// /**\n// * Getter and setter methods for position coordinates\n// * @return {Number} [updated coordinate value]\n// */\n p5.Listener3D.prototype.positionX = function(xVal, time) {\n var t = time || 0;\n if (typeof xVal === 'number') {\n this.listener.positionX.value = xVal;\n this.listener.positionX.cancelScheduledValues(this.ac.currentTime + 0.01 + t);\n this.listener.positionX.linearRampToValueAtTime(xVal, this.ac.currentTime + 0.02 + t);\n } else if (xVal) {\n xVal.connect(this.listener.positionX);\n }\n return this.listener.positionX.value;\n };\n p5.Listener3D.prototype.positionY = function(yVal, time) {\n var t = time || 0;\n if (typeof yVal === 'number') {\n this.listener.positionY.value = yVal;\n this.listener.positionY.cancelScheduledValues(this.ac.currentTime + 0.01 + t);\n this.listener.positionY.linearRampToValueAtTime(yVal, this.ac.currentTime + 0.02 + t);\n } else if (yVal) {\n yVal.connect(this.listener.positionY);\n }\n return this.listener.positionY.value;\n };\n p5.Listener3D.prototype.positionZ = function(zVal, time) {\n var t = time || 0;\n if (typeof zVal === 'number') {\n this.listener.positionZ.value = zVal;\n this.listener.positionZ.cancelScheduledValues(this.ac.currentTime + 0.01 + t);\n this.listener.positionZ.linearRampToValueAtTime(zVal, this.ac.currentTime + 0.02 + t);\n } else if (zVal) {\n zVal.connect(this.listener.positionZ);\n }\n return this.listener.positionZ.value;\n };\n\n// cannot define method when class definition is commented\n// /**\n// * Overrides the listener orient() method because Listener has slightly\n// * different params. In human terms, Forward vectors are the direction the \n// * nose is pointing. Up vectors are the direction of the top of the head.\n// *\n// * @method orient\n// * @param {Number} xValF Forward vector X direction\n// * @param {Number} yValF Forward vector Y direction\n// * @param {Number} zValF Forward vector Z direction\n// * @param {Number} xValU Up vector X direction\n// * @param {Number} yValU Up vector Y direction\n// * @param {Number} zValU Up vector Z direction\n// * @param {Number} time \n// * @return {Array} All orienation params\n// */\n p5.Listener3D.prototype.orient = function(xValF, yValF, zValF, \n xValU, yValU, zValU, time) {\n\n if (arguments.length === 3 || arguments.length === 4) {\n time = arguments[3];\n this.orientForward(xValF, yValF, zValF, time);\n } else if (arguments.length === 6 || arguments === 7) {\n this.orientForward(xValF, yValF, zValF);\n this.orientUp(xValU, yValU, zValU, time);\n }\n \n return [this.listener.forwardX.value, \n this.listener.forwardY.value,\n this.listener.forwardZ.value,\n this.listener.upX.value,\n this.listener.upY.value,\n this.listener.upZ.value];\n };\n\n\n p5.Listener3D.prototype.orientForward = function(xValF, yValF, zValF, time) {\n this.forwardX(xValF,time);\n this.forwardY(yValF,time);\n this.forwardZ(zValF,time);\n\n return [this.listener.forwardX, \n this.listener.forwardY,\n this.listener.forwardZ];\n };\n\n p5.Listener3D.prototype.orientUp = function(xValU, yValU, zValU, time) {\n this.upX(xValU,time);\n this.upY(yValU,time);\n this.upZ(zValU,time);\n\n return [this.listener.upX, \n this.listener.upY,\n this.listener.upZ];\n };\n// /**\n// * Getter and setter methods for orient coordinates\n// * @return {Number} [updated coordinate value]\n// */\n p5.Listener3D.prototype.forwardX = function(xVal, time) {\n var t = time || 0;\n if (typeof xVal === 'number') {\n this.listener.forwardX.value = xVal;\n this.listener.forwardX.cancelScheduledValues(this.ac.currentTime + 0.01 + t);\n this.listener.forwardX.linearRampToValueAtTime(xVal, this.ac.currentTime + 0.02 + t);\n } else if (xVal) {\n xVal.connect(this.listener.forwardX);\n }\n return this.listener.forwardX.value;\n };\n p5.Listener3D.prototype.forwardY = function(yVal, time) {\n var t = time || 0;\n if (typeof yVal === 'number') {\n this.listener.forwardY.value = yVal;\n this.listener.forwardY.cancelScheduledValues(this.ac.currentTime + 0.01 + t);\n this.listener.forwardY.linearRampToValueAtTime(yVal, this.ac.currentTime + 0.02 + t);\n } else if (yVal) {\n yVal.connect(this.listener.forwardY);\n }\n return this.listener.forwardY.value;\n };\n p5.Listener3D.prototype.forwardZ = function(zVal, time) {\n var t = time || 0;\n if (typeof zVal === 'number') {\n this.listener.forwardZ.value = zVal;\n this.listener.forwardZ.cancelScheduledValues(this.ac.currentTime + 0.01 + t);\n this.listener.forwardZ.linearRampToValueAtTime(zVal, this.ac.currentTime + 0.02 + t);\n } else if (zVal) {\n zVal.connect(this.listener.forwardZ);\n }\n return this.listener.forwardZ.value;\n };\n p5.Listener3D.prototype.upX = function(xVal, time) {\n var t = time || 0;\n if (typeof xVal === 'number') {\n this.listener.upX.value = xVal;\n this.listener.upX.cancelScheduledValues(this.ac.currentTime + 0.01 + t);\n this.listener.upX.linearRampToValueAtTime(xVal, this.ac.currentTime + 0.02 + t);\n } else if (xVal) {\n xVal.connect(this.listener.upX);\n }\n return this.listener.upX.value;\n };\n p5.Listener3D.prototype.upY = function(yVal, time) {\n var t = time || 0;\n if (typeof yVal === 'number') {\n this.listener.upY.value = yVal;\n this.listener.upY.cancelScheduledValues(this.ac.currentTime + 0.01 + t);\n this.listener.upY.linearRampToValueAtTime(yVal, this.ac.currentTime + 0.02 + t);\n } else if (yVal) {\n yVal.connect(this.listener.upY);\n }\n return this.listener.upY.value;\n };\n p5.Listener3D.prototype.upZ = function(zVal, time) {\n var t = time || 0;\n if (typeof zVal === 'number') {\n this.listener.upZ.value = zVal;\n this.listener.upZ.cancelScheduledValues(this.ac.currentTime + 0.01 + t);\n this.listener.upZ.linearRampToValueAtTime(zVal, this.ac.currentTime + 0.02 + t);\n } else if (zVal) {\n zVal.connect(this.listener.upZ);\n }\n return this.listener.upZ.value;\n };\n \n return p5.Listener3D;\n\n});","'use strict';\n\ndefine(function (require) {\n var Filter = require('filter');\n var Effect = require('effect');\n\n /**\n * Delay is an echo effect. It processes an existing sound source,\n * and outputs a delayed version of that sound. The p5.Delay can\n * produce different effects depending on the delayTime, feedback,\n * filter, and type. In the example below, a feedback of 0.5 (the\n * defaul value) will produce a looping delay that decreases in\n * volume by 50% each repeat. A filter will cut out the high\n * frequencies so that the delay does not sound as piercing as the\n * original source.\n *\n *\n * This class extends p5.Effect.\n * Methods amp(), chain(),\n * drywet(), connect(), and\n * disconnect() are available.\n * @class p5.Delay\n * @extends p5.Effect\n * @constructor\n * @example\n *
\n * var noise, env, delay;\n *\n * function setup() {\n * background(0);\n * noStroke();\n * fill(255);\n * textAlign(CENTER);\n * text('click to play', width/2, height/2);\n *\n * noise = new p5.Noise('brown');\n * noise.amp(0);\n * noise.start();\n *\n * delay = new p5.Delay();\n *\n * // delay.process() accepts 4 parameters:\n * // source, delayTime, feedback, filter frequency\n * // play with these numbers!!\n * delay.process(noise, .12, .7, 2300);\n *\n * // play the noise with an envelope,\n * // a series of fades ( time / value pairs )\n * env = new p5.Envelope(.01, 0.2, .2, .1);\n * }\n *\n * // mouseClick triggers envelope\n * function mouseClicked() {\n * // is mouse over canvas?\n * if (mouseX > 0 && mouseX < width && mouseY > 0 && mouseY < height) {\n * env.play(noise);\n * }\n * }\n *
\n */\n p5.Delay = function() {\n \tEffect.call(this);\n\n this._split = this.ac.createChannelSplitter(2);\n this._merge = this.ac.createChannelMerger(2);\n\n this._leftGain = this.ac.createGain();\n this._rightGain = this.ac.createGain();\n\n /**\n * The p5.Delay is built with two\n * \n * Web Audio Delay Nodes, one for each stereo channel.\n *\n * @property {DelayNode} leftDelay\n */\n this.leftDelay = this.ac.createDelay();\n /**\n * The p5.Delay is built with two\n * \n * Web Audio Delay Nodes, one for each stereo channel.\n *\n * @property {DelayNode} rightDelay\n */\n this.rightDelay = this.ac.createDelay();\n\n this._leftFilter = new Filter();\n this._rightFilter = new Filter();\n this._leftFilter.disconnect();\n this._rightFilter.disconnect();\n\n this._leftFilter.biquad.frequency.setValueAtTime(1200, this.ac.currentTime);\n this._rightFilter.biquad.frequency.setValueAtTime(1200, this.ac.currentTime);\n this._leftFilter.biquad.Q.setValueAtTime(0.3, this.ac.currentTime);\n this._rightFilter.biquad.Q.setValueAtTime(0.3, this.ac.currentTime);\n\n // graph routing\n this.input.connect(this._split);\n this.leftDelay.connect(this._leftGain);\n this.rightDelay.connect(this._rightGain);\n this._leftGain.connect(this._leftFilter.input);\n this._rightGain.connect(this._rightFilter.input);\n this._merge.connect(this.wet);\n\n\n this._leftFilter.biquad.gain.setValueAtTime(1, this.ac.currentTime);\n this._rightFilter.biquad.gain.setValueAtTime(1, this.ac.currentTime);\n\n // default routing\n this.setType(0);\n\n this._maxDelay = this.leftDelay.delayTime.maxValue;\n\n // set initial feedback to 0.5\n this.feedback(0.5);\n\n\n };\n\n p5.Delay.prototype = Object.create(Effect.prototype);\n /**\n * Add delay to an audio signal according to a set\n * of delay parameters.\n *\n * @method process\n * @for p5.Delay\n * @param {Object} Signal An object that outputs audio\n * @param {Number} [delayTime] Time (in seconds) of the delay/echo.\n * Some browsers limit delayTime to\n * 1 second.\n * @param {Number} [feedback] sends the delay back through itself\n * in a loop that decreases in volume\n * each time.\n * @param {Number} [lowPass] Cutoff frequency. Only frequencies\n * below the lowPass will be part of the\n * delay.\n */\n p5.Delay.prototype.process = function(src, _delayTime, _feedback, _filter) {\n var feedback = _feedback || 0;\n var delayTime = _delayTime || 0;\n if (feedback >= 1.0) {\n throw new Error('Feedback value will force a positive feedback loop.');\n }\n if (delayTime >= this._maxDelay) {\n throw new Error('Delay Time exceeds maximum delay time of ' + this._maxDelay + ' second.');\n }\n\n src.connect(this.input);\n this.leftDelay.delayTime.setValueAtTime(delayTime, this.ac.currentTime);\n this.rightDelay.delayTime.setValueAtTime(delayTime, this.ac.currentTime);\n this._leftGain.gain.value = feedback;\n this._rightGain.gain.value = feedback;\n\n if (_filter) {\n this._leftFilter.freq(_filter);\n this._rightFilter.freq(_filter);\n }\n };\n\n /**\n * Set the delay (echo) time, in seconds. Usually this value will be\n * a floating point number between 0.0 and 1.0.\n *\n * @method delayTime\n * @for p5.Delay\n * @param {Number} delayTime Time (in seconds) of the delay\n */\n p5.Delay.prototype.delayTime = function(t) {\n // if t is an audio node...\n if (typeof t !== 'number') {\n t.connect(this.leftDelay.delayTime);\n t.connect(this.rightDelay.delayTime);\n }\n\n else {\n this.leftDelay.delayTime.cancelScheduledValues(this.ac.currentTime);\n this.rightDelay.delayTime.cancelScheduledValues(this.ac.currentTime);\n this.leftDelay.delayTime.linearRampToValueAtTime(t, this.ac.currentTime);\n this.rightDelay.delayTime.linearRampToValueAtTime(t, this.ac.currentTime);\n }\n };\n\n /**\n * Feedback occurs when Delay sends its signal back through its input\n * in a loop. The feedback amount determines how much signal to send each\n * time through the loop. A feedback greater than 1.0 is not desirable because\n * it will increase the overall output each time through the loop,\n * creating an infinite feedback loop. The default value is 0.5\n *\n * @method feedback\n * @for p5.Delay\n * @param {Number|Object} feedback 0.0 to 1.0, or an object such as an\n * Oscillator that can be used to\n * modulate this param\n * @returns {Number} Feedback value\n *\n */\n p5.Delay.prototype.feedback = function(f) {\n // if f is an audio node...\n if (f && typeof f !== 'number') {\n f.connect(this._leftGain.gain);\n f.connect(this._rightGain.gain);\n }\n else if (f >= 1.0) {\n throw new Error('Feedback value will force a positive feedback loop.');\n }\n else if (typeof f === 'number') {\n this._leftGain.gain.value = f;\n this._rightGain.gain.value = f;\n }\n\n // return value of feedback\n return this._leftGain.gain.value;\n };\n\n /**\n * Set a lowpass filter frequency for the delay. A lowpass filter\n * will cut off any frequencies higher than the filter frequency.\n *\n * @method filter\n * @for p5.Delay\n * @param {Number|Object} cutoffFreq A lowpass filter will cut off any\n * frequencies higher than the filter frequency.\n * @param {Number|Object} res Resonance of the filter frequency\n * cutoff, or an object (i.e. a p5.Oscillator)\n * that can be used to modulate this parameter.\n * High numbers (i.e. 15) will produce a resonance,\n * low numbers (i.e. .2) will produce a slope.\n */\n p5.Delay.prototype.filter = function(freq, q) {\n this._leftFilter.set(freq, q);\n this._rightFilter.set(freq, q);\n };\n\n\n /**\n * Choose a preset type of delay. 'pingPong' bounces the signal\n * from the left to the right channel to produce a stereo effect.\n * Any other parameter will revert to the default delay setting.\n *\n * @method setType\n * @for p5.Delay\n * @param {String|Number} type 'pingPong' (1) or 'default' (0)\n */\n p5.Delay.prototype.setType = function(t) {\n if (t === 1) {\n t = 'pingPong';\n }\n this._split.disconnect();\n this._leftFilter.disconnect();\n this._rightFilter.disconnect();\n this._split.connect(this.leftDelay, 0);\n this._split.connect(this.rightDelay, 1);\n switch(t) {\n case 'pingPong':\n this._rightFilter.setType( this._leftFilter.biquad.type );\n this._leftFilter.output.connect(this._merge, 0, 0);\n this._rightFilter.output.connect(this._merge, 0, 1);\n this._leftFilter.output.connect(this.rightDelay);\n this._rightFilter.output.connect(this.leftDelay);\n break;\n default:\n this._leftFilter.output.connect(this._merge, 0, 0);\n this._rightFilter.output.connect(this._merge, 0, 1);\n this._leftFilter.output.connect(this.leftDelay);\n this._rightFilter.output.connect(this.rightDelay);\n }\n };\n\n // DocBlocks for methods inherited from p5.Effect\n /**\n * Set the output level of the delay effect.\n *\n * @method amp\n * @for p5.Delay\n * @param {Number} volume amplitude between 0 and 1.0\n * @param {Number} [rampTime] create a fade that lasts rampTime\n * @param {Number} [timeFromNow] schedule this event to happen\n * seconds from now\n */\n /**\n * Send output to a p5.sound or web audio object\n *\n * @method connect\n * @for p5.Delay\n * @param {Object} unit\n */\n /**\n * Disconnect all output.\n *\n * @method disconnect\n * @for p5.Delay\n */\n\n p5.Delay.prototype.dispose = function() {\n\n Effect.prototype.dispose.apply(this);\n\n this._split.disconnect();\n this._leftFilter.dispose();\n this._rightFilter.dispose();\n this._merge.disconnect();\n this._leftGain.disconnect();\n this._rightGain.disconnect();\n this.leftDelay.disconnect();\n this.rightDelay.disconnect();\n\n this._split = undefined;\n this._leftFilter = undefined;\n this._rightFilter = undefined;\n this._merge = undefined;\n this._leftGain = undefined;\n this._rightGain = undefined;\n this.leftDelay = undefined;\n this.rightDelay = undefined;\n };\n\n});\n","'use strict';\n\ndefine(function (require) {\n var CustomError = require('errorHandler');\n var Effect = require('effect');\n\n /**\n * Reverb adds depth to a sound through a large number of decaying\n * echoes. It creates the perception that sound is occurring in a\n * physical space. The p5.Reverb has paramters for Time (how long does the\n * reverb last) and decayRate (how much the sound decays with each echo)\n * that can be set with the .set() or .process() methods. The p5.Convolver\n * extends p5.Reverb allowing you to recreate the sound of actual physical\n * spaces through convolution.\n *\n * This class extends p5.Effect.\n * Methods amp(), chain(),\n * drywet(), connect(), and\n * disconnect() are available.\n *\n * @class p5.Reverb\n * @extends p5.Effect\n * @constructor\n * @example\n *
\n * var soundFile, reverb;\n * function preload() {\n * soundFile = loadSound('assets/Damscray_DancingTiger.mp3');\n * }\n *\n * function setup() {\n * reverb = new p5.Reverb();\n * soundFile.disconnect(); // so we'll only hear reverb...\n *\n * // connect soundFile to reverb, process w/\n * // 3 second reverbTime, decayRate of 2%\n * reverb.process(soundFile, 3, 2);\n * soundFile.play();\n * }\n *
\n */\n\n\n p5.Reverb = function() {\n Effect.call(this);\n\n this._initConvolverNode();\n\n // otherwise, Safari distorts\n this.input.gain.value = 0.5;\n\n // default params\n this._seconds = 3;\n this._decay = 2;\n this._reverse = false;\n\n this._buildImpulse();\n\n };\n\n p5.Reverb.prototype = Object.create(Effect.prototype);\n\n p5.Reverb.prototype._initConvolverNode = function() {\n this.convolverNode = this.ac.createConvolver();\n this.input.connect(this.convolverNode);\n this.convolverNode.connect(this.wet);\n };\n\n p5.Reverb.prototype._teardownConvolverNode = function() {\n if (this.convolverNode) {\n this.convolverNode.disconnect();\n delete this.convolverNode;\n }\n };\n\n p5.Reverb.prototype._setBuffer = function(audioBuffer) {\n this._teardownConvolverNode();\n this._initConvolverNode();\n this.convolverNode.buffer = audioBuffer;\n };\n /**\n * Connect a source to the reverb, and assign reverb parameters.\n *\n * @method process\n * @for p5.Reverb\n * @param {Object} src p5.sound / Web Audio object with a sound\n * output.\n * @param {Number} [seconds] Duration of the reverb, in seconds.\n * Min: 0, Max: 10. Defaults to 3.\n * @param {Number} [decayRate] Percentage of decay with each echo.\n * Min: 0, Max: 100. Defaults to 2.\n * @param {Boolean} [reverse] Play the reverb backwards or forwards.\n */\n p5.Reverb.prototype.process = function(src, seconds, decayRate, reverse) {\n src.connect(this.input);\n var rebuild = false;\n if (seconds) {\n this._seconds = seconds;\n rebuild = true;\n }\n if (decayRate) {\n this._decay = decayRate;\n }\n if (reverse) {\n this._reverse = reverse;\n }\n if (rebuild) {\n this._buildImpulse();\n }\n };\n\n /**\n * Set the reverb settings. Similar to .process(), but without\n * assigning a new input.\n *\n * @method set\n * @for p5.Reverb\n * @param {Number} [seconds] Duration of the reverb, in seconds.\n * Min: 0, Max: 10. Defaults to 3.\n * @param {Number} [decayRate] Percentage of decay with each echo.\n * Min: 0, Max: 100. Defaults to 2.\n * @param {Boolean} [reverse] Play the reverb backwards or forwards.\n */\n p5.Reverb.prototype.set = function(seconds, decayRate, reverse) {\n var rebuild = false;\n if (seconds) {\n this._seconds = seconds;\n rebuild = true;\n }\n if (decayRate) {\n this._decay = decayRate;\n }\n if (reverse) {\n this._reverse = reverse;\n }\n if (rebuild) {\n this._buildImpulse();\n }\n };\n\n // DocBlocks for methods inherited from p5.Effect\n /**\n * Set the output level of the reverb effect.\n *\n * @method amp\n * @for p5.Reverb\n * @param {Number} volume amplitude between 0 and 1.0\n * @param {Number} [rampTime] create a fade that lasts rampTime\n * @param {Number} [timeFromNow] schedule this event to happen\n * seconds from now\n */\n /**\n * Send output to a p5.sound or web audio object\n *\n * @method connect\n * @for p5.Reverb\n * @param {Object} unit\n */\n /**\n * Disconnect all output.\n *\n * @method disconnect\n * @for p5.Reverb\n */\n\n /**\n * Inspired by Simple Reverb by Jordan Santell\n * https://github.com/web-audio-components/simple-reverb/blob/master/index.js\n *\n * Utility function for building an impulse response\n * based on the module parameters.\n *\n * @private\n */\n p5.Reverb.prototype._buildImpulse = function() {\n var rate = this.ac.sampleRate;\n var length = rate*this._seconds;\n var decay = this._decay;\n var impulse = this.ac.createBuffer(2, length, rate);\n var impulseL = impulse.getChannelData(0);\n var impulseR = impulse.getChannelData(1);\n var n, i;\n for (i = 0; i < length; i++) {\n n = this._reverse ? length - i : i;\n impulseL[i] = (Math.random() * 2 - 1) * Math.pow(1 - n / length, decay);\n impulseR[i] = (Math.random() * 2 - 1) * Math.pow(1 - n / length, decay);\n }\n this._setBuffer(impulse);\n };\n\n p5.Reverb.prototype.dispose = function() {\n Effect.prototype.dispose.apply(this);\n this._teardownConvolverNode();\n };\n\n // =======================================================================\n // *** p5.Convolver ***\n // =======================================================================\n\n /**\n *
p5.Convolver extends p5.Reverb. It can emulate the sound of real\n * physical spaces through a process called \n * convolution.
\n *\n *
Convolution multiplies any audio input by an \"impulse response\"\n * to simulate the dispersion of sound over time. The impulse response is\n * generated from an audio file that you provide. One way to\n * generate an impulse response is to pop a balloon in a reverberant space\n * and record the echo. Convolution can also be used to experiment with\n * sound.
\n *\n *
Use the method createConvolution(path) to instantiate a\n * p5.Convolver with a path to your impulse response audio file.
\n *\n * @class p5.Convolver\n * @extends p5.Effect\n * @constructor\n * @param {String} path path to a sound file\n * @param {Function} [callback] function to call when loading succeeds\n * @param {Function} [errorCallback] function to call if loading fails.\n * This function will receive an error or\n * XMLHttpRequest object with information\n * about what went wrong.\n * @example\n *
\n * var cVerb, sound;\n * function preload() {\n * // We have both MP3 and OGG versions of all sound assets\n * soundFormats('ogg', 'mp3');\n *\n * // Try replacing 'bx-spring' with other soundfiles like\n * // 'concrete-tunnel' 'small-plate' 'drum' 'beatbox'\n * cVerb = createConvolver('assets/bx-spring.mp3');\n *\n * // Try replacing 'Damscray_DancingTiger' with\n * // 'beat', 'doorbell', lucky_dragons_-_power_melody'\n * sound = loadSound('assets/Damscray_DancingTiger.mp3');\n * }\n *\n * function setup() {\n * // disconnect from master output...\n * sound.disconnect();\n *\n * // ...and process with cVerb\n * // so that we only hear the convolution\n * cVerb.process(sound);\n *\n * sound.play();\n * }\n *
\n */\n p5.Convolver = function(path, callback, errorCallback) {\n \t p5.Reverb.call(this);\n\n /**\n * Internally, the p5.Convolver uses the a\n * \n * Web Audio Convolver Node.\n *\n * @property {ConvolverNode} convolverNode\n */\n this._initConvolverNode();\n\n // otherwise, Safari distorts\n this.input.gain.value = 0.5;\n\n if (path) {\n this.impulses = [];\n this._loadBuffer(path, callback, errorCallback);\n }\n else {\n // parameters\n this._seconds = 3;\n this._decay = 2;\n this._reverse = false;\n\n this._buildImpulse();\n }\n\n };\n\n p5.Convolver.prototype = Object.create(p5.Reverb.prototype);\n\n p5.prototype.registerPreloadMethod('createConvolver', p5.prototype);\n\n /**\n * Create a p5.Convolver. Accepts a path to a soundfile\n * that will be used to generate an impulse response.\n *\n * @method createConvolver\n * @for p5\n * @param {String} path path to a sound file\n * @param {Function} [callback] function to call if loading is successful.\n * The object will be passed in as the argument\n * to the callback function.\n * @param {Function} [errorCallback] function to call if loading is not successful.\n * A custom error will be passed in as the argument\n * to the callback function.\n * @return {p5.Convolver}\n * @example\n *
\n * var cVerb, sound;\n * function preload() {\n * // We have both MP3 and OGG versions of all sound assets\n * soundFormats('ogg', 'mp3');\n *\n * // Try replacing 'bx-spring' with other soundfiles like\n * // 'concrete-tunnel' 'small-plate' 'drum' 'beatbox'\n * cVerb = createConvolver('assets/bx-spring.mp3');\n *\n * // Try replacing 'Damscray_DancingTiger' with\n * // 'beat', 'doorbell', lucky_dragons_-_power_melody'\n * sound = loadSound('assets/Damscray_DancingTiger.mp3');\n * }\n *\n * function setup() {\n * // disconnect from master output...\n * sound.disconnect();\n *\n * // ...and process with cVerb\n * // so that we only hear the convolution\n * cVerb.process(sound);\n *\n * sound.play();\n * }\n *
\n */\n p5.prototype.createConvolver = function(path, callback, errorCallback) {\n // if loading locally without a server\n if (window.location.origin.indexOf('file://') > -1 && window.cordova === 'undefined') {\n alert('This sketch may require a server to load external files. Please see http://bit.ly/1qcInwS');\n }\n var self = this;\n var cReverb = new p5.Convolver(path, function(buffer) {\n if (typeof callback === 'function') {\n callback(buffer);\n }\n\n if (typeof self._decrementPreload === 'function') {\n self._decrementPreload();\n }\n }, errorCallback);\n cReverb.impulses = [];\n return cReverb;\n };\n\n /**\n * Private method to load a buffer as an Impulse Response,\n * assign it to the convolverNode, and add to the Array of .impulses.\n *\n * @param {String} path\n * @param {Function} callback\n * @param {Function} errorCallback\n * @private\n */\n p5.Convolver.prototype._loadBuffer = function(path, callback, errorCallback) {\n var path = p5.prototype._checkFileFormats(path);\n var self = this;\n var errorTrace = new Error().stack;\n var ac = p5.prototype.getAudioContext();\n\n var request = new XMLHttpRequest();\n request.open('GET', path, true);\n request.responseType = 'arraybuffer';\n\n request.onload = function() {\n if (request.status === 200) {\n // on success loading file:\n ac.decodeAudioData(request.response,\n function(buff) {\n var buffer = {};\n var chunks = path.split('/');\n buffer.name = chunks[chunks.length - 1];\n buffer.audioBuffer = buff;\n self.impulses.push(buffer);\n self._setBuffer(buffer.audioBuffer);\n if (callback) {\n callback(buffer);\n }\n },\n // error decoding buffer. \"e\" is undefined in Chrome 11/22/2015\n function() {\n var err = new CustomError('decodeAudioData', errorTrace, self.url);\n var msg = 'AudioContext error at decodeAudioData for ' + self.url;\n if (errorCallback) {\n err.msg = msg;\n errorCallback(err);\n } else {\n console.error(msg +'\\n The error stack trace includes: \\n' + err.stack);\n }\n }\n );\n }\n // if request status != 200, it failed\n else {\n var err = new CustomError('loadConvolver', errorTrace, self.url);\n var msg = 'Unable to load ' + self.url +\n '. The request status was: ' + request.status + ' (' + request.statusText + ')';\n\n if (errorCallback) {\n err.message = msg;\n errorCallback(err);\n } else {\n console.error(msg +'\\n The error stack trace includes: \\n' + err.stack);\n }\n }\n };\n\n // if there is another error, aside from 404...\n request.onerror = function() {\n var err = new CustomError('loadConvolver', errorTrace, self.url);\n var msg = 'There was no response from the server at ' + self.url + '. Check the url and internet connectivity.';\n\n if (errorCallback) {\n err.message = msg;\n errorCallback(err);\n } else {\n console.error(msg +'\\n The error stack trace includes: \\n' + err.stack);\n }\n };\n request.send();\n };\n\n p5.Convolver.prototype.set = null;\n\n /**\n * Connect a source to the reverb, and assign reverb parameters.\n *\n * @method process\n * @for p5.Convolver\n * @param {Object} src p5.sound / Web Audio object with a sound\n * output.\n * @example\n *
\n * var cVerb, sound;\n * function preload() {\n * soundFormats('ogg', 'mp3');\n *\n * cVerb = createConvolver('assets/concrete-tunnel.mp3');\n *\n * sound = loadSound('assets/beat.mp3');\n * }\n *\n * function setup() {\n * // disconnect from master output...\n * sound.disconnect();\n *\n * // ...and process with (i.e. connect to) cVerb\n * // so that we only hear the convolution\n * cVerb.process(sound);\n *\n * sound.play();\n * }\n *
\n */\n p5.Convolver.prototype.process = function(src) {\n src.connect(this.input);\n };\n\n /**\n * If you load multiple impulse files using the .addImpulse method,\n * they will be stored as Objects in this Array. Toggle between them\n * with the toggleImpulse(id) method.\n *\n * @property {Array} impulses\n * @for p5.Convolver\n */\n p5.Convolver.prototype.impulses = [];\n\n /**\n * Load and assign a new Impulse Response to the p5.Convolver.\n * The impulse is added to the .impulses array. Previous\n * impulses can be accessed with the .toggleImpulse(id)\n * method.\n *\n * @method addImpulse\n * @for p5.Convolver\n * @param {String} path path to a sound file\n * @param {Function} callback function (optional)\n * @param {Function} errorCallback function (optional)\n */\n p5.Convolver.prototype.addImpulse = function(path, callback, errorCallback) {\n // if loading locally without a server\n if (window.location.origin.indexOf('file://') > -1 && window.cordova === 'undefined') {\n alert('This sketch may require a server to load external files. Please see http://bit.ly/1qcInwS');\n }\n this._loadBuffer(path, callback, errorCallback);\n };\n\n /**\n * Similar to .addImpulse, except that the .impulses\n * Array is reset to save memory. A new .impulses\n * array is created with this impulse as the only item.\n *\n * @method resetImpulse\n * @for p5.Convolver\n * @param {String} path path to a sound file\n * @param {Function} callback function (optional)\n * @param {Function} errorCallback function (optional)\n */\n p5.Convolver.prototype.resetImpulse = function(path, callback, errorCallback) {\n // if loading locally without a server\n if (window.location.origin.indexOf('file://') > -1 && window.cordova === 'undefined') {\n alert('This sketch may require a server to load external files. Please see http://bit.ly/1qcInwS');\n }\n this.impulses = [];\n this._loadBuffer(path, callback, errorCallback);\n };\n\n /**\n * If you have used .addImpulse() to add multiple impulses\n * to a p5.Convolver, then you can use this method to toggle between\n * the items in the .impulses Array. Accepts a parameter\n * to identify which impulse you wish to use, identified either by its\n * original filename (String) or by its position in the .impulses\n * Array (Number). \n * You can access the objects in the .impulses Array directly. Each\n * Object has two attributes: an .audioBuffer (type:\n * Web Audio \n * AudioBuffer) and a .name, a String that corresponds\n * with the original filename.\n *\n * @method toggleImpulse\n * @for p5.Convolver\n * @param {String|Number} id Identify the impulse by its original filename\n * (String), or by its position in the\n * .impulses Array (Number).\n */\n p5.Convolver.prototype.toggleImpulse = function(id) {\n if (typeof id === 'number' && id < this.impulses.length) {\n this._setBuffer(this.impulses[id].audioBuffer);\n }\n if (typeof id === 'string') {\n for (var i = 0; i < this.impulses.length; i++) {\n if (this.impulses[i].name === id) {\n this._setBuffer(this.impulses[i].audioBuffer);\n break;\n }\n }\n }\n };\n\n p5.Convolver.prototype.dispose = function() {\n p5.Reverb.prototype.dispose.apply(this);\n\n // remove all the Impulse Response buffers\n for (var i in this.impulses) {\n if (this.impulses[i]) {\n this.impulses[i] = null;\n }\n }\n };\n\n});\n","'use strict';\n\ndefine(function (require) {\n var p5sound = require('master');\n\n // requires the Tone.js library's Clock (MIT license, Yotam Mann)\n // https://github.com/TONEnoTONE/Tone.js/\n var Clock = require('Tone/core/Clock');\n\n p5.Metro = function() {\n this.clock = new Clock({\n 'callback': this.ontick.bind(this)\n });\n this.syncedParts = [];\n this.bpm = 120; // gets overridden by p5.Part\n this._init();\n\n this.prevTick = 0;\n this.tatumTime = 0;\n\n this.tickCallback = function() {};\n };\n\n p5.Metro.prototype.ontick = function(tickTime) {\n var elapsedTime = tickTime - this.prevTick;\n var secondsFromNow = tickTime - p5sound.audiocontext.currentTime;\n if (elapsedTime - this.tatumTime <= -0.02) {\n return;\n } else {\n // console.log('ok', this.syncedParts[0].phrases[0].name);\n this.prevTick = tickTime;\n\n // for all of the active things on the metro:\n var self = this;\n this.syncedParts.forEach(function(thisPart) {\n if (!thisPart.isPlaying) return;\n thisPart.incrementStep(secondsFromNow);\n // each synced source keeps track of its own beat number\n thisPart.phrases.forEach(function(thisPhrase) {\n var phraseArray = thisPhrase.sequence;\n var bNum = self.metroTicks % phraseArray.length;\n if (phraseArray[bNum] !== 0 && (self.metroTicks < phraseArray.length || !thisPhrase.looping) ) {\n thisPhrase.callback(secondsFromNow, phraseArray[bNum]);\n }\n });\n });\n this.metroTicks += 1;\n this.tickCallback(secondsFromNow);\n }\n };\n\n p5.Metro.prototype.setBPM = function(bpm, rampTime) {\n var beatTime = 60 / (bpm*this.tatums);\n var now = p5sound.audiocontext.currentTime;\n this.tatumTime = beatTime;\n\n var rampTime = rampTime || 0;\n this.clock.frequency.setValueAtTime(this.clock.frequency.value, now);\n this.clock.frequency.linearRampToValueAtTime(bpm, now + rampTime);\n this.bpm = bpm;\n };\n\n p5.Metro.prototype.getBPM = function() {\n return this.clock.getRate() / this.tatums * 60;\n };\n\n p5.Metro.prototype._init = function() {\n this.metroTicks = 0;\n // this.setBPM(120);\n };\n\n // clear existing synced parts, add only this one\n p5.Metro.prototype.resetSync = function(part) {\n this.syncedParts = [part];\n };\n\n // push a new synced part to the array\n p5.Metro.prototype.pushSync = function(part) {\n this.syncedParts.push(part);\n };\n\n p5.Metro.prototype.start = function(timeFromNow) {\n var t = timeFromNow || 0;\n var now = p5sound.audiocontext.currentTime;\n this.clock.start(now + t);\n this.setBPM(this.bpm);\n };\n\n p5.Metro.prototype.stop = function(timeFromNow) {\n var t = timeFromNow || 0;\n var now = p5sound.audiocontext.currentTime;\n this.clock.stop(now + t);\n };\n\n p5.Metro.prototype.beatLength = function(tatums) {\n this.tatums = 1/tatums / 4; // lowest possible division of a beat\n };\n\n});\n","define([\"Tone/core/Tone\", \"Tone/core/Timeline\", \"Tone/type/Type\"], function (Tone) {\n\n\t\"use strict\";\n\n\t/**\n\t * @class A Timeline State. Provides the methods: setStateAtTime(\"state\", time)\n\t * and getValueAtTime(time).\n\t *\n\t * @extends {Tone.Timeline}\n\t * @param {String} initial The initial state of the TimelineState. \n\t * Defaults to undefined\n\t */\n\tTone.TimelineState = function(initial){\n\n\t\tTone.Timeline.call(this);\n\n\t\t/**\n\t\t * The initial state\n\t\t * @private\n\t\t * @type {String}\n\t\t */\n\t\tthis._initial = initial;\n\t};\n\n\tTone.extend(Tone.TimelineState, Tone.Timeline);\n\n\t/**\n\t * Returns the scheduled state scheduled before or at\n\t * the given time.\n\t * @param {Number} time The time to query.\n\t * @return {String} The name of the state input in setStateAtTime.\n\t */\n\tTone.TimelineState.prototype.getValueAtTime = function(time){\n\t\tvar event = this.get(time);\n\t\tif (event !== null){\n\t\t\treturn event.state;\n\t\t} else {\n\t\t\treturn this._initial;\n\t\t}\n\t};\n\n\t/**\n\t * Returns the scheduled state scheduled before or at\n\t * the given time.\n\t * @param {String} state The name of the state to set.\n\t * @param {Number} time The time to query.\n\t */\n\tTone.TimelineState.prototype.setStateAtTime = function(state, time){\n\t\tthis.add({\n\t\t\t\"state\" : state,\n\t\t\t\"time\" : time\n\t\t});\n\t};\n\n\treturn Tone.TimelineState;\n});","'use strict';\n\ndefine(function(require) {\n var p5sound = require('master');\n\n var BPM = 120;\n\n /**\n * Set the global tempo, in beats per minute, for all\n * p5.Parts. This method will impact all active p5.Parts.\n *\n * @method setBPM\n * @for p5\n * @param {Number} BPM Beats Per Minute\n * @param {Number} rampTime Seconds from now\n */\n p5.prototype.setBPM = function(bpm, rampTime) {\n BPM = bpm;\n for (var i in p5sound.parts) {\n if (p5sound.parts[i]) {\n p5sound.parts[i].setBPM(bpm, rampTime);\n }\n }\n };\n\n /**\n *
A phrase is a pattern of musical events over time, i.e.\n * a series of notes and rests.
\n *\n *
Phrases must be added to a p5.Part for playback, and\n * each part can play multiple phrases at the same time.\n * For example, one Phrase might be a kick drum, another\n * could be a snare, and another could be the bassline.
\n *\n *
The first parameter is a name so that the phrase can be\n * modified or deleted later. The callback is a a function that\n * this phrase will call at every step—for example it might be\n * called playNote(value){}. The array determines\n * which value is passed into the callback at each step of the\n * phrase. It can be numbers, an object with multiple numbers,\n * or a zero (0) indicates a rest so the callback won't be called).
\n *\n * @class p5.Phrase\n * @constructor\n * @param {String} name Name so that you can access the Phrase.\n * @param {Function} callback The name of a function that this phrase\n * will call. Typically it will play a sound,\n * and accept two parameters: a time at which\n * to play the sound (in seconds from now),\n * and a value from the sequence array. The\n * time should be passed into the play() or\n * start() method to ensure precision.\n * @param {Array} sequence Array of values to pass into the callback\n * at each step of the phrase.\n * @example\n *
\n */\n p5.Phrase = function(name, callback, sequence) {\n this.phraseStep = 0;\n this.name = name;\n this.callback = callback;\n /**\n * Array of values to pass into the callback\n * at each step of the phrase. Depending on the callback\n * function's requirements, these values may be numbers,\n * strings, or an object with multiple parameters.\n * Zero (0) indicates a rest.\n *\n * @property {Array} sequence\n */\n this.sequence = sequence;\n };\n\n /**\n *
A p5.Part plays back one or more p5.Phrases. Instantiate a part\n * with steps and tatums. By default, each step represents a 1/16th note.
\n *\n *
See p5.Phrase for more about musical timing.
\n *\n * @class p5.Part\n * @constructor\n * @param {Number} [steps] Steps in the part\n * @param {Number} [tatums] Divisions of a beat, e.g. use 1/4, or 0.25 for a quater note (default is 1/16, a sixteenth note)\n * @example\n *
\n * var box, drum, myPart;\n * var boxPat = [1,0,0,2,0,2,0,0];\n * var drumPat = [0,1,1,0,2,0,1,0];\n * var msg = 'click to play';\n *\n * function preload() {\n * box = loadSound('assets/beatbox.mp3');\n * drum = loadSound('assets/drum.mp3');\n * }\n *\n * function setup() {\n * noStroke();\n * fill(255);\n * textAlign(CENTER);\n * masterVolume(0.1);\n *\n * var boxPhrase = new p5.Phrase('box', playBox, boxPat);\n * var drumPhrase = new p5.Phrase('drum', playDrum, drumPat);\n * myPart = new p5.Part();\n * myPart.addPhrase(boxPhrase);\n * myPart.addPhrase(drumPhrase);\n * myPart.setBPM(60);\n * masterVolume(0.1);\n * }\n *\n * function draw() {\n * background(0);\n * text(msg, width/2, height/2);\n * }\n *\n * function playBox(time, playbackRate) {\n * box.rate(playbackRate);\n * box.play(time);\n * }\n *\n * function playDrum(time, playbackRate) {\n * drum.rate(playbackRate);\n * drum.play(time);\n * }\n *\n * function mouseClicked() {\n * if (mouseX > 0 && mouseX < width && mouseY > 0 && mouseY < height) {\n * myPart.start();\n * msg = 'playing part';\n * }\n * }\n *
\n */\n p5.Part = function(steps, bLength) {\n this.length = steps || 0; // how many beats\n this.partStep = 0;\n this.phrases = [];\n this.isPlaying = false;\n this.noLoop();\n this.tatums = bLength || 0.0625; // defaults to quarter note\n\n this.metro = new p5.Metro();\n this.metro._init();\n this.metro.beatLength(this.tatums);\n this.metro.setBPM(BPM);\n p5sound.parts.push(this);\n this.callback = function() {};\n };\n\n /**\n * Set the tempo of this part, in Beats Per Minute.\n *\n * @method setBPM\n * @for p5.Part\n * @param {Number} BPM Beats Per Minute\n * @param {Number} [rampTime] Seconds from now\n */\n p5.Part.prototype.setBPM = function(tempo, rampTime) {\n this.metro.setBPM(tempo, rampTime);\n };\n\n /**\n * Returns the tempo, in Beats Per Minute, of this part.\n *\n * @method getBPM\n * @for p5.Part\n * @return {Number}\n */\n p5.Part.prototype.getBPM = function() {\n return this.metro.getBPM();\n };\n\n /**\n * Start playback of this part. It will play\n * through all of its phrases at a speed\n * determined by setBPM.\n *\n * @method start\n * @for p5.Part\n * @param {Number} [time] seconds from now\n */\n p5.Part.prototype.start = function(time) {\n if (!this.isPlaying) {\n this.isPlaying = true;\n this.metro.resetSync(this);\n var t = time || 0;\n this.metro.start(t);\n }\n };\n\n /**\n * Loop playback of this part. It will begin\n * looping through all of its phrases at a speed\n * determined by setBPM.\n *\n * @method loop\n * @for p5.Part\n * @param {Number} [time] seconds from now\n */\n p5.Part.prototype.loop = function(time) {\n this.looping = true;\n // rest onended function\n this.onended = function() {\n this.partStep = 0;\n };\n var t = time || 0;\n this.start(t);\n };\n\n /**\n * Tell the part to stop looping.\n *\n * @method noLoop\n * @for p5.Part\n */\n p5.Part.prototype.noLoop = function() {\n this.looping = false;\n // rest onended function\n this.onended = function() {\n this.stop();\n };\n };\n\n /**\n * Stop the part and cue it to step 0. Playback will resume from the begining of the Part when it is played again.\n *\n * @method stop\n * @for p5.Part\n * @param {Number} [time] seconds from now\n */\n p5.Part.prototype.stop = function(time) {\n this.partStep = 0;\n this.pause(time);\n };\n\n /**\n * Pause the part. Playback will resume\n * from the current step.\n *\n * @method pause\n * @for p5.Part\n * @param {Number} time seconds from now\n */\n p5.Part.prototype.pause = function(time) {\n this.isPlaying = false;\n var t = time || 0;\n this.metro.stop(t);\n };\n\n /**\n * Add a p5.Phrase to this Part.\n *\n * @method addPhrase\n * @for p5.Part\n * @param {p5.Phrase} phrase reference to a p5.Phrase\n */\n p5.Part.prototype.addPhrase = function(name, callback, array) {\n var p;\n if (arguments.length === 3) {\n p = new p5.Phrase(name, callback, array);\n } else if (arguments[0] instanceof p5.Phrase) {\n p = arguments[0];\n } else {\n throw 'invalid input. addPhrase accepts name, callback, array or a p5.Phrase';\n }\n this.phrases.push(p);\n // reset the length if phrase is longer than part's existing length\n if (p.sequence.length > this.length) {\n this.length = p.sequence.length;\n }\n };\n\n /**\n * Remove a phrase from this part, based on the name it was\n * given when it was created.\n *\n * @method removePhrase\n * @for p5.Part\n * @param {String} phraseName\n */\n p5.Part.prototype.removePhrase = function(name) {\n for (var i in this.phrases) {\n if (this.phrases[i].name === name) {\n this.phrases.splice(i, 1);\n }\n }\n };\n\n /**\n * Get a phrase from this part, based on the name it was\n * given when it was created. Now you can modify its array.\n *\n * @method getPhrase\n * @for p5.Part\n * @param {String} phraseName\n */\n p5.Part.prototype.getPhrase = function(name) {\n for (var i in this.phrases) {\n if (this.phrases[i].name === name) {\n return this.phrases[i];\n }\n }\n };\n\n /**\n * Find all sequences with the specified name, and replace their patterns with the specified array.\n *\n * @method replaceSequence\n * @for p5.Part\n * @param {String} phraseName\n * @param {Array} sequence Array of values to pass into the callback\n * at each step of the phrase.\n */\n p5.Part.prototype.replaceSequence = function(name, array) {\n for (var i in this.phrases) {\n if (this.phrases[i].name === name) {\n this.phrases[i].sequence = array;\n }\n }\n };\n\n p5.Part.prototype.incrementStep = function(time) {\n if (this.partStep < this.length - 1) {\n this.callback(time);\n this.partStep += 1;\n } else {\n if (!this.looping && this.partStep === this.length - 1) {\n console.log('done');\n // this.callback(time);\n this.onended();\n }\n }\n };\n\n /**\n * Set the function that will be called at every step. This will clear the previous function.\n *\n * @method onStep\n * @for p5.Part\n * @param {Function} callback The name of the callback\n * you want to fire\n * on every beat/tatum.\n */\n p5.Part.prototype.onStep = function(callback) {\n this.callback = callback;\n };\n\n\n // ===============\n // p5.Score\n // ===============\n\n /**\n * A Score consists of a series of Parts. The parts will\n * be played back in order. For example, you could have an\n * A part, a B part, and a C part, and play them back in this order\n * new p5.Score(a, a, b, a, c)\n *\n * @class p5.Score\n * @constructor\n * @param {p5.Part} [...parts] One or multiple parts, to be played in sequence.\n */\n p5.Score = function() {\n // for all of the arguments\n this.parts = [];\n this.currentPart = 0;\n\n var thisScore = this;\n for (var i in arguments) {\n if (arguments[i] && this.parts[i]) {\n this.parts[i] = arguments[i];\n this.parts[i].nextPart = this.parts[i + 1];\n this.parts[i].onended = function() {\n thisScore.resetPart(i);\n playNextPart(thisScore);\n };\n }\n }\n this.looping = false;\n };\n\n p5.Score.prototype.onended = function() {\n if (this.looping) {\n // this.resetParts();\n this.parts[0].start();\n } else {\n this.parts[this.parts.length - 1].onended = function() {\n this.stop();\n this.resetParts();\n };\n }\n this.currentPart = 0;\n };\n\n /**\n * Start playback of the score.\n *\n * @method start\n * @for p5.Score\n */\n p5.Score.prototype.start = function() {\n this.parts[this.currentPart].start();\n this.scoreStep = 0;\n };\n\n /**\n * Stop playback of the score.\n *\n * @method stop\n * @for p5.Score\n */\n p5.Score.prototype.stop = function() {\n this.parts[this.currentPart].stop();\n this.currentPart = 0;\n this.scoreStep = 0;\n };\n\n /**\n * Pause playback of the score.\n *\n * @method pause\n * @for p5.Score\n */\n p5.Score.prototype.pause = function() {\n this.parts[this.currentPart].stop();\n };\n\n /**\n * Loop playback of the score.\n *\n * @method loop\n * @for p5.Score\n */\n p5.Score.prototype.loop = function() {\n this.looping = true;\n this.start();\n };\n\n /**\n * Stop looping playback of the score. If it\n * is currently playing, this will go into effect\n * after the current round of playback completes.\n *\n * @method noLoop\n * @for p5.Score\n */\n p5.Score.prototype.noLoop = function() {\n this.looping = false;\n };\n\n p5.Score.prototype.resetParts = function() {\n var self = this;\n this.parts.forEach(function(part) {\n self.resetParts[part];\n });\n };\n\n p5.Score.prototype.resetPart = function(i) {\n this.parts[i].stop();\n this.parts[i].partStep = 0;\n for (var p in this.parts[i].phrases) {\n if (this.parts[i]) {\n this.parts[i].phrases[p].phraseStep = 0;\n }\n }\n };\n\n /**\n * Set the tempo for all parts in the score\n *\n * @method setBPM\n * @for p5.Score\n * @param {Number} BPM Beats Per Minute\n * @param {Number} rampTime Seconds from now\n */\n p5.Score.prototype.setBPM = function(bpm, rampTime) {\n for (var i in this.parts) {\n if (this.parts[i]) {\n this.parts[i].setBPM(bpm, rampTime);\n }\n }\n };\n\n function playNextPart(aScore) {\n aScore.currentPart++;\n if (aScore.currentPart >= aScore.parts.length) {\n aScore.scoreStep = 0;\n aScore.onended();\n } else {\n aScore.scoreStep = 0;\n aScore.parts[aScore.currentPart - 1].stop();\n aScore.parts[aScore.currentPart].start();\n }\n }\n\n});\n","'use strict';\n\ndefine(function (require) {\n var p5sound = require('master');\n var Clock = require('Tone/core/Clock');\n\n /**\n * SoundLoop\n *\n * @class p5.SoundLoop\n * @constructor\n *\n * @param {Function} callback this function will be called on each iteration of theloop\n * @param {Number|String} [interval] amount of time or beats for each iteration of the loop\n * defaults to 1\n *\n * @example\n *
\n * var click;\n * var looper1;\n *\n * function preload() {\n * click = loadSound('assets/drum.mp3');\n * }\n *\n * function setup() {\n * //the looper's callback is passed the timeFromNow\n * //this value should be used as a reference point from\n * //which to schedule sounds\n * looper1 = new p5.SoundLoop(function(timeFromNow){\n * click.play(timeFromNow);\n * background(255 * (looper1.iterations % 2));\n * }, 2);\n *\n * //stop after 10 iteratios;\n * looper1.maxIterations = 10;\n * //start the loop\n * looper1.start();\n * }\n *
\n */\n p5.SoundLoop = function(callback, interval) {\n this.callback = callback;\n /**\n * musicalTimeMode uses Tone.Time convention\n\t * true if string, false if number\n * @property {Boolean} musicalTimeMode\n */\n this.musicalTimeMode = typeof this._interval === 'number' ? false : true;\n\n this._interval = interval || 1;\n\n /**\n * musicalTimeMode variables\n * modify these only when the interval is specified in musicalTime format as a string\n */\n this._timeSignature = 4;\n this._bpm = 60;\n\n this.isPlaying = false;\n\n /**\n * Set a limit to the number of loops to play. defaults to Infinity\n * @property {Number} maxIterations\n */\n this.maxIterations = Infinity;\n var self = this;\n\n this.clock = new Clock({\n 'callback' : function(time) {\n var timeFromNow = time - p5sound.audiocontext.currentTime;\n /**\n * Do not initiate the callback if timeFromNow is < 0\n * This ususually occurs for a few milliseconds when the page\n * is not fully loaded\n *\n * The callback should only be called until maxIterations is reached\n */\n if (timeFromNow > 0 && self.iterations <= self.maxIterations) {\n self.callback(timeFromNow);}\n },\n 'frequency' : this._calcFreq()\n });\n };\n\n /**\n * Start the loop\n * @method start\n * @for p5.SoundLoop\n * @param {Number} [timeFromNow] schedule a starting time\n */\n p5.SoundLoop.prototype.start = function(timeFromNow) {\n var t = timeFromNow || 0;\n var now = p5sound.audiocontext.currentTime;\n if (!this.isPlaying) {\n this.clock.start(now + t);\n this.isPlaying = true;\n }\n };\n\n /**\n * Stop the loop\n * @method stop\n * @for p5.SoundLoop\n * @param {Number} [timeFromNow] schedule a stopping time\n */\n p5.SoundLoop.prototype.stop = function(timeFromNow) {\n var t = timeFromNow || 0;\n var now = p5sound.audiocontext.currentTime;\n if (this.isPlaying) {\n this.clock.stop(now + t);\n this.isPlaying = false;\n }\n };\n /**\n * Pause the loop\n * @method pause\n * @for p5.SoundLoop\n * @param {Number} [timeFromNow] schedule a pausing time\n */\n p5.SoundLoop.prototype.pause = function(timeFromNow) {\n var t = timeFromNow || 0;\n var now = p5sound.audiocontext.currentTime;\n if (this.isPlaying) {\n this.clock.pause(now + t);\n this.isPlaying = false;\n }\n };\n\n\n /**\n * Synchronize loops. Use this method to start two more more loops in synchronization\n * or to start a loop in synchronization with a loop that is already playing\n * This method will schedule the implicit loop in sync with the explicit master loop\n * i.e. loopToStart.syncedStart(loopToSyncWith)\n *\n * @method syncedStart\n * @for p5.SoundLoop\n * @param {Object} otherLoop a p5.SoundLoop to sync with\n * @param {Number} [timeFromNow] Start the loops in sync after timeFromNow seconds\n */\n p5.SoundLoop.prototype.syncedStart = function(otherLoop, timeFromNow) {\n var t = timeFromNow || 0;\n var now = p5sound.audiocontext.currentTime;\n\n if (!otherLoop.isPlaying) {\n otherLoop.clock.start(now + t);\n otherLoop.isPlaying = true;\n this.clock.start(now + t);\n this.isPlaying = true;\n } else if (otherLoop.isPlaying) {\n var time = otherLoop.clock._nextTick - p5sound.audiocontext.currentTime;\n this.clock.start(now + time);\n this.isPlaying = true;\n }\n };\n\n\n /**\n * Updates frequency value, reflected in next callback\n * @private\n * @for p5.SoundLoop\n * @method _update\n */\n p5.SoundLoop.prototype._update = function() {\n this.clock.frequency.value = this._calcFreq();\n };\n\n /**\n * Calculate the frequency of the clock's callback based on bpm, interval, and timesignature\n * @private\n * @for p5.SoundLoop\n * @method _calcFreq\n * @return {Number} new clock frequency value\n */\n p5.SoundLoop.prototype._calcFreq = function() {\n //Seconds mode, bpm / timesignature has no effect\n if (typeof this._interval === 'number') {\n this.musicalTimeMode = false;\n return 1 / this._interval;\n }\n //Musical timing mode, calculate interval based bpm, interval,and time signature\n else if (typeof this._interval === 'string') {\n this.musicalTimeMode = true;\n return this._bpm / 60 / this._convertNotation(this._interval) * (this._timeSignature / 4);\n }\n };\n\n /**\n * Convert notation from musical time format to seconds\n * Uses Tone.Time convention\n * @private\n * @for p5.SoundLoop\n * @method _convertNotation\n * @param {String} value value to be converted\n * @return {Number} converted value in seconds\n */\n p5.SoundLoop.prototype._convertNotation = function(value) {\n var type = value.slice(-1);\n value = Number(value.slice(0,-1));\n switch (type) {\n case 'm':\n return this._measure(value);\n case 'n':\n return this._note(value);\n default:\n console.warn('Specified interval is not formatted correctly. See Tone.js '+\n 'timing reference for more info: https://github.com/Tonejs/Tone.js/wiki/Time');\n }\n };\n\n /**\n * Helper conversion methods of measure and note\n * @private\n * @for p5.SoundLoop\n * @method _measure\n */\n p5.SoundLoop.prototype._measure = function(value) {\n return value * this._timeSignature;\n };\n\n /**\n * @private\n * @method _note\n * @for p5.SoundLoop\n */\n p5.SoundLoop.prototype._note = function(value) {\n return this._timeSignature / value ;\n };\n\n\n /**\n * Getters and Setters, setting any paramter will result in a change in the clock's\n * frequency, that will be reflected after the next callback\n * beats per minute (defaults to 60)\n * @property {Number} bpm\n * @for p5.SoundLoop\n */\n Object.defineProperty(p5.SoundLoop.prototype, 'bpm', {\n get : function() {\n return this._bpm;\n },\n set : function(bpm) {\n if (!this.musicalTimeMode) {\n console.warn('Changing the BPM in \"seconds\" mode has no effect. '+\n 'BPM is only relevant in musicalTimeMode '+\n 'when the interval is specified as a string '+\n '(\"2n\", \"4n\", \"1m\"...etc)');\n }\n this._bpm = bpm;\n this._update();\n }\n });\n\n /**\n * number of quarter notes in a measure (defaults to 4)\n * @property {Number} timeSignature\n * @for p5.SoundLoop\n */\n Object.defineProperty(p5.SoundLoop.prototype, 'timeSignature', {\n get : function() {\n return this._timeSignature;\n },\n set : function(timeSig) {\n if (!this.musicalTimeMode) {\n console.warn('Changing the timeSignature in \"seconds\" mode has no effect. '+\n 'BPM is only relevant in musicalTimeMode '+\n 'when the interval is specified as a string '+\n '(\"2n\", \"4n\", \"1m\"...etc)');\n }\n this._timeSignature = timeSig;\n this._update();\n }\n });\n\n /**\n * length of the loops interval\n * @property {Number|String} interval\n * @for p5.SoundLoop\n */\n Object.defineProperty(p5.SoundLoop.prototype, 'interval', {\n get : function() {\n return this._interval;\n },\n set : function(interval) {\n this.musicalTimeMode = typeof interval === 'Number'? false : true;\n this._interval = interval;\n this._update();\n }\n });\n\n /**\n * how many times the callback has been called so far\n * @property {Number} iterations\n * @for p5.SoundLoop\n * @readonly\n */\n Object.defineProperty(p5.SoundLoop.prototype, 'iterations', {\n get : function() {\n return this.clock.ticks;\n }\n });\n\n return p5.SoundLoop;\n});\n","define(function (require) {\n\t'use strict';\n\n\tvar p5sound = require('master');\n\tvar Effect = require('effect');\n var CustomError = require('errorHandler');\n\n /**\n * Compressor is an audio effect class that performs dynamics compression\n * on an audio input source. This is a very commonly used technique in music\n * and sound production. Compression creates an overall louder, richer,\n * and fuller sound by lowering the volume of louds and raising that of softs.\n * Compression can be used to avoid clipping (sound distortion due to\n * peaks in volume) and is especially useful when many sounds are played\n * at once. Compression can be used on indivudal sound sources in addition\n * to the master output.\n *\n * This class extends p5.Effect.\n * Methods amp(), chain(),\n * drywet(), connect(), and\n * disconnect() are available.\n *\n * @class p5.Compressor\n * @constructor\n * @extends p5.Effect\n *\n *\n */\n\tp5.Compressor = function() {\n\t\tEffect.call(this);\n\n /**\n * The p5.Compressor is built with a Web Audio Dynamics Compressor Node\n * \n * @property {AudioNode} compressor\n */\n\n\n\t\tthis.compressor = this.ac.createDynamicsCompressor();\n\n this.input.connect(this.compressor);\n this.compressor.connect(this.wet);\n\t};\n\n\tp5.Compressor.prototype = Object.create(Effect.prototype);\n\n /**\n * Performs the same function as .connect, but also accepts\n * optional parameters to set compressor's audioParams\n * @method process\n * @for p5.Compressor\n *\n * @param {Object} src Sound source to be connected\n *\n * @param {Number} [attack] The amount of time (in seconds) to reduce the gain by 10dB,\n * default = .003, range 0 - 1\n * @param {Number} [knee] A decibel value representing the range above the\n * threshold where the curve smoothly transitions to the \"ratio\" portion.\n * default = 30, range 0 - 40\n * @param {Number} [ratio] The amount of dB change in input for a 1 dB change in output\n * default = 12, range 1 - 20\n * @param {Number} [threshold] The decibel value above which the compression will start taking effect\n * default = -24, range -100 - 0\n * @param {Number} [release] The amount of time (in seconds) to increase the gain by 10dB\n * default = .25, range 0 - 1\n */\n\tp5.Compressor.prototype.process = function(src, attack, knee,\n ratio, threshold, release) {\n\t\tsrc.connect(this.input);\n\t\tthis.set(attack, knee, ratio, threshold, release);\n\t};\n\n /**\n * Set the paramters of a compressor.\n * @method set\n * @for p5.Compressor\n * @param {Number} attack The amount of time (in seconds) to reduce the gain by 10dB,\n * default = .003, range 0 - 1\n * @param {Number} knee A decibel value representing the range above the\n * threshold where the curve smoothly transitions to the \"ratio\" portion.\n * default = 30, range 0 - 40\n * @param {Number} ratio The amount of dB change in input for a 1 dB change in output\n * default = 12, range 1 - 20\n * @param {Number} threshold The decibel value above which the compression will start taking effect\n * default = -24, range -100 - 0\n * @param {Number} release The amount of time (in seconds) to increase the gain by 10dB\n * default = .25, range 0 - 1\n */\n p5.Compressor.prototype.set = function (attack, knee,\n ratio, threshold, release) {\n\n if (typeof attack !== 'undefined') {this.attack(attack);}\n if (typeof knee !== 'undefined') {this.knee(knee);}\n if (typeof ratio !== 'undefined') {this.ratio(ratio);}\n if (typeof threshold !== 'undefined') {this.threshold(threshold);}\n if (typeof release !== 'undefined') {this.release(release);}\n };\n\n\n /**\n * Get current attack or set value w/ time ramp\n *\n *\n * @method attack\n * @for p5.Compressor\n * @param {Number} [attack] Attack is the amount of time (in seconds) to reduce the gain by 10dB,\n * default = .003, range 0 - 1\n * @param {Number} [time] Assign time value to schedule the change in value\n */\n p5.Compressor.prototype.attack = function (attack, time){\n var t = time || 0;\n if (typeof attack == 'number'){\n this.compressor.attack.value = attack;\n this.compressor.attack.cancelScheduledValues(this.ac.currentTime + 0.01 + t);\n this.compressor.attack.linearRampToValueAtTime(attack, this.ac.currentTime + 0.02 + t);\n } else if (typeof attack !== 'undefined') {\n attack.connect(this.compressor.attack);\n }\n return this.compressor.attack.value;\n };\n\n\n /**\n * Get current knee or set value w/ time ramp\n *\n * @method knee\n * @for p5.Compressor\n * @param {Number} [knee] A decibel value representing the range above the\n * threshold where the curve smoothly transitions to the \"ratio\" portion.\n * default = 30, range 0 - 40\n * @param {Number} [time] Assign time value to schedule the change in value\n */\n p5.Compressor.prototype.knee = function (knee, time){\n var t = time || 0;\n if (typeof knee == 'number'){\n this.compressor.knee.value = knee;\n this.compressor.knee.cancelScheduledValues(this.ac.currentTime + 0.01 + t);\n this.compressor.knee.linearRampToValueAtTime(knee, this.ac.currentTime + 0.02 + t);\n } else if (typeof knee !== 'undefined') {\n knee.connect(this.compressor.knee);\n }\n return this.compressor.knee.value;\n };\n\n\n /**\n * Get current ratio or set value w/ time ramp\n * @method ratio\n * @for p5.Compressor\n * @param {Number} [ratio] The amount of dB change in input for a 1 dB change in output\n * default = 12, range 1 - 20\n * @param {Number} [time] Assign time value to schedule the change in value\n */\n p5.Compressor.prototype.ratio = function (ratio, time){\n var t = time || 0;\n if (typeof ratio == 'number'){\n this.compressor.ratio.value = ratio;\n this.compressor.ratio.cancelScheduledValues(this.ac.currentTime + 0.01 + t);\n this.compressor.ratio.linearRampToValueAtTime(ratio, this.ac.currentTime + 0.02 + t);\n } else if (typeof ratio !== 'undefined') {\n ratio.connect(this.compressor.ratio);\n }\n return this.compressor.ratio.value;\n };\n\n\n /**\n * Get current threshold or set value w/ time ramp\n * @method threshold\n * @for p5.Compressor\n * @param {Number} threshold The decibel value above which the compression will start taking effect\n * default = -24, range -100 - 0\n * @param {Number} [time] Assign time value to schedule the change in value\n */\n p5.Compressor.prototype.threshold = function (threshold, time){\n var t = time || 0;\n if (typeof threshold == 'number'){\n this.compressor.threshold.value = threshold;\n this.compressor.threshold.cancelScheduledValues(this.ac.currentTime + 0.01 + t);\n this.compressor.threshold.linearRampToValueAtTime(threshold, this.ac.currentTime + 0.02 + t);\n } else if (typeof threshold !== 'undefined') {\n threshold.connect(this.compressor.threshold);\n }\n return this.compressor.threshold.value;\n };\n\n\n /**\n * Get current release or set value w/ time ramp\n * @method release\n * @for p5.Compressor\n * @param {Number} release The amount of time (in seconds) to increase the gain by 10dB\n * default = .25, range 0 - 1\n *\n * @param {Number} [time] Assign time value to schedule the change in value\n */\n p5.Compressor.prototype.release = function (release, time){\n var t = time || 0;\n if (typeof release == 'number'){\n this.compressor.release.value = release;\n this.compressor.release.cancelScheduledValues(this.ac.currentTime + 0.01 + t);\n this.compressor.release.linearRampToValueAtTime(release, this.ac.currentTime + 0.02 + t);\n } else if (typeof number !== 'undefined') {\n release.connect(this.compressor.release);\n }\n return this.compressor.release.value;\n };\n\n /**\n * Return the current reduction value\n *\n * @method reduction\n * @for p5.Compressor\n * @return {Number} Value of the amount of gain reduction that is applied to the signal\n */\n p5.Compressor.prototype.reduction =function() {\n return this.compressor.reduction.value;\n };\n\n\n\tp5.Compressor.prototype.dispose = function() {\n Effect.prototype.dispose.apply(this);\n if (this.compressor) {\n this.compressor.disconnect();\n delete this.compressor;\n }\n\t};\n\n return p5.Compressor;\n});\n","'use strict';\n\ndefine(function (require) {\n\n // inspiration: recorder.js, Tone.js & typedarray.org\n\n var p5sound = require('master');\n var convertToWav = require('helpers').convertToWav;\n var processorNames = require('./audioWorklet/processorNames');\n var ac = p5sound.audiocontext;\n\n /**\n *
Record sounds for playback and/or to save as a .wav file.\n * The p5.SoundRecorder records all sound output from your sketch,\n * or can be assigned a specific source with setInput().
\n *
The record() method accepts a p5.SoundFile as a parameter.\n * When playback is stopped (either after the given amount of time,\n * or with the stop() method), the p5.SoundRecorder will send its\n * recording to that p5.SoundFile for playback.
\n * var mic, recorder, soundFile;\n * var state = 0;\n *\n * function setup() {\n * background(200);\n * // create an audio in\n * mic = new p5.AudioIn();\n *\n * // prompts user to enable their browser mic\n * mic.start();\n *\n * // create a sound recorder\n * recorder = new p5.SoundRecorder();\n *\n * // connect the mic to the recorder\n * recorder.setInput(mic);\n *\n * // this sound file will be used to\n * // playback & save the recording\n * soundFile = new p5.SoundFile();\n *\n * text('keyPress to record', 20, 20);\n * }\n *\n * function keyPressed() {\n * // make sure user enabled the mic\n * if (state === 0 && mic.enabled) {\n *\n * // record to our p5.SoundFile\n * recorder.record(soundFile);\n *\n * background(255,0,0);\n * text('Recording!', 20, 20);\n * state++;\n * }\n * else if (state === 1) {\n * background(0,255,0);\n *\n * // stop recorder and\n * // send result to soundFile\n * recorder.stop();\n *\n * text('Stopped', 20, 20);\n * state++;\n * }\n *\n * else if (state === 2) {\n * soundFile.play(); // play the result!\n * save(soundFile, 'mySound.wav');\n * state++;\n * }\n * }\n *
\n */\n p5.SoundRecorder = function() {\n this.input = ac.createGain();\n this.output = ac.createGain();\n\n this._inputChannels = 2;\n this._outputChannels = 2; // stereo output, even if input is mono\n\n this._workletNode = new AudioWorkletNode(ac, processorNames.recorderProcessor, {\n outputChannelCount: [this._outputChannels],\n processorOptions: { numInputChannels: this._inputChannels }\n });\n\n this._workletNode.port.onmessage = function(event) {\n if (event.data.name === 'buffers') {\n const buffers = [\n new Float32Array(event.data.leftBuffer),\n new Float32Array(event.data.rightBuffer)\n ];\n this._callback(buffers);\n }\n }.bind(this);\n\n /**\n * callback invoked when the recording is over\n * @private\n * @type Function(Float32Array)\n */\n this._callback = function() {};\n\n // connections\n this._workletNode.connect(p5.soundOut._silentNode);\n this.setInput();\n\n // add this p5.SoundFile to the soundArray\n p5sound.soundArray.push(this);\n };\n\n /**\n * Connect a specific device to the p5.SoundRecorder.\n * If no parameter is given, p5.SoundRecorer will record\n * all audible p5.sound from your sketch.\n *\n * @method setInput\n * @for p5.SoundRecorder\n * @param {Object} [unit] p5.sound object or a web audio unit\n * that outputs sound\n */\n p5.SoundRecorder.prototype.setInput = function(unit) {\n this.input.disconnect();\n this.input = null;\n this.input = ac.createGain();\n this.input.connect(this._workletNode);\n this.input.connect(this.output);\n if (unit) {\n unit.connect(this.input);\n } else {\n p5.soundOut.output.connect(this.input);\n }\n };\n\n /**\n * Start recording. To access the recording, provide\n * a p5.SoundFile as the first parameter. The p5.SoundRecorder\n * will send its recording to that p5.SoundFile for playback once\n * recording is complete. Optional parameters include duration\n * (in seconds) of the recording, and a callback function that\n * will be called once the complete recording has been\n * transfered to the p5.SoundFile.\n *\n * @method record\n * @for p5.SoundRecorder\n * @param {p5.SoundFile} soundFile p5.SoundFile\n * @param {Number} [duration] Time (in seconds)\n * @param {Function} [callback] The name of a function that will be\n * called once the recording completes\n */\n p5.SoundRecorder.prototype.record = function(sFile, duration, callback) {\n this._workletNode.port.postMessage({ name: 'start', duration: duration });\n\n if (sFile && callback) {\n this._callback = function(buffer) {\n sFile.setBuffer(buffer);\n callback();\n };\n }\n else if (sFile) {\n this._callback = function(buffer) {\n sFile.setBuffer(buffer);\n };\n }\n };\n\n /**\n * Stop the recording. Once the recording is stopped,\n * the results will be sent to the p5.SoundFile that\n * was given on .record(), and if a callback function\n * was provided on record, that function will be called.\n *\n * @method stop\n * @for p5.SoundRecorder\n */\n p5.SoundRecorder.prototype.stop = function() {\n this._workletNode.port.postMessage({ name: 'stop' });\n };\n\n p5.SoundRecorder.prototype.dispose = function() {\n // remove reference from soundArray\n var index = p5sound.soundArray.indexOf(this);\n p5sound.soundArray.splice(index, 1);\n\n this._callback = function() {};\n if (this.input) {\n this.input.disconnect();\n }\n this.input = null;\n this._workletNode = null;\n };\n\n\n /**\n * Save a p5.SoundFile as a .wav file. The browser will prompt the user\n * to download the file to their device.\n * For uploading audio to a server, use\n * `p5.SoundFile.saveBlob`.\n *\n * @for p5\n * @method saveSound\n * @param {p5.SoundFile} soundFile p5.SoundFile that you wish to save\n * @param {String} fileName name of the resulting .wav file.\n */\n // add to p5.prototype as this is used by the p5 `save()` method.\n p5.prototype.saveSound = function (soundFile, fileName) {\n const dataView = convertToWav(soundFile.buffer);\n p5.prototype.writeFile([dataView], fileName, 'wav');\n };\n});\n","'use strict';\n\ndefine(function () {\n /**\n *
PeakDetect works in conjunction with p5.FFT to\n * look for onsets in some or all of the frequency spectrum.\n *
\n *
\n * To use p5.PeakDetect, call update in the draw loop\n * and pass in a p5.FFT object.\n *
\n *
\n * You can listen for a specific part of the frequency spectrum by\n * setting the range between freq1 and freq2.\n *
\n *\n *
threshold is the threshold for detecting a peak,\n * scaled between 0 and 1. It is logarithmic, so 0.1 is half as loud\n * as 1.0.
\n *\n *
\n * The update method is meant to be run in the draw loop, and\n * frames determines how many loops must pass before\n * another peak can be detected.\n * For example, if the frameRate() = 60, you could detect the beat of a\n * 120 beat-per-minute song with this equation:\n * framesPerPeak = 60 / (estimatedBPM / 60 );\n *
\n *\n *
\n * Based on example contribtued by @b2renger, and a simple beat detection\n * explanation by Felix Turner.\n *
\n *\n * @class p5.PeakDetect\n * @constructor\n * @param {Number} [freq1] lowFrequency - defaults to 20Hz\n * @param {Number} [freq2] highFrequency - defaults to 20000 Hz\n * @param {Number} [threshold] Threshold for detecting a beat between 0 and 1\n * scaled logarithmically where 0.1 is 1/2 the loudness\n * of 1.0. Defaults to 0.35.\n * @param {Number} [framesPerPeak] Defaults to 20.\n * @example\n *
\n */\n p5.PeakDetect = function(freq1, freq2, threshold, _framesPerPeak) {\n // framesPerPeak determines how often to look for a beat.\n // If a beat is provided, try to look for a beat based on bpm\n this.framesPerPeak = _framesPerPeak || 20;\n this.framesSinceLastPeak = 0;\n this.decayRate = 0.95;\n\n this.threshold = threshold || 0.35;\n this.cutoff = 0;\n\n // how much to increase the cutoff\n // TO DO: document this / figure out how to make it accessible\n this.cutoffMult = 1.5;\n\n this.energy = 0;\n this.penergy = 0;\n\n // TO DO: document this property / figure out how to make it accessible\n this.currentValue = 0;\n\n /**\n * isDetected is set to true when a peak is detected.\n *\n * @attribute isDetected {Boolean}\n * @default false\n */\n this.isDetected = false;\n\n this.f1 = freq1 || 40;\n this.f2 = freq2 || 20000;\n\n // function to call when a peak is detected\n this._onPeak = function() {};\n };\n\n\n /**\n * The update method is run in the draw loop.\n *\n * Accepts an FFT object. You must call .analyze()\n * on the FFT object prior to updating the peakDetect\n * because it relies on a completed FFT analysis.\n *\n * @method update\n * @param {p5.FFT} fftObject A p5.FFT object\n */\n p5.PeakDetect.prototype.update = function(fftObject) {\n var nrg = this.energy = fftObject.getEnergy(this.f1,this.f2)/255;\n if (nrg > this.cutoff && nrg > this.threshold && nrg-this.penergy > 0) {\n\n // trigger callback\n this._onPeak();\n this.isDetected = true;\n\n // debounce\n this.cutoff = nrg * this.cutoffMult;\n this.framesSinceLastPeak = 0;\n } else {\n this.isDetected = false;\n if (this.framesSinceLastPeak <= this.framesPerPeak) {\n this.framesSinceLastPeak++;\n } else {\n this.cutoff *= this.decayRate;\n this.cutoff = Math.max(this.cutoff, this.threshold);\n }\n }\n\n this.currentValue = nrg;\n this.penergy = nrg;\n };\n\n /**\n * onPeak accepts two arguments: a function to call when\n * a peak is detected. The value of the peak,\n * between 0.0 and 1.0, is passed to the callback.\n *\n * @method onPeak\n * @param {Function} callback Name of a function that will\n * be called when a peak is\n * detected.\n * @param {Object} [val] Optional value to pass\n * into the function when\n * a peak is detected.\n * @example\n *
\n * var cnv, soundFile, fft, peakDetect;\n * var ellipseWidth = 0;\n *\n * function preload() {\n * soundFile = loadSound('assets/beat.mp3');\n * }\n *\n * function setup() {\n * cnv = createCanvas(100,100);\n * textAlign(CENTER);\n *\n * fft = new p5.FFT();\n * peakDetect = new p5.PeakDetect();\n *\n * setupSound();\n *\n * // when a beat is detected, call triggerBeat()\n * peakDetect.onPeak(triggerBeat);\n * }\n *\n * function draw() {\n * background(0);\n * fill(255);\n * text('click to play', width/2, height/2);\n *\n * fft.analyze();\n * peakDetect.update(fft);\n *\n * ellipseWidth *= 0.95;\n * ellipse(width/2, height/2, ellipseWidth, ellipseWidth);\n * }\n *\n * // this function is called by peakDetect.onPeak\n * function triggerBeat() {\n * ellipseWidth = 50;\n * }\n *\n * // mouseclick starts/stops sound\n * function setupSound() {\n * cnv.mouseClicked( function() {\n * if (soundFile.isPlaying() ) {\n * soundFile.stop();\n * } else {\n * soundFile.play();\n * }\n * });\n * }\n *
\n */\n p5.PeakDetect.prototype.onPeak = function(callback, val) {\n var self = this;\n\n self._onPeak = function() {\n callback(self.energy, val);\n };\n };\n\n});\n","'use strict';\n\ndefine(function (require) {\n var p5sound = require('master');\n\n /**\n * A gain node is usefull to set the relative volume of sound.\n * It's typically used to build mixers.\n *\n * @class p5.Gain\n * @constructor\n * @example\n *
\n *\n * // load two soundfile and crossfade beetween them\n * var sound1,sound2;\n * var gain1, gain2, gain3;\n *\n * function preload(){\n * soundFormats('ogg', 'mp3');\n * sound1 = loadSound('assets/Damscray_-_Dancing_Tiger_01');\n * sound2 = loadSound('assets/beat.mp3');\n * }\n *\n * function setup() {\n * createCanvas(400,200);\n *\n * // create a 'master' gain to which we will connect both soundfiles\n * gain3 = new p5.Gain();\n * gain3.connect();\n *\n * // setup first sound for playing\n * sound1.rate(1);\n * sound1.loop();\n * sound1.disconnect(); // diconnect from p5 output\n *\n * gain1 = new p5.Gain(); // setup a gain node\n * gain1.setInput(sound1); // connect the first sound to its input\n * gain1.connect(gain3); // connect its output to the 'master'\n *\n * sound2.rate(1);\n * sound2.disconnect();\n * sound2.loop();\n *\n * gain2 = new p5.Gain();\n * gain2.setInput(sound2);\n * gain2.connect(gain3);\n *\n * }\n *\n * function draw(){\n * background(180);\n *\n * // calculate the horizontal distance beetween the mouse and the right of the screen\n * var d = dist(mouseX,0,width,0);\n *\n * // map the horizontal position of the mouse to values useable for volume control of sound1\n * var vol1 = map(mouseX,0,width,0,1);\n * var vol2 = 1-vol1; // when sound1 is loud, sound2 is quiet and vice versa\n *\n * gain1.amp(vol1,0.5,0);\n * gain2.amp(vol2,0.5,0);\n *\n * // map the vertical position of the mouse to values useable for 'master volume control'\n * var vol3 = map(mouseY,0,height,0,1);\n * gain3.amp(vol3,0.5,0);\n * }\n *
\n *\n */\n\n p5.Gain = function() {\n this.ac = p5sound.audiocontext;\n\n this.input = this.ac.createGain();\n this.output = this.ac.createGain();\n\n // otherwise, Safari distorts\n this.input.gain.value = 0.5;\n this.input.connect(this.output);\n\n // add to the soundArray\n p5sound.soundArray.push(this);\n };\n\n /**\n * Connect a source to the gain node.\n *\n * @method setInput\n * @for p5.Gain\n * @param {Object} src p5.sound / Web Audio object with a sound\n * output.\n */\n\n\n p5.Gain.prototype.setInput = function(src) {\n src.connect(this.input);\n };\n\n /**\n * Send output to a p5.sound or web audio object\n *\n * @method connect\n * @for p5.Gain\n * @param {Object} unit\n */\n p5.Gain.prototype.connect = function(unit) {\n var u = unit || p5.soundOut.input;\n this.output.connect(u.input ? u.input : u);\n };\n\n /**\n * Disconnect all output.\n *\n * @method disconnect\n * @for p5.Gain\n */\n p5.Gain.prototype.disconnect = function() {\n if (this.output) {\n this.output.disconnect();\n }\n };\n\n /**\n * Set the output level of the gain node.\n *\n * @method amp\n * @for p5.Gain\n * @param {Number} volume amplitude between 0 and 1.0\n * @param {Number} [rampTime] create a fade that lasts rampTime\n * @param {Number} [timeFromNow] schedule this event to happen\n * seconds from now\n */\n p5.Gain.prototype.amp = function(vol, rampTime, tFromNow) {\n var rampTime = rampTime || 0;\n var tFromNow = tFromNow || 0;\n var now = p5sound.audiocontext.currentTime;\n var currentVol = this.output.gain.value;\n this.output.gain.cancelScheduledValues(now);\n this.output.gain.linearRampToValueAtTime(currentVol, now + tFromNow);\n this.output.gain.linearRampToValueAtTime(vol, now + tFromNow + rampTime);\n };\n\n p5.Gain.prototype.dispose = function() {\n // remove reference from soundArray\n var index = p5sound.soundArray.indexOf(this);\n p5sound.soundArray.splice(index, 1);\n if (this.output) {\n this.output.disconnect();\n delete this.output;\n }\n if (this.input) {\n this.input.disconnect();\n delete this.input;\n }\n };\n\n});\n","'use strict';\n\ndefine(function (require) {\n\n var Effect = require('effect');\n\n /*\n * Adapted from [Kevin Ennis on StackOverflow](http://stackoverflow.com/questions/22312841/waveshaper-node-in-webaudio-how-to-emulate-distortion)\n */\n function makeDistortionCurve(amount) {\n var k = typeof amount === 'number' ? amount : 50;\n var numSamples = 44100;\n var curve = new Float32Array(numSamples);\n var deg = Math.PI / 180;\n var i = 0;\n var x;\n for ( ; i < numSamples; ++i ) {\n x = i * 2 / numSamples - 1;\n curve[i] = ( 3 + k ) * x * 20 * deg / ( Math.PI + k * Math.abs(x) );\n }\n return curve;\n }\n\n /**\n * A Distortion effect created with a Waveshaper Node,\n * with an approach adapted from\n * [Kevin Ennis](http://stackoverflow.com/questions/22312841/waveshaper-node-in-webaudio-how-to-emulate-distortion)\n *\n * This class extends p5.Effect.\n * Methods amp(), chain(),\n * drywet(), connect(), and\n * disconnect() are available.\n *\n * @class p5.Distortion\n * @extends p5.Effect\n * @constructor\n * @param {Number} [amount=0.25] Unbounded distortion amount.\n * Normal values range from 0-1.\n * @param {String} [oversample='none'] 'none', '2x', or '4x'.\n *\n */\n p5.Distortion = function(amount, oversample) {\n Effect.call(this);\n\n if (typeof amount === 'undefined') {\n amount = 0.25;\n } if (typeof amount !== 'number') {\n throw new Error('amount must be a number');\n } if (typeof oversample === 'undefined') {\n oversample = '2x';\n } if (typeof oversample !== 'string') {\n throw new Error('oversample must be a String');\n }\n\n var curveAmount = p5.prototype.map(amount, 0.0, 1.0, 0, 2000);\n\n /**\n * The p5.Distortion is built with a\n * \n * Web Audio WaveShaper Node.\n *\n * @property {AudioNode} WaveShaperNode\n */\n this.waveShaperNode = this.ac.createWaveShaper();\n\n this.amount = curveAmount;\n this.waveShaperNode.curve = makeDistortionCurve(curveAmount);\n this.waveShaperNode.oversample = oversample;\n\n this.input.connect(this.waveShaperNode);\n\n this.waveShaperNode.connect(this.wet);\n };\n\n p5.Distortion.prototype = Object.create(Effect.prototype);\n\n\n /**\n * Process a sound source, optionally specify amount and oversample values.\n *\n * @method process\n * @for p5.Distortion\n * @param {Number} [amount=0.25] Unbounded distortion amount.\n * Normal values range from 0-1.\n * @param {String} [oversample='none'] 'none', '2x', or '4x'.\n */\n p5.Distortion.prototype.process = function(src, amount, oversample) {\n src.connect(this.input);\n this.set(amount, oversample);\n };\n\n /**\n * Set the amount and oversample of the waveshaper distortion.\n *\n * @method set\n * @for p5.Distortion\n * @param {Number} [amount=0.25] Unbounded distortion amount.\n * Normal values range from 0-1.\n * @param {String} [oversample='none'] 'none', '2x', or '4x'.\n */\n p5.Distortion.prototype.set = function(amount, oversample) {\n if (amount) {\n var curveAmount = p5.prototype.map(amount, 0.0, 1.0, 0, 2000);\n this.amount = curveAmount;\n this.waveShaperNode.curve = makeDistortionCurve(curveAmount);\n }\n if (oversample) {\n this.waveShaperNode.oversample = oversample;\n }\n };\n\n /**\n * Return the distortion amount, typically between 0-1.\n *\n * @method getAmount\n * @for p5.Distortion\n * @return {Number} Unbounded distortion amount.\n * Normal values range from 0-1.\n */\n p5.Distortion.prototype.getAmount = function() {\n return this.amount;\n };\n\n /**\n * Return the oversampling.\n *\n * @method getOversample\n * @for p5.Distortion\n * @return {String} Oversample can either be 'none', '2x', or '4x'.\n */\n p5.Distortion.prototype.getOversample = function() {\n return this.waveShaperNode.oversample;\n };\n\n\n p5.Distortion.prototype.dispose = function() {\n Effect.prototype.dispose.apply(this);\n if (this.waveShaperNode) {\n this.waveShaperNode.disconnect();\n this.waveShaperNode = null;\n }\n };\n});\n"],"sourceRoot":""}
\ No newline at end of file
diff --git a/lib/p5.sound.min.js b/lib/p5.sound.min.js
index 0c0343fb..7c9e7f89 100644
--- a/lib/p5.sound.min.js
+++ b/lib/p5.sound.min.js
@@ -1,2 +1,2 @@
-!function(i){var n={};function o(t){if(n[t])return n[t].exports;var e=n[t]={i:t,l:!1,exports:{}};return i[t].call(e.exports,e,e.exports,o),e.l=!0,e.exports}o.m=i,o.c=n,o.d=function(t,e,i){o.o(t,e)||Object.defineProperty(t,e,{enumerable:!0,get:i})},o.r=function(t){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(t,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(t,"__esModule",{value:!0})},o.t=function(e,t){if(1&t&&(e=o(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var i=Object.create(null);if(o.r(i),Object.defineProperty(i,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var n in e)o.d(i,n,function(t){return e[t]}.bind(null,n));return i},o.n=function(t){var e=t&&t.__esModule?function(){return t.default}:function(){return t};return o.d(e,"a",e),e},o.o=function(t,e){return Object.prototype.hasOwnProperty.call(t,e)},o.p="",o(o.s=31)}([function(t,e,i){var n;void 0===(n=function(){"use strict";function c(t,e){this.isUndef(t)||1===t?this.input=this.context.createGain():1t)this.cancelScheduledValues(t),this.linearRampToValueAtTime(e,t);else{var n=this._searchAfter(t);n&&(this.cancelScheduledValues(t),n.type===u.TimelineSignal.Type.Linear?this.linearRampToValueAtTime(e,t):n.type===u.TimelineSignal.Type.Exponential&&this.exponentialRampToValueAtTime(e,t)),this.setValueAtTime(e,t)}return this},u.TimelineSignal.prototype.linearRampToValueBetween=function(t,e,i){return this.setRampPoint(e),this.linearRampToValueAtTime(t,i),this},u.TimelineSignal.prototype.exponentialRampToValueBetween=function(t,e,i){return this.setRampPoint(e),this.exponentialRampToValueAtTime(t,i),this},u.TimelineSignal.prototype._searchBefore=function(t){return this._events.get(t)},u.TimelineSignal.prototype._searchAfter=function(t){return this._events.getAfter(t)},u.TimelineSignal.prototype.getValueAtTime=function(t){t=this.toSeconds(t);var e=this._searchAfter(t),i=this._searchBefore(t),n=this._initial;if(null===i)n=this._initial;else if(i.type===u.TimelineSignal.Type.Target){var o,r=this._events.getBefore(i.time);o=null===r?this._initial:r.value,n=this._exponentialApproach(i.time,o,i.value,i.constant,t)}else n=i.type===u.TimelineSignal.Type.Curve?this._curveInterpolate(i.time,i.value,i.duration,t):null===e?i.value:e.type===u.TimelineSignal.Type.Linear?this._linearInterpolate(i.time,i.value,e.time,e.value,t):e.type===u.TimelineSignal.Type.Exponential?this._exponentialInterpolate(i.time,i.value,e.time,e.value,t):i.value;return n},u.TimelineSignal.prototype.connect=u.SignalBase.prototype.connect,u.TimelineSignal.prototype._exponentialApproach=function(t,e,i,n,o){return i+(e-i)*Math.exp(-(o-t)/n)},u.TimelineSignal.prototype._linearInterpolate=function(t,e,i,n,o){return e+(o-t)/(i-t)*(n-e)},u.TimelineSignal.prototype._exponentialInterpolate=function(t,e,i,n,o){return(e=Math.max(this._minOutput,e))*Math.pow(n/e,(o-t)/(i-t))},u.TimelineSignal.prototype._curveInterpolate=function(t,e,i,n){var o=e.length;if(t+i<=n)return e[o-1];if(n<=t)return e[0];var r=(n-t)/i,s=Math.floor((o-1)*r),a=Math.ceil((o-1)*r),u=e[s],p=e[a];return a===s?u:this._linearInterpolate(s,u,a,p,r*(o-1))},u.TimelineSignal.prototype.dispose=function(){u.Signal.prototype.dispose.call(this),u.Param.prototype.dispose.call(this),this._events.dispose(),this._events=null},u.TimelineSignal}.apply(e,n))||(t.exports=o)},function(t,e,i){"use strict";var n;void 0===(n=function(t){var e=i(4);return p5.Filter=function(t){e.call(this),this.biquad=this.ac.createBiquadFilter(),this.input.connect(this.biquad),this.biquad.connect(this.wet),t&&this.setType(t),this._on=!0,this._untoggledType=this.biquad.type},p5.Filter.prototype=Object.create(e.prototype),p5.Filter.prototype.process=function(t,e,i,n){t.connect(this.input),this.set(e,i,n)},p5.Filter.prototype.set=function(t,e,i){t&&this.freq(t,i),e&&this.res(e,i)},p5.Filter.prototype.freq=function(t,e){var i=e||0;return t<=0&&(t=1),"number"==typeof t?(this.biquad.frequency.cancelScheduledValues(this.ac.currentTime+.01+i),this.biquad.frequency.exponentialRampToValueAtTime(t,this.ac.currentTime+.02+i)):t&&t.connect(this.biquad.frequency),this.biquad.frequency.value},p5.Filter.prototype.res=function(t,e){var i=e||0;return"number"==typeof t?(this.biquad.Q.value=t,this.biquad.Q.cancelScheduledValues(this.ac.currentTime+.01+i),this.biquad.Q.linearRampToValueAtTime(t,this.ac.currentTime+.02+i)):t&&t.connect(this.biquad.Q),this.biquad.Q.value},p5.Filter.prototype.gain=function(t,e){var i=e||0;return"number"==typeof t?(this.biquad.gain.value=t,this.biquad.gain.cancelScheduledValues(this.ac.currentTime+.01+i),this.biquad.gain.linearRampToValueAtTime(t,this.ac.currentTime+.02+i)):t&&t.connect(this.biquad.gain),this.biquad.gain.value},p5.Filter.prototype.toggle=function(){return this._on=!this._on,!0===this._on?this.biquad.type=this._untoggledType:!1===this._on&&(this.biquad.type="allpass"),this._on},p5.Filter.prototype.setType=function(t){this.biquad.type=t,this._untoggledType=this.biquad.type},p5.Filter.prototype.dispose=function(){e.prototype.dispose.apply(this),this.biquad&&(this.biquad.disconnect(),delete this.biquad)},p5.LowPass=function(){p5.Filter.call(this,"lowpass")},p5.LowPass.prototype=Object.create(p5.Filter.prototype),p5.HighPass=function(){p5.Filter.call(this,"highpass")},p5.HighPass.prototype=Object.create(p5.Filter.prototype),p5.BandPass=function(){p5.Filter.call(this,"bandpass")},p5.BandPass.prototype=Object.create(p5.Filter.prototype),p5.Filter}.call(e,i,e,t))||(t.exports=n)},function(t,e,i){var n,o;n=[i(0),i(7),i(25),i(2),i(9)],void 0===(o=function(e){"use strict";return e.Subtract=function(t){this.createInsOuts(2,0),this._sum=this.input[0]=this.output=new e.Gain,this._neg=new e.Negate,this._param=this.input[1]=new e.Signal(t),this._param.chain(this._neg,this._sum)},e.extend(e.Subtract,e.Signal),e.Subtract.prototype.dispose=function(){return e.prototype.dispose.call(this),this._neg.dispose(),this._neg=null,this._sum.disconnect(),this._sum=null,this._param.dispose(),this._param=null,this},e.Subtract}.apply(e,n))||(t.exports=o)},function(n,o,r){"use strict";(function(t){var e,i;t.TONE_SILENCE_VERSION_LOGGING=!0,e=[r(35),r(11),r(0)],void 0===(i=function(n,t,e){var o=new window.AudioContext;return e.context.dispose(),e.setContext(o),p5.prototype.getAudioContext=function(){return o},p5.prototype.userStartAudio=function(t,e){var i=t;return t instanceof p5.Element?i=t.elt:t instanceof Array&&t[0]instanceof p5.Element&&(i=t.map(function(t){return t.elt})),n(o,i,e)},o}.apply(o,e))||(n.exports=i)}).call(this,r(34))},function(t,e,i){var n,o;n=[i(0)],void 0===(o=function(s){"use strict";return s.Emitter=function(){this._events={}},s.extend(s.Emitter),s.Emitter.prototype.on=function(t,e){for(var i=t.split(/\W+/),n=0;nthis.memory){var i=this.length-this.memory;this._timeline.splice(0,i)}return this},e.Timeline.prototype.remove=function(t){if(this._iterating)this._toRemove.push(t);else{var e=this._timeline.indexOf(t);-1!==e&&this._timeline.splice(e,1)}return this},e.Timeline.prototype.get=function(t){var e=this._search(t);return-1!==e?this._timeline[e]:null},e.Timeline.prototype.peek=function(){return this._timeline[0]},e.Timeline.prototype.shift=function(){return this._timeline.shift()},e.Timeline.prototype.getAfter=function(t){var e=this._search(t);return e+1=t&&(this._timeline=[]);return this},e.Timeline.prototype.cancelBefore=function(t){if(this._timeline.length){var e=this._search(t);0<=e&&(this._timeline=this._timeline.slice(e+1))}return this},e.Timeline.prototype._search=function(t){var e=0,i=this._timeline.length,n=i;if(0t)return o;r.time>t?n=o:r.time=t;)i--;return this._iterate(e,i+1),this},e.Timeline.prototype.forEachAtTime=function(e,i){var t=this._search(e);return-1!==t&&this._iterate(function(t){t.time===e&&i(t)},0,t),this},e.Timeline.prototype.dispose=function(){e.prototype.dispose.call(this),this._timeline=null,this._toRemove=null},e.Timeline}.apply(e,n))||(t.exports=o)},function(t,e,i){var n,o;n=[i(0),i(3),i(2)],void 0===(o=function(t){"use strict";return t.Negate=function(){this._multiply=this.input=this.output=new t.Multiply(-1)},t.extend(t.Negate,t.SignalBase),t.Negate.prototype.dispose=function(){return t.prototype.dispose.call(this),this._multiply.dispose(),this._multiply=null,this},t.Negate}.apply(e,n))||(t.exports=o)},function(t,e,i){var n,o;n=[i(0),i(2),i(3),i(5)],void 0===(o=function(t){"use strict";return t.GreaterThanZero=function(){this._thresh=this.output=new t.WaveShaper(function(t){return t<=0?0:1},127),this._scale=this.input=new t.Multiply(1e4),this._scale.connect(this._thresh)},t.extend(t.GreaterThanZero,t.SignalBase),t.GreaterThanZero.prototype.dispose=function(){return t.prototype.dispose.call(this),this._scale.dispose(),this._scale=null,this._thresh.dispose(),this._thresh=null,this},t.GreaterThanZero}.apply(e,n))||(t.exports=o)},function(t,e,i){var n,o;n=[i(0),i(13),i(65),i(17),i(11)],void 0===(o=function(o){"use strict";return o.Clock=function(){o.Emitter.call(this);var t=this.optionsObject(arguments,["callback","frequency"],o.Clock.defaults);this.callback=t.callback,this._nextTick=0,this._lastState=o.State.Stopped,this.frequency=new o.TimelineSignal(t.frequency,o.Type.Frequency),this._readOnly("frequency"),this.ticks=0,this._state=new o.TimelineState(o.State.Stopped),this._boundLoop=this._loop.bind(this),this.context.on("tick",this._boundLoop)},o.extend(o.Clock,o.Emitter),o.Clock.defaults={callback:o.noOp,frequency:1,lookAhead:"auto"},Object.defineProperty(o.Clock.prototype,"state",{get:function(){return this._state.getValueAtTime(this.now())}}),o.Clock.prototype.start=function(t,e){return t=this.toSeconds(t),this._state.getValueAtTime(t)!==o.State.Started&&this._state.add({state:o.State.Started,time:t,offset:e}),this},o.Clock.prototype.stop=function(t){return t=this.toSeconds(t),this._state.cancel(t),this._state.setStateAtTime(o.State.Stopped,t),this},o.Clock.prototype.pause=function(t){return t=this.toSeconds(t),this._state.getValueAtTime(t)===o.State.Started&&this._state.setStateAtTime(o.State.Paused,t),this},o.Clock.prototype._loop=function(){for(var t=this.now()+this.context.lookAhead+this.context.updateInterval+2*this.context.lag;t>this._nextTick&&this._state;){var e=this._state.getValueAtTime(this._nextTick);if(e!==this._lastState){this._lastState=e;var i=this._state.get(this._nextTick);e===o.State.Started?(this._nextTick=i.time,this.isUndef(i.offset)||(this.ticks=i.offset),this.emit("start",i.time,this.ticks)):e===o.State.Stopped?(this.ticks=0,this.emit("stop",i.time)):e===o.State.Paused&&this.emit("pause",i.time)}var n=this._nextTick;this.frequency&&(this._nextTick+=1/this.frequency.getValueAtTime(this._nextTick),e===o.State.Started&&(this.callback(n),this.ticks++))}},o.Clock.prototype.getStateAtTime=function(t){return t=this.toSeconds(t),this._state.getValueAtTime(t)},o.Clock.prototype.dispose=function(){o.Emitter.prototype.dispose.call(this),this.context.off("tick",this._boundLoop),this._writable("frequency"),this.frequency.dispose(),this.frequency=null,this._boundLoop=null,this._nextTick=1/0,this.callback=null,this._state.dispose(),this._state=null},o.Clock}.apply(e,n))||(t.exports=o)},function(t,e,n){"use strict";var i;void 0===(i=function(t){var i=n(1),e=n(29),r=n(6).noteToFreq;p5.MonoSynth=function(){e.call(this),this.oscillator=new p5.Oscillator,this.env=new p5.Envelope,this.env.setRange(1,0),this.env.setExp(!0),this.setADSR(.02,.25,.05,.35),this.oscillator.disconnect(),this.oscillator.connect(this.output),this.env.disconnect(),this.env.setInput(this.output.gain),this.oscillator.output.gain.value=1,this.oscillator.start(),this.connect(),i.soundArray.push(this)},p5.MonoSynth.prototype=Object.create(p5.AudioVoice.prototype),p5.MonoSynth.prototype.play=function(t,e,i,n){this.triggerAttack(t,e,~~i),this.triggerRelease(~~i+(n||.15))},p5.MonoSynth.prototype.triggerAttack=function(t,e,i){i=~~i;var n=r(t),o=e||.1;this.oscillator.freq(n,0,i),this.env.ramp(this.output.gain,i,o)},p5.MonoSynth.prototype.triggerRelease=function(t){t=t||0;this.env.ramp(this.output.gain,t,0)},p5.MonoSynth.prototype.setADSR=function(t,e,i,n){this.env.setADSR(t,e,i,n)},Object.defineProperties(p5.MonoSynth.prototype,{attack:{get:function(){return this.env.aTime},set:function(t){this.env.setADSR(t,this.env.dTime,this.env.sPercent,this.env.rTime)}},decay:{get:function(){return this.env.dTime},set:function(t){this.env.setADSR(this.env.aTime,t,this.env.sPercent,this.env.rTime)}},sustain:{get:function(){return this.env.sPercent},set:function(t){this.env.setADSR(this.env.aTime,this.env.dTime,t,this.env.rTime)}},release:{get:function(){return this.env.rTime},set:function(t){this.env.setADSR(this.env.aTime,this.env.dTime,this.env.sPercent,t)}}}),p5.MonoSynth.prototype.amp=function(t,e){var i=e||0;return void 0!==t&&this.oscillator.amp(t,i),this.oscillator.amp().value},p5.MonoSynth.prototype.connect=function(t){var e=t||i.input;this.output.connect(e.input?e.input:e)},p5.MonoSynth.prototype.disconnect=function(){this.output&&this.output.disconnect()},p5.MonoSynth.prototype.dispose=function(){e.prototype.dispose.apply(this),this.env&&this.env.dispose(),this.oscillator&&this.oscillator.dispose()}}.call(e,n,e,t))||(t.exports=i)},function(t,e,n){"use strict";var i;void 0===(i=function(){var i=n(1);return p5.AudioVoice=function(){this.ac=i.audiocontext,this.output=this.ac.createGain(),this.connect(),i.soundArray.push(this)},p5.AudioVoice.prototype.play=function(t,e,i,n){},p5.AudioVoice.prototype.triggerAttack=function(t,e,i){},p5.AudioVoice.prototype.triggerRelease=function(t){},p5.AudioVoice.prototype.amp=function(t,e){},p5.AudioVoice.prototype.connect=function(t){var e=t||i.input;this.output.connect(e.input?e.input:e)},p5.AudioVoice.prototype.disconnect=function(){this.output.disconnect()},p5.AudioVoice.prototype.dispose=function(){this.output&&(this.output.disconnect(),delete this.output)},p5.AudioVoice}.call(e,n,e,t))||(t.exports=i)},function(t,e,i){"use strict";var n;void 0===(n=function(t){var c=i(1),h=i(13),l=i(6).noteToFreq;p5.PolySynth=function(t,e){this.audiovoices=[],this.notes={},this._newest=0,this._oldest=0,this.maxVoices=e||8,this.AudioVoice=void 0===t?p5.MonoSynth:t,this._voicesInUse=new h(0),this.output=c.audiocontext.createGain(),this.connect(),this._allocateVoices(),c.soundArray.push(this)},p5.PolySynth.prototype._allocateVoices=function(){for(var t=0;t= this.sampleLimit) {\n this.stop();\n return true;\n }\n\n var input = inputs[0];\n var output = outputs[0];\n\n for (var channel = 0; channel < output.length; ++channel) {\n var inputChannel = input[channel];\n\n if (channel === 0) {\n this.leftBuffers.push(inputChannel);\n\n if (this.numInputChannels === 1) {\n this.rightBuffers.push(inputChannel);\n }\n } else if (channel === 1 && this.numInputChannels > 1) {\n this.rightBuffers.push(inputChannel);\n }\n }\n\n this.recordedSamples += output[0].length;\n return true;\n }\n }, {\n key: "record",\n value: function record(duration) {\n if (duration) {\n this.sampleLimit = Math.round(duration * sampleRate);\n }\n\n this.recording = true;\n }\n }, {\n key: "stop",\n value: function stop() {\n this.recording = false;\n var buffers = this.getBuffers();\n var leftBuffer = buffers[0].buffer;\n var rightBuffer = buffers[1].buffer;\n this.port.postMessage({\n name: \'buffers\',\n leftBuffer: leftBuffer,\n rightBuffer: rightBuffer\n }, [leftBuffer, rightBuffer]);\n this.clear();\n }\n }, {\n key: "getBuffers",\n value: function getBuffers() {\n var buffers = [];\n buffers.push(this.mergeBuffers(this.leftBuffers));\n buffers.push(this.mergeBuffers(this.rightBuffers));\n return buffers;\n }\n }, {\n key: "mergeBuffers",\n value: function mergeBuffers(channelBuffer) {\n var result = new Float32Array(this.recordedSamples);\n var offset = 0;\n var lng = channelBuffer.length;\n\n for (var i = 0; i < lng; i++) {\n var buffer = channelBuffer[i];\n result.set(buffer, offset);\n offset += buffer.length;\n }\n\n return result;\n }\n }, {\n key: "clear",\n value: function clear() {\n this.leftBuffers = [];\n this.rightBuffers = [];\n this.recordedSamples = 0;\n this.sampleLimit = null;\n }\n }]);\n\n return RecorderProcessor;\n}(_wrapNativeSuper(AudioWorkletProcessor));\n\nregisterProcessor(processorNames.recorderProcessor, RecorderProcessor);'},function(t,e,i){"use strict";i.r(e),e.default='function _typeof(obj) { if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof(obj); }\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }\n\nfunction _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }\n\nfunction _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }\n\nfunction _possibleConstructorReturn(self, call) { if (call && (_typeof(call) === "object" || typeof call === "function")) { return call; } return _assertThisInitialized(self); }\n\nfunction _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError("this hasn\'t been initialised - super() hasn\'t been called"); } return self; }\n\nfunction _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function"); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, writable: true, configurable: true } }); if (superClass) _setPrototypeOf(subClass, superClass); }\n\nfunction _wrapNativeSuper(Class) { var _cache = typeof Map === "function" ? new Map() : undefined; _wrapNativeSuper = function _wrapNativeSuper(Class) { if (Class === null || !_isNativeFunction(Class)) return Class; if (typeof Class !== "function") { throw new TypeError("Super expression must either be null or a function"); } if (typeof _cache !== "undefined") { if (_cache.has(Class)) return _cache.get(Class); _cache.set(Class, Wrapper); } function Wrapper() { return _construct(Class, arguments, _getPrototypeOf(this).constructor); } Wrapper.prototype = Object.create(Class.prototype, { constructor: { value: Wrapper, enumerable: false, writable: true, configurable: true } }); return _setPrototypeOf(Wrapper, Class); }; return _wrapNativeSuper(Class); }\n\nfunction isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === "function") return true; try { Date.prototype.toString.call(Reflect.construct(Date, [], function () {})); return true; } catch (e) { return false; } }\n\nfunction _construct(Parent, args, Class) { if (isNativeReflectConstruct()) { _construct = Reflect.construct; } else { _construct = function _construct(Parent, args, Class) { var a = [null]; a.push.apply(a, args); var Constructor = Function.bind.apply(Parent, a); var instance = new Constructor(); if (Class) _setPrototypeOf(instance, Class.prototype); return instance; }; } return _construct.apply(null, arguments); }\n\nfunction _isNativeFunction(fn) { return Function.toString.call(fn).indexOf("[native code]") !== -1; }\n\nfunction _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); }\n\nfunction _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); }; return _getPrototypeOf(o); }\n\n// import processor name via preval.require so that it\'s available as a value at compile time\nvar processorNames = {\n "recorderProcessor": "recorder-processor",\n "soundFileProcessor": "sound-file-processor",\n "amplitudeProcessor": "amplitude-processor"\n};\n\nvar SoundFileProcessor =\n/*#__PURE__*/\nfunction (_AudioWorkletProcesso) {\n _inherits(SoundFileProcessor, _AudioWorkletProcesso);\n\n function SoundFileProcessor() {\n _classCallCheck(this, SoundFileProcessor);\n\n return _possibleConstructorReturn(this, _getPrototypeOf(SoundFileProcessor).apply(this, arguments));\n }\n\n _createClass(SoundFileProcessor, [{\n key: "process",\n value: function process(inputs) {\n var input = inputs[0];\n var inputChannel = input[0];\n var position = inputChannel[inputChannel.length - 1] || 0;\n this.port.postMessage({\n name: \'position\',\n position: position\n });\n return true;\n }\n }]);\n\n return SoundFileProcessor;\n}(_wrapNativeSuper(AudioWorkletProcessor));\n\nregisterProcessor(processorNames.soundFileProcessor, SoundFileProcessor);'},function(t,e,i){"use strict";var n;function o(t){return(o="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t})(t)}void 0===(n=function(t){var a=i(1).audiocontext;void 0!==a.createStereoPanner?(p5.Panner=function(t,e){this.stereoPanner=this.input=a.createStereoPanner(),t.connect(this.stereoPanner),this.stereoPanner.connect(e)},p5.Panner.prototype.pan=function(t,e){var i=e||0,n=a.currentTime+i;this.stereoPanner.pan.linearRampToValueAtTime(t,n)},p5.Panner.prototype.inputChannels=function(){},p5.Panner.prototype.connect=function(t){this.stereoPanner.connect(t)},p5.Panner.prototype.disconnect=function(){this.stereoPanner&&this.stereoPanner.disconnect()}):(p5.Panner=function(t,e,i){this.input=a.createGain(),t.connect(this.input),this.left=a.createGain(),this.right=a.createGain(),this.left.channelInterpretation="discrete",this.right.channelInterpretation="discrete",1this.buffer.duration)throw"jump time out of range";if(e>this.buffer.duration-t)throw"end time out of range";var i=t||0,n=e||void 0;this.isPlaying()&&this.stop(0),this.play(0,this.playbackRate,this.output.gain.value,i,n)},p5.SoundFile.prototype.channels=function(){return this.buffer.numberOfChannels},p5.SoundFile.prototype.sampleRate=function(){return this.buffer.sampleRate},p5.SoundFile.prototype.frames=function(){return this.buffer.length},p5.SoundFile.prototype.getPeaks=function(t){if(!this.buffer)throw"Cannot load peaks yet, buffer is not loaded";if(t=t||5*window.width,this.buffer){for(var e=this.buffer,i=e.length/t,n=~~(i/10)||1,o=e.numberOfChannels,r=new Float32Array(Math.round(t)),s=0;sr[u])&&(r[u]=h)}return r}},p5.SoundFile.prototype.reverseBuffer=function(){if(!this.buffer)throw"SoundFile is not done loading";var t=this._lastPos/p.sampleRate,e=this.getVolume();this.setVolume(0,.001);for(var i=this.buffer.numberOfChannels,n=0;ne){var r=t[o],s=new c(r,o);i[o]=s,o+=6e3}o++}return i}function m(t){if(isFinite(t)&&0!==t){for(;t<90;)t*=2;for(;180t[r].hi&&r++,o[r]=void 0!==o[r]?(o[r]+i[s])/2:i[s]}return o},p5.FFT.prototype.getOctaveBands=function(t,e){t=t||3;var i=[],n={lo:(e=e||15.625)/Math.pow(2,1/(2*t)),ctr:e,hi:e*Math.pow(2,1/(2*t))};i.push(n);for(var o=c.audiocontext.sampleRate/2;n.hi=this._maxDelay)throw new Error("Delay Time exceeds maximum delay time of "+this._maxDelay+" second.");t.connect(this.input),this.leftDelay.delayTime.setValueAtTime(r,this.ac.currentTime),this.rightDelay.delayTime.setValueAtTime(r,this.ac.currentTime),this._leftGain.gain.value=o,this._rightGain.gain.value=o,n&&(this._leftFilter.freq(n),this._rightFilter.freq(n))},p5.Delay.prototype.delayTime=function(t){"number"!=typeof t?(t.connect(this.leftDelay.delayTime),t.connect(this.rightDelay.delayTime)):(this.leftDelay.delayTime.cancelScheduledValues(this.ac.currentTime),this.rightDelay.delayTime.cancelScheduledValues(this.ac.currentTime),this.leftDelay.delayTime.linearRampToValueAtTime(t,this.ac.currentTime),this.rightDelay.delayTime.linearRampToValueAtTime(t,this.ac.currentTime))},p5.Delay.prototype.feedback=function(t){if(t&&"number"!=typeof t)t.connect(this._leftGain.gain),t.connect(this._rightGain.gain);else{if(1<=t)throw new Error("Feedback value will force a positive feedback loop.");"number"==typeof t&&(this._leftGain.gain.value=t,this._rightGain.gain.value=t)}return this._leftGain.gain.value},p5.Delay.prototype.filter=function(t,e){this._leftFilter.set(t,e),this._rightFilter.set(t,e)},p5.Delay.prototype.setType=function(t){switch(1===t&&(t="pingPong"),this._split.disconnect(),this._leftFilter.disconnect(),this._rightFilter.disconnect(),this._split.connect(this.leftDelay,0),this._split.connect(this.rightDelay,1),t){case"pingPong":this._rightFilter.setType(this._leftFilter.biquad.type),this._leftFilter.output.connect(this._merge,0,0),this._rightFilter.output.connect(this._merge,0,1),this._leftFilter.output.connect(this.rightDelay),this._rightFilter.output.connect(this.leftDelay);break;default:this._leftFilter.output.connect(this._merge,0,0),this._rightFilter.output.connect(this._merge,0,1),this._leftFilter.output.connect(this.leftDelay),this._rightFilter.output.connect(this.rightDelay)}},p5.Delay.prototype.dispose=function(){i.prototype.dispose.apply(this),this._split.disconnect(),this._leftFilter.dispose(),this._rightFilter.dispose(),this._merge.disconnect(),this._leftGain.disconnect(),this._rightGain.disconnect(),this.leftDelay.disconnect(),this.rightDelay.disconnect(),this._split=void 0,this._leftFilter=void 0,this._rightFilter=void 0,this._merge=void 0,this._leftGain=void 0,this._rightGain=void 0,this.leftDelay=void 0,this.rightDelay=void 0}}.call(e,n,e,t))||(t.exports=i)},function(t,e,i){"use strict";var n;void 0===(n=function(t){var p=i(10),e=i(4);p5.Reverb=function(){e.call(this),this._initConvolverNode(),this.input.gain.value=.5,this._seconds=3,this._decay=2,this._reverse=!1,this._buildImpulse()},p5.Reverb.prototype=Object.create(e.prototype),p5.Reverb.prototype._initConvolverNode=function(){this.convolverNode=this.ac.createConvolver(),this.input.connect(this.convolverNode),this.convolverNode.connect(this.wet)},p5.Reverb.prototype._teardownConvolverNode=function(){this.convolverNode&&(this.convolverNode.disconnect(),delete this.convolverNode)},p5.Reverb.prototype._setBuffer=function(t){this._teardownConvolverNode(),this._initConvolverNode(),this.convolverNode.buffer=t},p5.Reverb.prototype.process=function(t,e,i,n){t.connect(this.input);var o=!1;e&&(this._seconds=e,o=!0),i&&(this._decay=i),n&&(this._reverse=n),o&&this._buildImpulse()},p5.Reverb.prototype.set=function(t,e,i){var n=!1;t&&(this._seconds=t,n=!0),e&&(this._decay=e),i&&(this._reverse=i),n&&this._buildImpulse()},p5.Reverb.prototype._buildImpulse=function(){var t,e,i=this.ac.sampleRate,n=i*this._seconds,o=this._decay,r=this.ac.createBuffer(2,n,i),s=r.getChannelData(0),a=r.getChannelData(1);for(e=0;e=t.parts.length?(t.scoreStep=0,t.onended()):(t.scoreStep=0,t.parts[t.currentPart-1].stop(),t.parts[t.currentPart].start())}p5.prototype.setBPM=function(t,e){for(var i in o=t,n.parts)n.parts[i]&&n.parts[i].setBPM(t,e)},p5.Phrase=function(t,e,i){this.phraseStep=0,this.name=t,this.callback=e,this.sequence=i},p5.Part=function(t,e){this.length=t||0,this.partStep=0,this.phrases=[],this.isPlaying=!1,this.noLoop(),this.tatums=e||.0625,this.metro=new p5.Metro,this.metro._init(),this.metro.beatLength(this.tatums),this.metro.setBPM(o),n.parts.push(this),this.callback=function(){}},p5.Part.prototype.setBPM=function(t,e){this.metro.setBPM(t,e)},p5.Part.prototype.getBPM=function(){return this.metro.getBPM()},p5.Part.prototype.start=function(t){if(!this.isPlaying){this.isPlaying=!0,this.metro.resetSync(this);var e=t||0;this.metro.start(e)}},p5.Part.prototype.loop=function(t){this.looping=!0,this.onended=function(){this.partStep=0};var e=t||0;this.start(e)},p5.Part.prototype.noLoop=function(){this.looping=!1,this.onended=function(){this.stop()}},p5.Part.prototype.stop=function(t){this.partStep=0,this.pause(t)},p5.Part.prototype.pause=function(t){this.isPlaying=!1;var e=t||0;this.metro.stop(e)},p5.Part.prototype.addPhrase=function(t,e,i){var n;if(3===arguments.length)n=new p5.Phrase(t,e,i);else{if(!(t instanceof p5.Phrase))throw"invalid input. addPhrase accepts name, callback, array or a p5.Phrase";n=t}this.phrases.push(n),n.sequence.length>this.length&&(this.length=n.sequence.length)},p5.Part.prototype.removePhrase=function(t){for(var e in this.phrases)this.phrases[e].name===t&&this.phrases.splice(e,1)},p5.Part.prototype.getPhrase=function(t){for(var e in this.phrases)if(this.phrases[e].name===t)return this.phrases[e]},p5.Part.prototype.replaceSequence=function(t,e){for(var i in this.phrases)this.phrases[i].name===t&&(this.phrases[i].sequence=e)},p5.Part.prototype.incrementStep=function(t){this.partStepthis.cutoff&&e>this.threshold&&0t)this.cancelScheduledValues(t),this.linearRampToValueAtTime(e,t);else{var n=this._searchAfter(t);n&&(this.cancelScheduledValues(t),n.type===u.TimelineSignal.Type.Linear?this.linearRampToValueAtTime(e,t):n.type===u.TimelineSignal.Type.Exponential&&this.exponentialRampToValueAtTime(e,t)),this.setValueAtTime(e,t)}return this},u.TimelineSignal.prototype.linearRampToValueBetween=function(t,e,i){return this.setRampPoint(e),this.linearRampToValueAtTime(t,i),this},u.TimelineSignal.prototype.exponentialRampToValueBetween=function(t,e,i){return this.setRampPoint(e),this.exponentialRampToValueAtTime(t,i),this},u.TimelineSignal.prototype._searchBefore=function(t){return this._events.get(t)},u.TimelineSignal.prototype._searchAfter=function(t){return this._events.getAfter(t)},u.TimelineSignal.prototype.getValueAtTime=function(t){t=this.toSeconds(t);var e=this._searchAfter(t),i=this._searchBefore(t),n=this._initial;if(null===i)n=this._initial;else if(i.type===u.TimelineSignal.Type.Target){var o,r=this._events.getBefore(i.time);o=null===r?this._initial:r.value,n=this._exponentialApproach(i.time,o,i.value,i.constant,t)}else n=i.type===u.TimelineSignal.Type.Curve?this._curveInterpolate(i.time,i.value,i.duration,t):null===e?i.value:e.type===u.TimelineSignal.Type.Linear?this._linearInterpolate(i.time,i.value,e.time,e.value,t):e.type===u.TimelineSignal.Type.Exponential?this._exponentialInterpolate(i.time,i.value,e.time,e.value,t):i.value;return n},u.TimelineSignal.prototype.connect=u.SignalBase.prototype.connect,u.TimelineSignal.prototype._exponentialApproach=function(t,e,i,n,o){return i+(e-i)*Math.exp(-(o-t)/n)},u.TimelineSignal.prototype._linearInterpolate=function(t,e,i,n,o){return e+(o-t)/(i-t)*(n-e)},u.TimelineSignal.prototype._exponentialInterpolate=function(t,e,i,n,o){return(e=Math.max(this._minOutput,e))*Math.pow(n/e,(o-t)/(i-t))},u.TimelineSignal.prototype._curveInterpolate=function(t,e,i,n){var o=e.length;if(t+i<=n)return e[o-1];if(n<=t)return e[0];var r=(n-t)/i,s=Math.floor((o-1)*r),a=Math.ceil((o-1)*r),u=e[s],p=e[a];return a===s?u:this._linearInterpolate(s,u,a,p,r*(o-1))},u.TimelineSignal.prototype.dispose=function(){u.Signal.prototype.dispose.call(this),u.Param.prototype.dispose.call(this),this._events.dispose(),this._events=null},u.TimelineSignal}.apply(e,n))||(t.exports=o)},function(t,e,i){"use strict";var n;void 0===(n=function(t){var e=i(4);return p5.Filter=function(t){e.call(this),this.biquad=this.ac.createBiquadFilter(),this.input.connect(this.biquad),this.biquad.connect(this.wet),t&&this.setType(t),this._on=!0,this._untoggledType=this.biquad.type},p5.Filter.prototype=Object.create(e.prototype),p5.Filter.prototype.process=function(t,e,i,n){t.connect(this.input),this.set(e,i,n)},p5.Filter.prototype.set=function(t,e,i){t&&this.freq(t,i),e&&this.res(e,i)},p5.Filter.prototype.freq=function(t,e){var i=e||0;return t<=0&&(t=1),"number"==typeof t?(this.biquad.frequency.cancelScheduledValues(this.ac.currentTime+.01+i),this.biquad.frequency.exponentialRampToValueAtTime(t,this.ac.currentTime+.02+i)):t&&t.connect(this.biquad.frequency),this.biquad.frequency.value},p5.Filter.prototype.res=function(t,e){var i=e||0;return"number"==typeof t?(this.biquad.Q.value=t,this.biquad.Q.cancelScheduledValues(this.ac.currentTime+.01+i),this.biquad.Q.linearRampToValueAtTime(t,this.ac.currentTime+.02+i)):t&&t.connect(this.biquad.Q),this.biquad.Q.value},p5.Filter.prototype.gain=function(t,e){var i=e||0;return"number"==typeof t?(this.biquad.gain.value=t,this.biquad.gain.cancelScheduledValues(this.ac.currentTime+.01+i),this.biquad.gain.linearRampToValueAtTime(t,this.ac.currentTime+.02+i)):t&&t.connect(this.biquad.gain),this.biquad.gain.value},p5.Filter.prototype.toggle=function(){return this._on=!this._on,!0===this._on?this.biquad.type=this._untoggledType:!1===this._on&&(this.biquad.type="allpass"),this._on},p5.Filter.prototype.setType=function(t){this.biquad.type=t,this._untoggledType=this.biquad.type},p5.Filter.prototype.dispose=function(){e.prototype.dispose.apply(this),this.biquad&&(this.biquad.disconnect(),delete this.biquad)},p5.LowPass=function(){p5.Filter.call(this,"lowpass")},p5.LowPass.prototype=Object.create(p5.Filter.prototype),p5.HighPass=function(){p5.Filter.call(this,"highpass")},p5.HighPass.prototype=Object.create(p5.Filter.prototype),p5.BandPass=function(){p5.Filter.call(this,"bandpass")},p5.BandPass.prototype=Object.create(p5.Filter.prototype),p5.Filter}.call(e,i,e,t))||(t.exports=n)},function(t,e,i){var n,o;n=[i(0),i(7),i(25),i(2),i(9)],void 0===(o=function(e){"use strict";return e.Subtract=function(t){this.createInsOuts(2,0),this._sum=this.input[0]=this.output=new e.Gain,this._neg=new e.Negate,this._param=this.input[1]=new e.Signal(t),this._param.chain(this._neg,this._sum)},e.extend(e.Subtract,e.Signal),e.Subtract.prototype.dispose=function(){return e.prototype.dispose.call(this),this._neg.dispose(),this._neg=null,this._sum.disconnect(),this._sum=null,this._param.dispose(),this._param=null,this},e.Subtract}.apply(e,n))||(t.exports=o)},function(n,o,r){"use strict";(function(t){var e,i;t.TONE_SILENCE_VERSION_LOGGING=!0,e=[r(35),r(11),r(0)],void 0===(i=function(n,t,e){var o=new window.AudioContext;return e.context.dispose(),e.setContext(o),p5.prototype.getAudioContext=function(){return o},p5.prototype.userStartAudio=function(t,e){var i=t;return t instanceof p5.Element?i=t.elt:t instanceof Array&&t[0]instanceof p5.Element&&(i=t.map(function(t){return t.elt})),n(o,i,e)},o}.apply(o,e))||(n.exports=i)}).call(this,r(34))},function(t,e,i){var n,o;n=[i(0)],void 0===(o=function(s){"use strict";return s.Emitter=function(){this._events={}},s.extend(s.Emitter),s.Emitter.prototype.on=function(t,e){for(var i=t.split(/\W+/),n=0;nthis.memory){var i=this.length-this.memory;this._timeline.splice(0,i)}return this},e.Timeline.prototype.remove=function(t){if(this._iterating)this._toRemove.push(t);else{var e=this._timeline.indexOf(t);-1!==e&&this._timeline.splice(e,1)}return this},e.Timeline.prototype.get=function(t){var e=this._search(t);return-1!==e?this._timeline[e]:null},e.Timeline.prototype.peek=function(){return this._timeline[0]},e.Timeline.prototype.shift=function(){return this._timeline.shift()},e.Timeline.prototype.getAfter=function(t){var e=this._search(t);return e+1=t&&(this._timeline=[]);return this},e.Timeline.prototype.cancelBefore=function(t){if(this._timeline.length){var e=this._search(t);0<=e&&(this._timeline=this._timeline.slice(e+1))}return this},e.Timeline.prototype._search=function(t){var e=0,i=this._timeline.length,n=i;if(0t)return o;r.time>t?n=o:r.time=t;)i--;return this._iterate(e,i+1),this},e.Timeline.prototype.forEachAtTime=function(e,i){var t=this._search(e);return-1!==t&&this._iterate(function(t){t.time===e&&i(t)},0,t),this},e.Timeline.prototype.dispose=function(){e.prototype.dispose.call(this),this._timeline=null,this._toRemove=null},e.Timeline}.apply(e,n))||(t.exports=o)},function(t,e,i){var n,o;n=[i(0),i(3),i(2)],void 0===(o=function(t){"use strict";return t.Negate=function(){this._multiply=this.input=this.output=new t.Multiply(-1)},t.extend(t.Negate,t.SignalBase),t.Negate.prototype.dispose=function(){return t.prototype.dispose.call(this),this._multiply.dispose(),this._multiply=null,this},t.Negate}.apply(e,n))||(t.exports=o)},function(t,e,i){var n,o;n=[i(0),i(2),i(3),i(5)],void 0===(o=function(t){"use strict";return t.GreaterThanZero=function(){this._thresh=this.output=new t.WaveShaper(function(t){return t<=0?0:1},127),this._scale=this.input=new t.Multiply(1e4),this._scale.connect(this._thresh)},t.extend(t.GreaterThanZero,t.SignalBase),t.GreaterThanZero.prototype.dispose=function(){return t.prototype.dispose.call(this),this._scale.dispose(),this._scale=null,this._thresh.dispose(),this._thresh=null,this},t.GreaterThanZero}.apply(e,n))||(t.exports=o)},function(t,e,i){var n,o;n=[i(0),i(14),i(66),i(18),i(11)],void 0===(o=function(o){"use strict";return o.Clock=function(){o.Emitter.call(this);var t=this.optionsObject(arguments,["callback","frequency"],o.Clock.defaults);this.callback=t.callback,this._nextTick=0,this._lastState=o.State.Stopped,this.frequency=new o.TimelineSignal(t.frequency,o.Type.Frequency),this._readOnly("frequency"),this.ticks=0,this._state=new o.TimelineState(o.State.Stopped),this._boundLoop=this._loop.bind(this),this.context.on("tick",this._boundLoop)},o.extend(o.Clock,o.Emitter),o.Clock.defaults={callback:o.noOp,frequency:1,lookAhead:"auto"},Object.defineProperty(o.Clock.prototype,"state",{get:function(){return this._state.getValueAtTime(this.now())}}),o.Clock.prototype.start=function(t,e){return t=this.toSeconds(t),this._state.getValueAtTime(t)!==o.State.Started&&this._state.add({state:o.State.Started,time:t,offset:e}),this},o.Clock.prototype.stop=function(t){return t=this.toSeconds(t),this._state.cancel(t),this._state.setStateAtTime(o.State.Stopped,t),this},o.Clock.prototype.pause=function(t){return t=this.toSeconds(t),this._state.getValueAtTime(t)===o.State.Started&&this._state.setStateAtTime(o.State.Paused,t),this},o.Clock.prototype._loop=function(){for(var t=this.now()+this.context.lookAhead+this.context.updateInterval+2*this.context.lag;t>this._nextTick&&this._state;){var e=this._state.getValueAtTime(this._nextTick);if(e!==this._lastState){this._lastState=e;var i=this._state.get(this._nextTick);e===o.State.Started?(this._nextTick=i.time,this.isUndef(i.offset)||(this.ticks=i.offset),this.emit("start",i.time,this.ticks)):e===o.State.Stopped?(this.ticks=0,this.emit("stop",i.time)):e===o.State.Paused&&this.emit("pause",i.time)}var n=this._nextTick;this.frequency&&(this._nextTick+=1/this.frequency.getValueAtTime(this._nextTick),e===o.State.Started&&(this.callback(n),this.ticks++))}},o.Clock.prototype.getStateAtTime=function(t){return t=this.toSeconds(t),this._state.getValueAtTime(t)},o.Clock.prototype.dispose=function(){o.Emitter.prototype.dispose.call(this),this.context.off("tick",this._boundLoop),this._writable("frequency"),this.frequency.dispose(),this.frequency=null,this._boundLoop=null,this._nextTick=1/0,this.callback=null,this._state.dispose(),this._state=null},o.Clock}.apply(e,n))||(t.exports=o)},function(t,e,n){"use strict";var i;void 0===(i=function(t){var i=n(1),e=n(29),r=n(6).noteToFreq;p5.MonoSynth=function(){e.call(this),this.oscillator=new p5.Oscillator,this.env=new p5.Envelope,this.env.setRange(1,0),this.env.setExp(!0),this.setADSR(.02,.25,.05,.35),this.oscillator.disconnect(),this.oscillator.connect(this.output),this.env.disconnect(),this.env.setInput(this.output.gain),this.oscillator.output.gain.value=1,this.oscillator.start(),this.connect(),i.soundArray.push(this)},p5.MonoSynth.prototype=Object.create(p5.AudioVoice.prototype),p5.MonoSynth.prototype.play=function(t,e,i,n){this.triggerAttack(t,e,~~i),this.triggerRelease(~~i+(n||.15))},p5.MonoSynth.prototype.triggerAttack=function(t,e,i){i=~~i;var n=r(t),o=e||.1;this.oscillator.freq(n,0,i),this.env.ramp(this.output.gain,i,o)},p5.MonoSynth.prototype.triggerRelease=function(t){t=t||0;this.env.ramp(this.output.gain,t,0)},p5.MonoSynth.prototype.setADSR=function(t,e,i,n){this.env.setADSR(t,e,i,n)},Object.defineProperties(p5.MonoSynth.prototype,{attack:{get:function(){return this.env.aTime},set:function(t){this.env.setADSR(t,this.env.dTime,this.env.sPercent,this.env.rTime)}},decay:{get:function(){return this.env.dTime},set:function(t){this.env.setADSR(this.env.aTime,t,this.env.sPercent,this.env.rTime)}},sustain:{get:function(){return this.env.sPercent},set:function(t){this.env.setADSR(this.env.aTime,this.env.dTime,t,this.env.rTime)}},release:{get:function(){return this.env.rTime},set:function(t){this.env.setADSR(this.env.aTime,this.env.dTime,this.env.sPercent,t)}}}),p5.MonoSynth.prototype.amp=function(t,e){var i=e||0;return void 0!==t&&this.oscillator.amp(t,i),this.oscillator.amp().value},p5.MonoSynth.prototype.connect=function(t){var e=t||i.input;this.output.connect(e.input?e.input:e)},p5.MonoSynth.prototype.disconnect=function(){this.output&&this.output.disconnect()},p5.MonoSynth.prototype.dispose=function(){e.prototype.dispose.apply(this),this.env&&this.env.dispose(),this.oscillator&&this.oscillator.dispose()}}.call(e,n,e,t))||(t.exports=i)},function(t,e,n){"use strict";var i;void 0===(i=function(){var i=n(1);return p5.AudioVoice=function(){this.ac=i.audiocontext,this.output=this.ac.createGain(),this.connect(),i.soundArray.push(this)},p5.AudioVoice.prototype.play=function(t,e,i,n){},p5.AudioVoice.prototype.triggerAttack=function(t,e,i){},p5.AudioVoice.prototype.triggerRelease=function(t){},p5.AudioVoice.prototype.amp=function(t,e){},p5.AudioVoice.prototype.connect=function(t){var e=t||i.input;this.output.connect(e.input?e.input:e)},p5.AudioVoice.prototype.disconnect=function(){this.output.disconnect()},p5.AudioVoice.prototype.dispose=function(){this.output&&(this.output.disconnect(),delete this.output)},p5.AudioVoice}.call(e,n,e,t))||(t.exports=i)},function(t,e,i){"use strict";var n;void 0===(n=function(t){var c=i(1),h=i(14),l=i(6).noteToFreq;p5.PolySynth=function(t,e){this.audiovoices=[],this.notes={},this._newest=0,this._oldest=0,this.maxVoices=e||8,this.AudioVoice=void 0===t?p5.MonoSynth:t,this._voicesInUse=new h(0),this.output=c.audiocontext.createGain(),this.connect(),this._allocateVoices(),c.soundArray.push(this)},p5.PolySynth.prototype._allocateVoices=function(){for(var t=0;t= this.sampleLimit) {\n this.stop();\n return true;\n }\n\n var input = inputs[0];\n var output = outputs[0];\n\n for (var channel = 0; channel < output.length; ++channel) {\n var inputChannel = input[channel];\n\n if (channel === 0) {\n this.leftBuffers.push(inputChannel);\n\n if (this.numInputChannels === 1) {\n this.rightBuffers.push(inputChannel);\n }\n } else if (channel === 1 && this.numInputChannels > 1) {\n this.rightBuffers.push(inputChannel);\n }\n }\n\n this.recordedSamples += output[0].length;\n return true;\n }\n }, {\n key: "record",\n value: function record(duration) {\n if (duration) {\n this.sampleLimit = Math.round(duration * sampleRate);\n }\n\n this.recording = true;\n }\n }, {\n key: "stop",\n value: function stop() {\n this.recording = false;\n var buffers = this.getBuffers();\n var leftBuffer = buffers[0].buffer;\n var rightBuffer = buffers[1].buffer;\n this.port.postMessage({\n name: \'buffers\',\n leftBuffer: leftBuffer,\n rightBuffer: rightBuffer\n }, [leftBuffer, rightBuffer]);\n this.clear();\n }\n }, {\n key: "getBuffers",\n value: function getBuffers() {\n var buffers = [];\n buffers.push(this.mergeBuffers(this.leftBuffers));\n buffers.push(this.mergeBuffers(this.rightBuffers));\n return buffers;\n }\n }, {\n key: "mergeBuffers",\n value: function mergeBuffers(channelBuffer) {\n var result = new Float32Array(this.recordedSamples);\n var offset = 0;\n var lng = channelBuffer.length;\n\n for (var i = 0; i < lng; i++) {\n var buffer = channelBuffer[i];\n result.set(buffer, offset);\n offset += buffer.length;\n }\n\n return result;\n }\n }, {\n key: "clear",\n value: function clear() {\n this.leftBuffers = [];\n this.rightBuffers = [];\n this.recordedSamples = 0;\n this.sampleLimit = null;\n }\n }]);\n\n return RecorderProcessor;\n}(_wrapNativeSuper(AudioWorkletProcessor));\n\nregisterProcessor(processorNames.recorderProcessor, RecorderProcessor);'},function(t,e,i){"use strict";i.r(e),e.default='function _typeof(obj) { if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof(obj); }\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }\n\nfunction _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }\n\nfunction _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }\n\nfunction _possibleConstructorReturn(self, call) { if (call && (_typeof(call) === "object" || typeof call === "function")) { return call; } return _assertThisInitialized(self); }\n\nfunction _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError("this hasn\'t been initialised - super() hasn\'t been called"); } return self; }\n\nfunction _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function"); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, writable: true, configurable: true } }); if (superClass) _setPrototypeOf(subClass, superClass); }\n\nfunction _wrapNativeSuper(Class) { var _cache = typeof Map === "function" ? new Map() : undefined; _wrapNativeSuper = function _wrapNativeSuper(Class) { if (Class === null || !_isNativeFunction(Class)) return Class; if (typeof Class !== "function") { throw new TypeError("Super expression must either be null or a function"); } if (typeof _cache !== "undefined") { if (_cache.has(Class)) return _cache.get(Class); _cache.set(Class, Wrapper); } function Wrapper() { return _construct(Class, arguments, _getPrototypeOf(this).constructor); } Wrapper.prototype = Object.create(Class.prototype, { constructor: { value: Wrapper, enumerable: false, writable: true, configurable: true } }); return _setPrototypeOf(Wrapper, Class); }; return _wrapNativeSuper(Class); }\n\nfunction isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === "function") return true; try { Date.prototype.toString.call(Reflect.construct(Date, [], function () {})); return true; } catch (e) { return false; } }\n\nfunction _construct(Parent, args, Class) { if (isNativeReflectConstruct()) { _construct = Reflect.construct; } else { _construct = function _construct(Parent, args, Class) { var a = [null]; a.push.apply(a, args); var Constructor = Function.bind.apply(Parent, a); var instance = new Constructor(); if (Class) _setPrototypeOf(instance, Class.prototype); return instance; }; } return _construct.apply(null, arguments); }\n\nfunction _isNativeFunction(fn) { return Function.toString.call(fn).indexOf("[native code]") !== -1; }\n\nfunction _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); }\n\nfunction _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); }; return _getPrototypeOf(o); }\n\n// import processor name via preval.require so that it\'s available as a value at compile time\nvar processorNames = {\n "recorderProcessor": "recorder-processor",\n "soundFileProcessor": "sound-file-processor",\n "amplitudeProcessor": "amplitude-processor"\n};\n\nvar SoundFileProcessor =\n/*#__PURE__*/\nfunction (_AudioWorkletProcesso) {\n _inherits(SoundFileProcessor, _AudioWorkletProcesso);\n\n function SoundFileProcessor() {\n var _this;\n\n _classCallCheck(this, SoundFileProcessor);\n\n _this = _possibleConstructorReturn(this, _getPrototypeOf(SoundFileProcessor).call(this));\n _this.paused = false;\n\n _this.port.onmessage = function (event) {\n var data = event.data;\n\n if (data.name === \'play\') {\n _this.paused = false;\n } else if (data.name === \'pause\') {\n _this.paused = true;\n }\n };\n\n return _this;\n }\n\n _createClass(SoundFileProcessor, [{\n key: "process",\n value: function process(inputs) {\n var input = inputs[0];\n var inputChannel = input[0];\n var position = inputChannel[inputChannel.length - 1];\n\n if (!this.paused) {\n this.port.postMessage({\n name: \'position\',\n position: position\n });\n }\n\n return true;\n }\n }]);\n\n return SoundFileProcessor;\n}(_wrapNativeSuper(AudioWorkletProcessor));\n\nregisterProcessor(processorNames.soundFileProcessor, SoundFileProcessor);'},function(t,e,i){"use strict";i.r(e),e.default='function _typeof(obj) { if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof(obj); }\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }\n\nfunction _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }\n\nfunction _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }\n\nfunction _possibleConstructorReturn(self, call) { if (call && (_typeof(call) === "object" || typeof call === "function")) { return call; } return _assertThisInitialized(self); }\n\nfunction _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError("this hasn\'t been initialised - super() hasn\'t been called"); } return self; }\n\nfunction _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function"); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, writable: true, configurable: true } }); if (superClass) _setPrototypeOf(subClass, superClass); }\n\nfunction _wrapNativeSuper(Class) { var _cache = typeof Map === "function" ? new Map() : undefined; _wrapNativeSuper = function _wrapNativeSuper(Class) { if (Class === null || !_isNativeFunction(Class)) return Class; if (typeof Class !== "function") { throw new TypeError("Super expression must either be null or a function"); } if (typeof _cache !== "undefined") { if (_cache.has(Class)) return _cache.get(Class); _cache.set(Class, Wrapper); } function Wrapper() { return _construct(Class, arguments, _getPrototypeOf(this).constructor); } Wrapper.prototype = Object.create(Class.prototype, { constructor: { value: Wrapper, enumerable: false, writable: true, configurable: true } }); return _setPrototypeOf(Wrapper, Class); }; return _wrapNativeSuper(Class); }\n\nfunction isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === "function") return true; try { Date.prototype.toString.call(Reflect.construct(Date, [], function () {})); return true; } catch (e) { return false; } }\n\nfunction _construct(Parent, args, Class) { if (isNativeReflectConstruct()) { _construct = Reflect.construct; } else { _construct = function _construct(Parent, args, Class) { var a = [null]; a.push.apply(a, args); var Constructor = Function.bind.apply(Parent, a); var instance = new Constructor(); if (Class) _setPrototypeOf(instance, Class.prototype); return instance; }; } return _construct.apply(null, arguments); }\n\nfunction _isNativeFunction(fn) { return Function.toString.call(fn).indexOf("[native code]") !== -1; }\n\nfunction _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); }\n\nfunction _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); }; return _getPrototypeOf(o); }\n\n// import processor name via preval.require so that it\'s available as a value at compile time\nvar processorNames = {\n "recorderProcessor": "recorder-processor",\n "soundFileProcessor": "sound-file-processor",\n "amplitudeProcessor": "amplitude-processor"\n};\n\nvar AmplitudeProcessor =\n/*#__PURE__*/\nfunction (_AudioWorkletProcesso) {\n _inherits(AmplitudeProcessor, _AudioWorkletProcesso);\n\n function AmplitudeProcessor(options) {\n var _this;\n\n _classCallCheck(this, AmplitudeProcessor);\n\n _this = _possibleConstructorReturn(this, _getPrototypeOf(AmplitudeProcessor).call(this));\n var processorOptions = options.processorOptions || {};\n _this.smoothing = processorOptions.smoothing || 0;\n _this.normalize = processorOptions.normalize || false;\n _this.stereoVol = [0, 0];\n _this.stereoVolNorm = [0, 0];\n _this.volMax = 0.001;\n\n _this.port.onmessage = function (event) {\n var data = event.data;\n\n if (data.name === \'toggleNormalize\') {\n _this.normalize = data.normalize;\n } else if (data.name === \'smoothing\') {\n _this.smoothing = Math.max(0, Math.min(1, data.smoothing));\n }\n };\n\n return _this;\n } // TO DO make this stereo / dependent on # of audio channels\n\n\n _createClass(AmplitudeProcessor, [{\n key: "process",\n value: function process(inputs, outputs) {\n var input = inputs[0];\n var output = outputs[0];\n var smoothing = this.smoothing;\n\n for (var channel = 0; channel < input.length; ++channel) {\n var inputBuffer = input[channel];\n var bufLength = inputBuffer.length;\n var sum = 0;\n\n for (var i = 0; i < bufLength; i++) {\n var x = inputBuffer[i];\n\n if (this.normalize) {\n sum += Math.max(Math.min(x / this.volMax, 1), -1) * Math.max(Math.min(x / this.volMax, 1), -1);\n } else {\n sum += x * x;\n }\n } // ... then take the square root of the sum.\n\n\n var rms = Math.sqrt(sum / bufLength);\n this.stereoVol[channel] = Math.max(rms, this.stereoVol[channel] * smoothing);\n this.volMax = Math.max(this.stereoVol[channel], this.volMax);\n } // calculate stero normalized volume and add volume from all channels together\n\n\n var volSum = 0;\n\n for (var index = 0; index < this.stereoVol.length; index++) {\n this.stereoVolNorm[index] = Math.max(Math.min(this.stereoVol[index] / this.volMax, 1), 0);\n volSum += this.stereoVol[index];\n } // volume is average of channels\n\n\n var volume = volSum / this.stereoVol.length; // normalized value\n\n var volNorm = Math.max(Math.min(volume / this.volMax, 1), 0);\n this.port.postMessage({\n name: \'amplitude\',\n volume: volume,\n volNorm: volNorm,\n stereoVol: this.stereoVol,\n stereoVolNorm: this.stereoVolNorm\n }); // pass input through to output\n\n for (var _channel = 0; _channel < output.length; ++_channel) {\n output[_channel].set(input[_channel]);\n }\n\n return true;\n }\n }]);\n\n return AmplitudeProcessor;\n}(_wrapNativeSuper(AudioWorkletProcessor));\n\nregisterProcessor(processorNames.amplitudeProcessor, AmplitudeProcessor);'},function(t,e,i){"use strict";var n;function o(t){return(o="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t})(t)}void 0===(n=function(t){var a=i(1).audiocontext;void 0!==a.createStereoPanner?(p5.Panner=function(t,e){this.stereoPanner=this.input=a.createStereoPanner(),t.connect(this.stereoPanner),this.stereoPanner.connect(e)},p5.Panner.prototype.pan=function(t,e){var i=e||0,n=a.currentTime+i;this.stereoPanner.pan.linearRampToValueAtTime(t,n)},p5.Panner.prototype.inputChannels=function(){},p5.Panner.prototype.connect=function(t){this.stereoPanner.connect(t)},p5.Panner.prototype.disconnect=function(){this.stereoPanner&&this.stereoPanner.disconnect()}):(p5.Panner=function(t,e,i){this.input=a.createGain(),t.connect(this.input),this.left=a.createGain(),this.right=a.createGain(),this.left.channelInterpretation="discrete",this.right.channelInterpretation="discrete",1this.buffer.duration)throw"jump time out of range";if(e>this.buffer.duration-t)throw"end time out of range";var i=t||0,n=e||void 0;this.isPlaying()&&this.stop(0),this.play(0,this.playbackRate,this.output.gain.value,i,n)},p5.SoundFile.prototype.channels=function(){return this.buffer.numberOfChannels},p5.SoundFile.prototype.sampleRate=function(){return this.buffer.sampleRate},p5.SoundFile.prototype.frames=function(){return this.buffer.length},p5.SoundFile.prototype.getPeaks=function(t){if(!this.buffer)throw"Cannot load peaks yet, buffer is not loaded";if(t=t||5*window.width,this.buffer){for(var e=this.buffer,i=e.length/t,n=~~(i/10)||1,o=e.numberOfChannels,r=new Float32Array(Math.round(t)),s=0;sr[u])&&(r[u]=h)}return r}},p5.SoundFile.prototype.reverseBuffer=function(){if(!this.buffer)throw"SoundFile is not done loading";var t=this._lastPos/p.sampleRate,e=this.getVolume();this.setVolume(0,.001);for(var i=this.buffer.numberOfChannels,n=0;ne){var r=t[o],s=new c(r,o);i[o]=s,o+=6e3}o++}return i}function m(t){if(isFinite(t)&&0!==t){for(;t<90;)t*=2;for(;180t[r].hi&&r++,o[r]=void 0!==o[r]?(o[r]+i[s])/2:i[s]}return o},p5.FFT.prototype.getOctaveBands=function(t,e){t=t||3;var i=[],n={lo:(e=e||15.625)/Math.pow(2,1/(2*t)),ctr:e,hi:e*Math.pow(2,1/(2*t))};i.push(n);for(var o=c.audiocontext.sampleRate/2;n.hi=this._maxDelay)throw new Error("Delay Time exceeds maximum delay time of "+this._maxDelay+" second.");t.connect(this.input),this.leftDelay.delayTime.setValueAtTime(r,this.ac.currentTime),this.rightDelay.delayTime.setValueAtTime(r,this.ac.currentTime),this._leftGain.gain.value=o,this._rightGain.gain.value=o,n&&(this._leftFilter.freq(n),this._rightFilter.freq(n))},p5.Delay.prototype.delayTime=function(t){"number"!=typeof t?(t.connect(this.leftDelay.delayTime),t.connect(this.rightDelay.delayTime)):(this.leftDelay.delayTime.cancelScheduledValues(this.ac.currentTime),this.rightDelay.delayTime.cancelScheduledValues(this.ac.currentTime),this.leftDelay.delayTime.linearRampToValueAtTime(t,this.ac.currentTime),this.rightDelay.delayTime.linearRampToValueAtTime(t,this.ac.currentTime))},p5.Delay.prototype.feedback=function(t){if(t&&"number"!=typeof t)t.connect(this._leftGain.gain),t.connect(this._rightGain.gain);else{if(1<=t)throw new Error("Feedback value will force a positive feedback loop.");"number"==typeof t&&(this._leftGain.gain.value=t,this._rightGain.gain.value=t)}return this._leftGain.gain.value},p5.Delay.prototype.filter=function(t,e){this._leftFilter.set(t,e),this._rightFilter.set(t,e)},p5.Delay.prototype.setType=function(t){switch(1===t&&(t="pingPong"),this._split.disconnect(),this._leftFilter.disconnect(),this._rightFilter.disconnect(),this._split.connect(this.leftDelay,0),this._split.connect(this.rightDelay,1),t){case"pingPong":this._rightFilter.setType(this._leftFilter.biquad.type),this._leftFilter.output.connect(this._merge,0,0),this._rightFilter.output.connect(this._merge,0,1),this._leftFilter.output.connect(this.rightDelay),this._rightFilter.output.connect(this.leftDelay);break;default:this._leftFilter.output.connect(this._merge,0,0),this._rightFilter.output.connect(this._merge,0,1),this._leftFilter.output.connect(this.leftDelay),this._rightFilter.output.connect(this.rightDelay)}},p5.Delay.prototype.dispose=function(){i.prototype.dispose.apply(this),this._split.disconnect(),this._leftFilter.dispose(),this._rightFilter.dispose(),this._merge.disconnect(),this._leftGain.disconnect(),this._rightGain.disconnect(),this.leftDelay.disconnect(),this.rightDelay.disconnect(),this._split=void 0,this._leftFilter=void 0,this._rightFilter=void 0,this._merge=void 0,this._leftGain=void 0,this._rightGain=void 0,this.leftDelay=void 0,this.rightDelay=void 0}}.call(e,n,e,t))||(t.exports=i)},function(t,e,i){"use strict";var n;void 0===(n=function(t){var p=i(10),e=i(4);p5.Reverb=function(){e.call(this),this._initConvolverNode(),this.input.gain.value=.5,this._seconds=3,this._decay=2,this._reverse=!1,this._buildImpulse()},p5.Reverb.prototype=Object.create(e.prototype),p5.Reverb.prototype._initConvolverNode=function(){this.convolverNode=this.ac.createConvolver(),this.input.connect(this.convolverNode),this.convolverNode.connect(this.wet)},p5.Reverb.prototype._teardownConvolverNode=function(){this.convolverNode&&(this.convolverNode.disconnect(),delete this.convolverNode)},p5.Reverb.prototype._setBuffer=function(t){this._teardownConvolverNode(),this._initConvolverNode(),this.convolverNode.buffer=t},p5.Reverb.prototype.process=function(t,e,i,n){t.connect(this.input);var o=!1;e&&(this._seconds=e,o=!0),i&&(this._decay=i),n&&(this._reverse=n),o&&this._buildImpulse()},p5.Reverb.prototype.set=function(t,e,i){var n=!1;t&&(this._seconds=t,n=!0),e&&(this._decay=e),i&&(this._reverse=i),n&&this._buildImpulse()},p5.Reverb.prototype._buildImpulse=function(){var t,e,i=this.ac.sampleRate,n=i*this._seconds,o=this._decay,r=this.ac.createBuffer(2,n,i),s=r.getChannelData(0),a=r.getChannelData(1);for(e=0;e=t.parts.length?(t.scoreStep=0,t.onended()):(t.scoreStep=0,t.parts[t.currentPart-1].stop(),t.parts[t.currentPart].start())}p5.prototype.setBPM=function(t,e){for(var i in o=t,n.parts)n.parts[i]&&n.parts[i].setBPM(t,e)},p5.Phrase=function(t,e,i){this.phraseStep=0,this.name=t,this.callback=e,this.sequence=i},p5.Part=function(t,e){this.length=t||0,this.partStep=0,this.phrases=[],this.isPlaying=!1,this.noLoop(),this.tatums=e||.0625,this.metro=new p5.Metro,this.metro._init(),this.metro.beatLength(this.tatums),this.metro.setBPM(o),n.parts.push(this),this.callback=function(){}},p5.Part.prototype.setBPM=function(t,e){this.metro.setBPM(t,e)},p5.Part.prototype.getBPM=function(){return this.metro.getBPM()},p5.Part.prototype.start=function(t){if(!this.isPlaying){this.isPlaying=!0,this.metro.resetSync(this);var e=t||0;this.metro.start(e)}},p5.Part.prototype.loop=function(t){this.looping=!0,this.onended=function(){this.partStep=0};var e=t||0;this.start(e)},p5.Part.prototype.noLoop=function(){this.looping=!1,this.onended=function(){this.stop()}},p5.Part.prototype.stop=function(t){this.partStep=0,this.pause(t)},p5.Part.prototype.pause=function(t){this.isPlaying=!1;var e=t||0;this.metro.stop(e)},p5.Part.prototype.addPhrase=function(t,e,i){var n;if(3===arguments.length)n=new p5.Phrase(t,e,i);else{if(!(t instanceof p5.Phrase))throw"invalid input. addPhrase accepts name, callback, array or a p5.Phrase";n=t}this.phrases.push(n),n.sequence.length>this.length&&(this.length=n.sequence.length)},p5.Part.prototype.removePhrase=function(t){for(var e in this.phrases)this.phrases[e].name===t&&this.phrases.splice(e,1)},p5.Part.prototype.getPhrase=function(t){for(var e in this.phrases)if(this.phrases[e].name===t)return this.phrases[e]},p5.Part.prototype.replaceSequence=function(t,e){for(var i in this.phrases)this.phrases[i].name===t&&(this.phrases[i].sequence=e)},p5.Part.prototype.incrementStep=function(t){this.partStepthis.cutoff&&e>this.threshold&&0 1){\n\t\t\tthis.input = new Array(inputs);\n\t\t}\n\n\t\t/**\n\t\t * the output node(s)\n\t\t * @type {GainNode|Array}\n\t\t */\n\t\tif (this.isUndef(outputs) || outputs === 1){\n\t\t\tthis.output = this.context.createGain();\n\t\t} else if (outputs > 1){\n\t\t\tthis.output = new Array(inputs);\n\t\t}\n\t};\n\n\t/**\n\t * Set the parameters at once. Either pass in an\n\t * object mapping parameters to values, or to set a\n\t * single parameter, by passing in a string and value.\n\t * The last argument is an optional ramp time which \n\t * will ramp any signal values to their destination value\n\t * over the duration of the rampTime.\n\t * @param {Object|string} params\n\t * @param {number=} value\n\t * @param {Time=} rampTime\n\t * @returns {Tone} this\n\t * @example\n\t * //set values using an object\n\t * filter.set({\n\t * \t\"frequency\" : 300,\n\t * \t\"type\" : highpass\n\t * });\n\t * @example\n\t * filter.set(\"type\", \"highpass\");\n\t * @example\n\t * //ramp to the value 220 over 3 seconds. \n\t * oscillator.set({\n\t * \t\"frequency\" : 220\n\t * }, 3);\n\t */\n\tTone.prototype.set = function(params, value, rampTime){\n\t\tif (this.isObject(params)){\n\t\t\trampTime = value;\n\t\t} else if (this.isString(params)){\n\t\t\tvar tmpObj = {};\n\t\t\ttmpObj[params] = value;\n\t\t\tparams = tmpObj;\n\t\t}\n\n\t\tparamLoop:\n\t\tfor (var attr in params){\n\t\t\tvalue = params[attr];\n\t\t\tvar parent = this;\n\t\t\tif (attr.indexOf(\".\") !== -1){\n\t\t\t\tvar attrSplit = attr.split(\".\");\n\t\t\t\tfor (var i = 0; i < attrSplit.length - 1; i++){\n\t\t\t\t\tparent = parent[attrSplit[i]];\n\t\t\t\t\tif (parent instanceof Tone) {\n\t\t\t\t\t\tattrSplit.splice(0,i+1);\n\t\t\t\t\t\tvar innerParam = attrSplit.join(\".\");\n\t\t\t\t\t\tparent.set(innerParam, value);\n\t\t\t\t\t\tcontinue paramLoop;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tattr = attrSplit[attrSplit.length - 1];\n\t\t\t}\n\t\t\tvar param = parent[attr];\n\t\t\tif (this.isUndef(param)){\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tif ((Tone.Signal && param instanceof Tone.Signal) || \n\t\t\t\t\t(Tone.Param && param instanceof Tone.Param)){\n\t\t\t\tif (param.value !== value){\n\t\t\t\t\tif (this.isUndef(rampTime)){\n\t\t\t\t\t\tparam.value = value;\n\t\t\t\t\t} else {\n\t\t\t\t\t\tparam.rampTo(value, rampTime);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} else if (param instanceof AudioParam){\n\t\t\t\tif (param.value !== value){\n\t\t\t\t\tparam.value = value;\n\t\t\t\t}\t\t\t\t\n\t\t\t} else if (param instanceof Tone){\n\t\t\t\tparam.set(value);\n\t\t\t} else if (param !== value){\n\t\t\t\tparent[attr] = value;\n\t\t\t}\n\t\t}\n\t\treturn this;\n\t};\n\n\t/**\n\t * Get the object's attributes. Given no arguments get\n\t * will return all available object properties and their corresponding\n\t * values. Pass in a single attribute to retrieve or an array\n\t * of attributes. The attribute strings can also include a \".\"\n\t * to access deeper properties.\n\t * @example\n\t * osc.get();\n\t * //returns {\"type\" : \"sine\", \"frequency\" : 440, ...etc}\n\t * @example\n\t * osc.get(\"type\");\n\t * //returns { \"type\" : \"sine\"}\n\t * @example\n\t * //use dot notation to access deep properties\n\t * synth.get([\"envelope.attack\", \"envelope.release\"]);\n\t * //returns {\"envelope\" : {\"attack\" : 0.2, \"release\" : 0.4}}\n\t * @param {Array=|string|undefined} params the parameters to get, otherwise will return \n\t * \t\t\t\t\t all available.\n\t * @returns {Object}\n\t */\n\tTone.prototype.get = function(params){\n\t\tif (this.isUndef(params)){\n\t\t\tparams = this._collectDefaults(this.constructor);\n\t\t} else if (this.isString(params)){\n\t\t\tparams = [params];\n\t\t} \n\t\tvar ret = {};\n\t\tfor (var i = 0; i < params.length; i++){\n\t\t\tvar attr = params[i];\n\t\t\tvar parent = this;\n\t\t\tvar subRet = ret;\n\t\t\tif (attr.indexOf(\".\") !== -1){\n\t\t\t\tvar attrSplit = attr.split(\".\");\n\t\t\t\tfor (var j = 0; j < attrSplit.length - 1; j++){\n\t\t\t\t\tvar subAttr = attrSplit[j];\n\t\t\t\t\tsubRet[subAttr] = subRet[subAttr] || {};\n\t\t\t\t\tsubRet = subRet[subAttr];\n\t\t\t\t\tparent = parent[subAttr];\n\t\t\t\t}\n\t\t\t\tattr = attrSplit[attrSplit.length - 1];\n\t\t\t}\n\t\t\tvar param = parent[attr];\n\t\t\tif (this.isObject(params[attr])){\n\t\t\t\tsubRet[attr] = param.get();\n\t\t\t} else if (Tone.Signal && param instanceof Tone.Signal){\n\t\t\t\tsubRet[attr] = param.value;\n\t\t\t} else if (Tone.Param && param instanceof Tone.Param){\n\t\t\t\tsubRet[attr] = param.value;\n\t\t\t} else if (param instanceof AudioParam){\n\t\t\t\tsubRet[attr] = param.value;\n\t\t\t} else if (param instanceof Tone){\n\t\t\t\tsubRet[attr] = param.get();\n\t\t\t} else if (!this.isFunction(param) && !this.isUndef(param)){\n\t\t\t\tsubRet[attr] = param;\n\t\t\t} \n\t\t}\n\t\treturn ret;\n\t};\n\n\t/**\n\t * collect all of the default attributes in one\n\t * @private\n\t * @param {function} constr the constructor to find the defaults from\n\t * @return {Array} all of the attributes which belong to the class\n\t */\n\tTone.prototype._collectDefaults = function(constr){\n\t\tvar ret = [];\n\t\tif (!this.isUndef(constr.defaults)){\n\t\t\tret = Object.keys(constr.defaults);\n\t\t}\n\t\tif (!this.isUndef(constr._super)){\n\t\t\tvar superDefs = this._collectDefaults(constr._super);\n\t\t\t//filter out repeats\n\t\t\tfor (var i = 0; i < superDefs.length; i++){\n\t\t\t\tif (ret.indexOf(superDefs[i]) === -1){\n\t\t\t\t\tret.push(superDefs[i]);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\treturn ret;\n\t};\n\n\t/**\n\t * @returns {string} returns the name of the class as a string\n\t */\n\tTone.prototype.toString = function(){\n\t\tfor (var className in Tone){\n\t\t\tvar isLetter = className[0].match(/^[A-Z]$/);\n\t\t\tvar sameConstructor = Tone[className] === this.constructor;\n\t\t\tif (this.isFunction(Tone[className]) && isLetter && sameConstructor){\n\t\t\t\treturn className;\n\t\t\t}\n\t\t}\n\t\treturn \"Tone\";\n\t};\n\n\t///////////////////////////////////////////////////////////////////////////\n\t//\tCLASS VARS\n\t///////////////////////////////////////////////////////////////////////////\n\n\t/**\n\t * The number of inputs feeding into the AudioNode. \n\t * For source nodes, this will be 0.\n\t * @memberOf Tone#\n\t * @name numberOfInputs\n\t * @readOnly\n\t */\n\tObject.defineProperty(Tone.prototype, \"numberOfInputs\", {\n\t\tget : function(){\n\t\t\tif (this.input){\n\t\t\t\tif (this.isArray(this.input)){\n\t\t\t\t\treturn this.input.length;\n\t\t\t\t} else {\n\t\t\t\t\treturn 1;\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\treturn 0;\n\t\t\t}\n\t\t}\n\t});\n\n\t/**\n\t * The number of outputs coming out of the AudioNode. \n\t * For source nodes, this will be 0.\n\t * @memberOf Tone#\n\t * @name numberOfInputs\n\t * @readOnly\n\t */\n\tObject.defineProperty(Tone.prototype, \"numberOfOutputs\", {\n\t\tget : function(){\n\t\t\tif (this.output){\n\t\t\t\tif (this.isArray(this.output)){\n\t\t\t\t\treturn this.output.length;\n\t\t\t\t} else {\n\t\t\t\t\treturn 1;\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\treturn 0;\n\t\t\t}\n\t\t}\n\t});\n\t\n\t///////////////////////////////////////////////////////////////////////////\n\t//\tCONNECTIONS\n\t///////////////////////////////////////////////////////////////////////////\n\n\t/**\n\t * disconnect and dispose\n\t * @returns {Tone} this\n\t */\n\tTone.prototype.dispose = function(){\n\t\tif (!this.isUndef(this.input)){\n\t\t\tif (this.input instanceof AudioNode){\n\t\t\t\tthis.input.disconnect();\n\t\t\t} \n\t\t\tthis.input = null;\n\t\t}\n\t\tif (!this.isUndef(this.output)){\n\t\t\tif (this.output instanceof AudioNode){\n\t\t\t\tthis.output.disconnect();\n\t\t\t} \n\t\t\tthis.output = null;\n\t\t}\n\t\treturn this;\n\t};\n\n\t/**\n\t * connect the output of a ToneNode to an AudioParam, AudioNode, or ToneNode\n\t * @param {Tone | AudioParam | AudioNode} unit \n\t * @param {number} [outputNum=0] optionally which output to connect from\n\t * @param {number} [inputNum=0] optionally which input to connect to\n\t * @returns {Tone} this\n\t */\n\tTone.prototype.connect = function(unit, outputNum, inputNum){\n\t\tif (Array.isArray(this.output)){\n\t\t\toutputNum = this.defaultArg(outputNum, 0);\n\t\t\tthis.output[outputNum].connect(unit, 0, inputNum);\n\t\t} else {\n\t\t\tthis.output.connect(unit, outputNum, inputNum);\n\t\t}\n\t\treturn this;\n\t};\n\n\t/**\n\t * disconnect the output\n\t * @param {Number|AudioNode} output Either the output index to disconnect\n\t * if the output is an array, or the\n\t * node to disconnect from.\n\t * @returns {Tone} this\n\t */\n\tTone.prototype.disconnect = function(destination, outputNum, inputNum){\n\t\tif (this.isArray(this.output)){\n\t\t\tif (this.isNumber(destination)){\n\t\t\t\tthis.output[destination].disconnect();\n\t\t\t} else {\n\t\t\t\toutputNum = this.defaultArg(outputNum, 0);\n\t\t\t\tthis.output[outputNum].disconnect(destination, 0, inputNum);\n\t\t\t}\n\t\t} else {\n\t\t\tthis.output.disconnect.apply(this.output, arguments);\n\t\t}\n\t};\n\n\t/**\n\t * connect together all of the arguments in series\n\t * @param {...AudioParam|Tone|AudioNode} nodes\n\t * @returns {Tone} this\n\t */\n\tTone.prototype.connectSeries = function(){\n\t\tif (arguments.length > 1){\n\t\t\tvar currentUnit = arguments[0];\n\t\t\tfor (var i = 1; i < arguments.length; i++){\n\t\t\t\tvar toUnit = arguments[i];\n\t\t\t\tcurrentUnit.connect(toUnit);\n\t\t\t\tcurrentUnit = toUnit;\n\t\t\t}\n\t\t}\n\t\treturn this;\n\t};\n\n\t/**\n\t * Connect the output of this node to the rest of the nodes in series.\n\t * @example\n\t * //connect a node to an effect, panVol and then to the master output\n\t * node.chain(effect, panVol, Tone.Master);\n\t * @param {...AudioParam|Tone|AudioNode} nodes\n\t * @returns {Tone} this\n\t */\n\tTone.prototype.chain = function(){\n\t\tif (arguments.length > 0){\n\t\t\tvar currentUnit = this;\n\t\t\tfor (var i = 0; i < arguments.length; i++){\n\t\t\t\tvar toUnit = arguments[i];\n\t\t\t\tcurrentUnit.connect(toUnit);\n\t\t\t\tcurrentUnit = toUnit;\n\t\t\t}\n\t\t}\n\t\treturn this;\n\t};\n\n\t/**\n\t * connect the output of this node to the rest of the nodes in parallel.\n\t * @param {...AudioParam|Tone|AudioNode} nodes\n\t * @returns {Tone} this\n\t */\n\tTone.prototype.fan = function(){\n\t\tif (arguments.length > 0){\n\t\t\tfor (var i = 0; i < arguments.length; i++){\n\t\t\t\tthis.connect(arguments[i]);\n\t\t\t}\n\t\t}\n\t\treturn this;\n\t};\n\n\t//give native nodes chain and fan methods\n\tAudioNode.prototype.chain = Tone.prototype.chain;\n\tAudioNode.prototype.fan = Tone.prototype.fan;\n\n\t///////////////////////////////////////////////////////////////////////////\n\t//\tUTILITIES / HELPERS / MATHS\n\t///////////////////////////////////////////////////////////////////////////\n\n\t/**\n\t * If the `given` parameter is undefined, use the `fallback`. \n\t * If both `given` and `fallback` are object literals, it will\n\t * return a deep copy which includes all of the parameters from both \n\t * objects. If a parameter is undefined in given, it will return\n\t * the fallback property. \n\t *
\n\t * WARNING: if object is self referential, it will go into an an \n\t * infinite recursive loop.\n\t * \n\t * @param {*} given \n\t * @param {*} fallback \n\t * @return {*} \n\t */\n\tTone.prototype.defaultArg = function(given, fallback){\n\t\tif (this.isObject(given) && this.isObject(fallback)){\n\t\t\tvar ret = {};\n\t\t\t//make a deep copy of the given object\n\t\t\tfor (var givenProp in given) {\n\t\t\t\tret[givenProp] = this.defaultArg(fallback[givenProp], given[givenProp]);\n\t\t\t}\n\t\t\tfor (var fallbackProp in fallback) {\n\t\t\t\tret[fallbackProp] = this.defaultArg(given[fallbackProp], fallback[fallbackProp]);\n\t\t\t}\n\t\t\treturn ret;\n\t\t} else {\n\t\t\treturn this.isUndef(given) ? fallback : given;\n\t\t}\n\t};\n\n\t/**\n\t * returns the args as an options object with given arguments\n\t * mapped to the names provided. \n\t *\n\t * if the args given is an array containing only one object, it is assumed\n\t * that that's already the options object and will just return it. \n\t * \n\t * @param {Array} values the 'arguments' object of the function\n\t * @param {Array} keys the names of the arguments as they\n\t * should appear in the options object\n\t * @param {Object=} defaults optional defaults to mixin to the returned \n\t * options object \n\t * @return {Object} the options object with the names mapped to the arguments\n\t */\n\tTone.prototype.optionsObject = function(values, keys, defaults){\n\t\tvar options = {};\n\t\tif (values.length === 1 && this.isObject(values[0])){\n\t\t\toptions = values[0];\n\t\t} else {\n\t\t\tfor (var i = 0; i < keys.length; i++){\n\t\t\t\toptions[keys[i]] = values[i];\n\t\t\t}\n\t\t}\n\t\tif (!this.isUndef(defaults)){\n\t\t\treturn this.defaultArg(options, defaults);\n\t\t} else {\n\t\t\treturn options;\n\t\t}\n\t};\n\n\t///////////////////////////////////////////////////////////////////////////\n\t// TYPE CHECKING\n\t///////////////////////////////////////////////////////////////////////////\n\n\t/**\n\t * test if the arg is undefined\n\t * @param {*} arg the argument to test\n\t * @returns {boolean} true if the arg is undefined\n\t * @function\n\t */\n\tTone.prototype.isUndef = function(val){\n\t\treturn typeof val === \"undefined\";\n\t};\n\n\t/**\n\t * test if the arg is a function\n\t * @param {*} arg the argument to test\n\t * @returns {boolean} true if the arg is a function\n\t * @function\n\t */\n\tTone.prototype.isFunction = function(val){\n\t\treturn typeof val === \"function\";\n\t};\n\n\t/**\n\t * Test if the argument is a number.\n\t * @param {*} arg the argument to test\n\t * @returns {boolean} true if the arg is a number\n\t */\n\tTone.prototype.isNumber = function(arg){\n\t\treturn (typeof arg === \"number\");\n\t};\n\n\t/**\n\t * Test if the given argument is an object literal (i.e. `{}`);\n\t * @param {*} arg the argument to test\n\t * @returns {boolean} true if the arg is an object literal.\n\t */\n\tTone.prototype.isObject = function(arg){\n\t\treturn (Object.prototype.toString.call(arg) === \"[object Object]\" && arg.constructor === Object);\n\t};\n\n\t/**\n\t * Test if the argument is a boolean.\n\t * @param {*} arg the argument to test\n\t * @returns {boolean} true if the arg is a boolean\n\t */\n\tTone.prototype.isBoolean = function(arg){\n\t\treturn (typeof arg === \"boolean\");\n\t};\n\n\t/**\n\t * Test if the argument is an Array\n\t * @param {*} arg the argument to test\n\t * @returns {boolean} true if the arg is an array\n\t */\n\tTone.prototype.isArray = function(arg){\n\t\treturn (Array.isArray(arg));\n\t};\n\n\t/**\n\t * Test if the argument is a string.\n\t * @param {*} arg the argument to test\n\t * @returns {boolean} true if the arg is a string\n\t */\n\tTone.prototype.isString = function(arg){\n\t\treturn (typeof arg === \"string\");\n\t};\n\n \t/**\n\t * An empty function.\n\t * @static\n\t */\n\tTone.noOp = function(){};\n\n\t/**\n\t * Make the property not writable. Internal use only. \n\t * @private\n\t * @param {string} property the property to make not writable\n\t */\n\tTone.prototype._readOnly = function(property){\n\t\tif (Array.isArray(property)){\n\t\t\tfor (var i = 0; i < property.length; i++){\n\t\t\t\tthis._readOnly(property[i]);\n\t\t\t}\n\t\t} else {\n\t\t\tObject.defineProperty(this, property, { \n\t\t\t\twritable: false,\n\t\t\t\tenumerable : true,\n\t\t\t});\n\t\t}\n\t};\n\n\t/**\n\t * Make an attribute writeable. Interal use only. \n\t * @private\n\t * @param {string} property the property to make writable\n\t */\n\tTone.prototype._writable = function(property){\n\t\tif (Array.isArray(property)){\n\t\t\tfor (var i = 0; i < property.length; i++){\n\t\t\t\tthis._writable(property[i]);\n\t\t\t}\n\t\t} else {\n\t\t\tObject.defineProperty(this, property, { \n\t\t\t\twritable: true,\n\t\t\t});\n\t\t}\n\t};\n\n\t/**\n\t * Possible play states. \n\t * @enum {string}\n\t */\n\tTone.State = {\n\t\tStarted : \"started\",\n\t\tStopped : \"stopped\",\n\t\tPaused : \"paused\",\n \t};\n\n\t///////////////////////////////////////////////////////////////////////////\n\t// CONVERSIONS\n\t///////////////////////////////////////////////////////////////////////////\n\n\t/**\n\t * Equal power gain scale. Good for cross-fading.\n\t * @param {NormalRange} percent (0-1)\n\t * @return {Number} output gain (0-1)\n\t */\n\tTone.prototype.equalPowerScale = function(percent){\n\t\tvar piFactor = 0.5 * Math.PI;\n\t\treturn Math.sin(percent * piFactor);\n\t};\n\n\t/**\n\t * Convert decibels into gain.\n\t * @param {Decibels} db\n\t * @return {Number} \n\t */\n\tTone.prototype.dbToGain = function(db) {\n\t\treturn Math.pow(2, db / 6);\n\t};\n\n\t/**\n\t * Convert gain to decibels.\n\t * @param {Number} gain (0-1)\n\t * @return {Decibels} \n\t */\n\tTone.prototype.gainToDb = function(gain) {\n\t\treturn 20 * (Math.log(gain) / Math.LN10);\n\t};\n\n\t/**\n\t * Convert an interval (in semitones) to a frequency ratio.\n\t * @param {Interval} interval the number of semitones above the base note\n\t * @return {number} the frequency ratio\n\t * @example\n\t * tone.intervalToFrequencyRatio(0); // 1\n\t * tone.intervalToFrequencyRatio(12); // 2\n\t * tone.intervalToFrequencyRatio(-12); // 0.5\n\t */\n\tTone.prototype.intervalToFrequencyRatio = function(interval){\n\t\treturn Math.pow(2,(interval/12));\n\t};\n\n\t///////////////////////////////////////////////////////////////////////////\n\t//\tTIMING\n\t///////////////////////////////////////////////////////////////////////////\n\n\t/**\n\t * Return the current time of the AudioContext clock.\n\t * @return {Number} the currentTime from the AudioContext\n\t */\n\tTone.prototype.now = function(){\n\t\treturn Tone.context.now();\n\t};\n\n\t/**\n\t * Return the current time of the AudioContext clock.\n\t * @return {Number} the currentTime from the AudioContext\n\t * @static\n\t */\n\tTone.now = function(){\n\t\treturn Tone.context.now();\n\t};\n\n\t///////////////////////////////////////////////////////////////////////////\n\t//\tINHERITANCE\n\t///////////////////////////////////////////////////////////////////////////\n\n\t/**\n\t * have a child inherit all of Tone's (or a parent's) prototype\n\t * to inherit the parent's properties, make sure to call \n\t * Parent.call(this) in the child's constructor\n\t *\n\t * based on closure library's inherit function\n\t *\n\t * @static\n\t * @param {function} \tchild \n\t * @param {function=} parent (optional) parent to inherit from\n\t * if no parent is supplied, the child\n\t * will inherit from Tone\n\t */\n\tTone.extend = function(child, parent){\n\t\tif (Tone.prototype.isUndef(parent)){\n\t\t\tparent = Tone;\n\t\t}\n\t\tfunction TempConstructor(){}\n\t\tTempConstructor.prototype = parent.prototype;\n\t\tchild.prototype = new TempConstructor();\n\t\t/** @override */\n\t\tchild.prototype.constructor = child;\n\t\tchild._super = parent;\n\t};\n\n\t///////////////////////////////////////////////////////////////////////////\n\t//\tCONTEXT\n\t///////////////////////////////////////////////////////////////////////////\n\n\t/**\n\t * The private audio context shared by all Tone Nodes. \n\t * @private\n\t * @type {Tone.Context|undefined}\n\t */\n\tvar audioContext;\n\n\t/**\n\t * A static pointer to the audio context accessible as Tone.context. \n\t * @type {Tone.Context}\n\t * @name context\n\t * @memberOf Tone\n\t */\n\tObject.defineProperty(Tone, \"context\", {\n\t\tget : function(){\n\t\t\treturn audioContext;\n\t\t},\n\t\tset : function(context){\n\t\t\tif (Tone.Context && context instanceof Tone.Context){\n\t\t\t\taudioContext = context;\n\t\t\t} else {\n\t\t\t\taudioContext = new Tone.Context(context);\n\t\t\t}\n\t\t\t//initialize the new audio context\n\t\t\tif (Tone.Context){\n\t\t\t\tTone.Context.emit(\"init\", audioContext);\n\t\t\t}\n\t\t}\n\t});\n\n\t/**\n\t * The AudioContext\n\t * @type {Tone.Context}\n\t * @name context\n\t * @memberOf Tone#\n\t * @readOnly\n\t */\n\tObject.defineProperty(Tone.prototype, \"context\", {\n\t\tget : function(){\n\t\t\treturn Tone.context;\n\t\t}\n\t});\n\n\t/**\n\t * Tone automatically creates a context on init, but if you are working\n\t * with other libraries which also create an AudioContext, it can be\n\t * useful to set your own. If you are going to set your own context, \n\t * be sure to do it at the start of your code, before creating any objects.\n\t * @static\n\t * @param {AudioContext} ctx The new audio context to set\n\t */\n\tTone.setContext = function(ctx){\n\t\tTone.context = ctx;\n\t};\n\n\t/**\n\t * The number of seconds of 1 processing block (128 samples)\n\t * @type {Number}\n\t * @name blockTime\n\t * @memberOf Tone#\n\t * @readOnly\n\t */\n\tObject.defineProperty(Tone.prototype, \"blockTime\", {\n\t\tget : function(){\n\t\t\treturn 128 / this.context.sampleRate;\n\t\t}\n\t});\n\n\t/**\n\t * The duration in seconds of one sample.\n\t * @type {Number}\n\t * @name sampleTime\n\t * @memberOf Tone#\n\t * @readOnly\n\t */\n\tObject.defineProperty(Tone.prototype, \"sampleTime\", {\n\t\tget : function(){\n\t\t\treturn 1 / this.context.sampleRate;\n\t\t}\n\t});\n\n\t/**\n\t * Whether or not all the technologies that Tone.js relies on are supported by the current browser. \n\t * @type {Boolean}\n\t * @name supported\n\t * @memberOf Tone\n\t * @readOnly\n\t */\n\tObject.defineProperty(Tone, \"supported\", {\n\t\tget : function(){\n\t\t\tvar hasAudioContext = window.hasOwnProperty(\"AudioContext\") || window.hasOwnProperty(\"webkitAudioContext\");\n\t\t\tvar hasPromises = window.hasOwnProperty(\"Promise\");\n\t\t\tvar hasWorkers = window.hasOwnProperty(\"Worker\");\n\t\t\treturn hasAudioContext && hasPromises && hasWorkers;\n\t\t}\n\t});\n\n\tTone.version = \"r10\";\n\n\t// allow optional silencing of this log\n\tif (!window.TONE_SILENCE_VERSION_LOGGING) {\n\t\tconsole.log(\"%c * Tone.js \" + Tone.version + \" * \", \"background: #000; color: #fff\");\n\t}\n\n\treturn Tone;\n});\n","'use strict';\r\n\r\n\r\ndefine(['audiocontext'], function (audiocontext) {\r\n /**\r\n * Master contains AudioContext and the master sound output.\r\n * @for p5\r\n */\r\n var Master = function() {\r\n this.input = audiocontext.createGain();\r\n this.output = audiocontext.createGain();\r\n\r\n //put a hard limiter on the output\r\n this.limiter = audiocontext.createDynamicsCompressor();\r\n this.limiter.threshold.value = -3;\r\n this.limiter.ratio.value = 20;\r\n this.limiter.knee.value = 1;\r\n\r\n this.audiocontext = audiocontext;\r\n\r\n this.output.disconnect();\r\n\r\n // connect input to limiter\r\n this.input.connect(this.limiter);\r\n\r\n // connect limiter to output\r\n this.limiter.connect(this.output);\r\n\r\n // meter is just for global Amplitude / FFT analysis\r\n this.meter = audiocontext.createGain();\r\n this.fftMeter = audiocontext.createGain();\r\n this.output.connect(this.meter);\r\n this.output.connect(this.fftMeter);\r\n\r\n // connect output to destination\r\n this.output.connect(this.audiocontext.destination);\r\n\r\n // an array of all sounds in the sketch\r\n this.soundArray = [];\r\n // an array of all musical parts in the sketch\r\n this.parts = [];\r\n\r\n // file extensions to search for\r\n this.extensions = [];\r\n };\r\n\r\n // create a single instance of the p5Sound / master output for use within this sketch\r\n var p5sound = new Master();\r\n\r\n /**\r\n * Returns a number representing the master amplitude (volume) for sound\r\n * in this sketch.\r\n *\r\n * @method getMasterVolume\r\n * @return {Number} Master amplitude (volume) for sound in this sketch.\r\n * Should be between 0.0 (silence) and 1.0.\r\n */\r\n p5.prototype.getMasterVolume = function() {\r\n return p5sound.output.gain.value;\r\n };\r\n\r\n /**\r\n *
Scale the output of all sound in this sketch
\r\n * Scaled between 0.0 (silence) and 1.0 (full volume).\r\n * 1.0 is the maximum amplitude of a digital sound, so multiplying\r\n * by greater than 1.0 may cause digital distortion. To\r\n * fade, provide a rampTime parameter. For more\r\n * complex fades, see the Envelope class.\r\n *\r\n * Alternately, you can pass in a signal source such as an\r\n * oscillator to modulate the amplitude with an audio signal.\r\n *\r\n *
How This Works: When you load the p5.sound module, it\r\n * creates a single instance of p5sound. All sound objects in this\r\n * module output to p5sound before reaching your computer's output.\r\n * So if you change the amplitude of p5sound, it impacts all of the\r\n * sound in this module.
\r\n *\r\n *
If no value is provided, returns a Web Audio API Gain Node
\r\n *\r\n * @method masterVolume\r\n * @param {Number|Object} volume Volume (amplitude) between 0.0\r\n * and 1.0 or modulating signal/oscillator\r\n * @param {Number} [rampTime] Fade for t seconds\r\n * @param {Number} [timeFromNow] Schedule this event to happen at\r\n * t seconds in the future\r\n */\r\n p5.prototype.masterVolume = function(vol, rampTime, tFromNow) {\r\n if (typeof vol === 'number') {\r\n var rampTime = rampTime || 0;\r\n var tFromNow = tFromNow || 0;\r\n var now = p5sound.audiocontext.currentTime;\r\n var currentVol = p5sound.output.gain.value;\r\n p5sound.output.gain.cancelScheduledValues(now + tFromNow);\r\n p5sound.output.gain.linearRampToValueAtTime(currentVol, now + tFromNow);\r\n p5sound.output.gain.linearRampToValueAtTime(vol, now + tFromNow + rampTime);\r\n }\r\n else if (vol) {\r\n vol.connect(p5sound.output.gain);\r\n } else {\r\n // return the Gain Node\r\n return p5sound.output.gain;\r\n }\r\n };\r\n\r\n /**\r\n * `p5.soundOut` is the p5.sound master output. It sends output to\r\n * the destination of this window's web audio context. It contains\r\n * Web Audio API nodes including a dyanmicsCompressor (.limiter),\r\n * and Gain Nodes for .input and .output.\r\n *\r\n * @property {Object} soundOut\r\n */\r\n p5.prototype.soundOut = p5.soundOut = p5sound;\r\n\r\n /**\r\n * a silent connection to the DesinationNode\r\n * which will ensure that anything connected to it\r\n * will not be garbage collected\r\n *\r\n * @private\r\n */\r\n p5.soundOut._silentNode = p5sound.audiocontext.createGain();\r\n p5.soundOut._silentNode.gain.value = 0;\r\n p5.soundOut._silentNode.connect(p5sound.audiocontext.destination);\r\n\r\n\r\n return p5sound;\r\n});\r\n","define([\"Tone/core/Tone\", \"Tone/signal/WaveShaper\", \"Tone/type/Type\", \"Tone/core/Param\", \"Tone/core/Gain\"], function(Tone){\n\n\t\"use strict\";\n\n\t/**\n\t * @class A signal is an audio-rate value. Tone.Signal is a core component of the library.\n\t * Unlike a number, Signals can be scheduled with sample-level accuracy. Tone.Signal\n\t * has all of the methods available to native Web Audio \n\t * [AudioParam](http://webaudio.github.io/web-audio-api/#the-audioparam-interface)\n\t * as well as additional conveniences. Read more about working with signals \n\t * [here](https://github.com/Tonejs/Tone.js/wiki/Signals).\n\t *\n\t * @constructor\n\t * @extends {Tone.Param}\n\t * @param {Number|AudioParam} [value] Initial value of the signal. If an AudioParam\n\t * is passed in, that parameter will be wrapped\n\t * and controlled by the Signal. \n\t * @param {string} [units=Number] unit The units the signal is in. \n\t * @example\n\t * var signal = new Tone.Signal(10);\n\t */\n\tTone.Signal = function(){\n\n\t\tvar options = this.optionsObject(arguments, [\"value\", \"units\"], Tone.Signal.defaults);\n\n\t\t/**\n\t\t * The node where the constant signal value is scaled.\n\t\t * @type {GainNode}\n\t\t * @private\n\t\t */\n\t\tthis.output = this._gain = this.context.createGain();\n\n\t\toptions.param = this._gain.gain;\n\t\tTone.Param.call(this, options);\n\n\t\t/**\n\t\t * The node where the value is set.\n\t\t * @type {Tone.Param}\n\t\t * @private\n\t\t */\n\t\tthis.input = this._param = this._gain.gain;\n\n\t\t//connect the const output to the node output\n\t\tthis.context.getConstant(1).chain(this._gain);\n\t};\n\n\tTone.extend(Tone.Signal, Tone.Param);\n\n\t/**\n\t * The default values\n\t * @type {Object}\n\t * @static\n\t * @const\n\t */\n\tTone.Signal.defaults = {\n\t\t\"value\" : 0,\n\t\t\"units\" : Tone.Type.Default,\n\t\t\"convert\" : true,\n\t};\n\n\t/**\n\t * When signals connect to other signals or AudioParams, \n\t * they take over the output value of that signal or AudioParam. \n\t * For all other nodes, the behavior is the same as a default connect. \n\t *\n\t * @override\n\t * @param {AudioParam|AudioNode|Tone.Signal|Tone} node \n\t * @param {number} [outputNumber=0] The output number to connect from.\n\t * @param {number} [inputNumber=0] The input number to connect to.\n\t * @returns {Tone.SignalBase} this\n\t * @method\n\t */\n\tTone.Signal.prototype.connect = Tone.SignalBase.prototype.connect;\n\n\t/**\n\t * dispose and disconnect\n\t * @returns {Tone.Signal} this\n\t */\n\tTone.Signal.prototype.dispose = function(){\n\t\tTone.Param.prototype.dispose.call(this);\n\t\tthis._param = null;\n\t\tthis._gain.disconnect();\n\t\tthis._gain = null;\n\t\treturn this;\n\t};\n\n\treturn Tone.Signal;\n});","define([\"Tone/core/Tone\", \"Tone/signal/Signal\", \"Tone/core/Gain\"], function(Tone){\n\n\t\"use strict\";\n\n\t/**\n\t * @class Multiply two incoming signals. Or, if a number is given in the constructor, \n\t * multiplies the incoming signal by that value. \n\t *\n\t * @constructor\n\t * @extends {Tone.Signal}\n\t * @param {number=} value Constant value to multiple. If no value is provided,\n\t * it will return the product of the first and second inputs\n\t * @example\n\t * var mult = new Tone.Multiply();\n\t * var sigA = new Tone.Signal(3);\n\t * var sigB = new Tone.Signal(4);\n\t * sigA.connect(mult, 0, 0);\n\t * sigB.connect(mult, 0, 1);\n\t * //output of mult is 12.\n\t * @example\n\t * var mult = new Tone.Multiply(10);\n\t * var sig = new Tone.Signal(2).connect(mult);\n\t * //the output of mult is 20. \n\t */\n\tTone.Multiply = function(value){\n\n\t\tthis.createInsOuts(2, 0);\n\n\t\t/**\n\t\t * the input node is the same as the output node\n\t\t * it is also the GainNode which handles the scaling of incoming signal\n\t\t * \n\t\t * @type {GainNode}\n\t\t * @private\n\t\t */\n\t\tthis._mult = this.input[0] = this.output = new Tone.Gain();\n\n\t\t/**\n\t\t * the scaling parameter\n\t\t * @type {AudioParam}\n\t\t * @private\n\t\t */\n\t\tthis._param = this.input[1] = this.output.gain;\n\t\t\n\t\tthis._param.value = this.defaultArg(value, 0);\n\t};\n\n\tTone.extend(Tone.Multiply, Tone.Signal);\n\n\t/**\n\t * clean up\n\t * @returns {Tone.Multiply} this\n\t */\n\tTone.Multiply.prototype.dispose = function(){\n\t\tTone.prototype.dispose.call(this);\n\t\tthis._mult.dispose();\n\t\tthis._mult = null;\n\t\tthis._param = null;\n\t\treturn this;\n\t}; \n\n\treturn Tone.Multiply;\n});\n","'use strict';\r\ndefine(function (require) {\r\n\r\n var p5sound = require('master');\r\n var CrossFade = require('Tone/component/CrossFade');\r\n\r\n /**\r\n * Effect is a base class for audio effects in p5. \r\n * This module handles the nodes and methods that are\r\n * common and useful for current and future effects.\r\n *\r\n *\r\n * This class is extended by p5.Distortion,\r\n * p5.Compressor,\r\n * p5.Delay,\r\n * p5.Filter,\r\n * p5.Reverb.\r\n *\r\n * @class p5.Effect\r\n * @constructor\r\n *\r\n * @param {Object} [ac] Reference to the audio context of the p5 object\r\n * @param {AudioNode} [input] Gain Node effect wrapper\r\n * @param {AudioNode} [output] Gain Node effect wrapper\r\n * @param {Object} [_drywet] Tone.JS CrossFade node (defaults to value: 1)\r\n * @param {AudioNode} [wet] Effects that extend this class should connect\r\n * to the wet signal to this gain node, so that dry and wet\r\n * signals are mixed properly.\r\n */\r\n p5.Effect = function() {\r\n this.ac = p5sound.audiocontext;\r\n\r\n this.input = this.ac.createGain();\r\n this.output = this.ac.createGain();\r\n\r\n /**\r\n *\tThe p5.Effect class is built\r\n * \tusing Tone.js CrossFade\r\n * \t@private\r\n */\r\n\r\n this._drywet = new CrossFade(1);\r\n\r\n /**\r\n *\tIn classes that extend\r\n *\tp5.Effect, connect effect nodes\r\n *\tto the wet parameter\r\n */\r\n this.wet = this.ac.createGain();\r\n\r\n this.input.connect(this._drywet.a);\r\n this.wet.connect(this._drywet.b);\r\n this._drywet.connect(this.output);\r\n\r\n this.connect();\r\n\r\n //Add to the soundArray\r\n p5sound.soundArray.push(this);\r\n };\r\n\r\n /**\r\n * Set the output volume of the filter.\r\n *\r\n * @method amp\r\n * @for p5.Effect\r\n * @param {Number} [vol] amplitude between 0 and 1.0\r\n * @param {Number} [rampTime] create a fade that lasts until rampTime\r\n * @param {Number} [tFromNow] schedule this event to happen in tFromNow seconds\r\n */\r\n p5.Effect.prototype.amp = function(vol, rampTime, tFromNow){\r\n var rampTime = rampTime || 0;\r\n var tFromNow = tFromNow || 0;\r\n var now = p5sound.audiocontext.currentTime;\r\n var currentVol = this.output.gain.value;\r\n this.output.gain.cancelScheduledValues(now);\r\n this.output.gain.linearRampToValueAtTime(currentVol, now + tFromNow + .001);\r\n this.output.gain.linearRampToValueAtTime(vol, now + tFromNow + rampTime + .001);\r\n };\r\n\r\n /**\r\n * Link effects together in a chain\r\n * Example usage: filter.chain(reverb, delay, panner);\r\n * May be used with an open-ended number of arguments\r\n *\r\n * @method chain\r\n * @for p5.Effect\r\n * @param {Object} [arguments] Chain together multiple sound objects\r\n */\r\n p5.Effect.prototype.chain = function(){\r\n if (arguments.length>0){\r\n this.connect(arguments[0]);\r\n for(var i=1;i\r\n * var notes = [60, 64, 67, 72];\r\n * var i = 0;\r\n *\r\n * function setup() {\r\n * osc = new p5.Oscillator('Triangle');\r\n * osc.start();\r\n * frameRate(1);\r\n * }\r\n *\r\n * function draw() {\r\n * var freq = midiToFreq(notes[i]);\r\n * osc.freq(freq);\r\n * i++;\r\n * if (i >= notes.length){\r\n * i = 0;\r\n * }\r\n * }\r\n * \r\n */\r\n var midiToFreq = p5.prototype.midiToFreq = function(m) {\r\n return 440 * Math.pow(2, (m-69)/12.0);\r\n };\r\n\r\n // This method converts ANSI notes specified as a string \"C4\", \"Eb3\" to a frequency\r\n var noteToFreq = function(note) {\r\n if (typeof note !== 'string') {\r\n return note;\r\n }\r\n var wholeNotes = {A:21, B:23, C:24, D:26, E:28, F:29, G:31};\r\n var value = wholeNotes[ note[0].toUpperCase() ];\r\n var octave = ~~note.slice(-1);\r\n value += 12 * (octave -1);\r\n\r\n switch(note[1]) {\r\n case '#':\r\n value += 1;\r\n break;\r\n case 'b':\r\n value -= 1;\r\n break;\r\n default:\r\n break;\r\n }\r\n return midiToFreq(value);\r\n };\r\n\r\n /**\r\n * List the SoundFile formats that you will include. LoadSound\r\n * will search your directory for these extensions, and will pick\r\n * a format that is compatable with the client's web browser.\r\n * Here is a free online file\r\n * converter.\r\n *\r\n * @method soundFormats\r\n * @param {String} [...formats] i.e. 'mp3', 'wav', 'ogg'\r\n * @example\r\n *
\r\n * function preload() {\r\n * // set the global sound formats\r\n * soundFormats('mp3', 'ogg');\r\n *\r\n * // load either beatbox.mp3, or .ogg, depending on browser\r\n * mySound = loadSound('assets/beatbox.mp3');\r\n * }\r\n *\r\n * function setup() {\r\n * mySound.play();\r\n * }\r\n *
\r\n */\r\n p5.prototype.soundFormats = function() {\r\n // reset extensions array\r\n p5sound.extensions = [];\r\n // add extensions\r\n for (var i = 0; i < arguments.length; i++) {\r\n arguments[i] = arguments[i].toLowerCase();\r\n if (['mp3','wav','ogg', 'm4a', 'aac'].indexOf(arguments[i]) > -1) {\r\n p5sound.extensions.push(arguments[i]);\r\n } else {\r\n throw arguments[i] + ' is not a valid sound format!';\r\n }\r\n }\r\n };\r\n\r\n p5.prototype.disposeSound = function() {\r\n for (var i = 0; i < p5sound.soundArray.length; i++) {\r\n p5sound.soundArray[i].dispose();\r\n }\r\n };\r\n\r\n // register removeSound to dispose of p5sound SoundFiles, Convolvers,\r\n // Oscillators etc when sketch ends\r\n p5.prototype.registerMethod('remove', p5.prototype.disposeSound);\r\n\r\n p5.prototype._checkFileFormats = function(paths) {\r\n var path;\r\n // if path is a single string, check to see if extension is provided\r\n if (typeof paths === 'string') {\r\n path = paths;\r\n // see if extension is provided\r\n var extTest = path.split('.').pop();\r\n // if an extension is provided...\r\n if (['mp3','wav','ogg', 'm4a', 'aac'].indexOf(extTest) > -1) {\r\n if (p5.prototype.isFileSupported(extTest)) {\r\n path = path;\r\n }\r\n else {\r\n var pathSplit = path.split('.');\r\n var pathCore = pathSplit[pathSplit.length - 1];\r\n for (var i = 0; i 1) {\r\n rightChannel = audioBuffer.getChannelData(1);\r\n } else {\r\n rightChannel = leftChannel;\r\n }\r\n\r\n var interleaved = interleave(leftChannel, rightChannel);\r\n\r\n // create the buffer and view to create the .WAV file\r\n var buffer = new window.ArrayBuffer(44 + interleaved.length * 2);\r\n var view = new window.DataView(buffer);\r\n\r\n // write the WAV container,\r\n // check spec at: https://web.archive.org/web/20171215131933/http://tiny.systems/software/soundProgrammer/WavFormatDocs.pdf\r\n\r\n // RIFF chunk descriptor\r\n writeUTFBytes(view, 0, 'RIFF');\r\n view.setUint32(4, 36 + interleaved.length * 2, true);\r\n writeUTFBytes(view, 8, 'WAVE');\r\n // FMT sub-chunk\r\n writeUTFBytes(view, 12, 'fmt ');\r\n view.setUint32(16, 16, true);\r\n view.setUint16(20, 1, true);\r\n // stereo (2 channels)\r\n view.setUint16(22, 2, true);\r\n view.setUint32(24, p5sound.audiocontext.sampleRate, true);\r\n view.setUint32(28, p5sound.audiocontext.sampleRate * 4, true);\r\n view.setUint16(32, 4, true);\r\n view.setUint16(34, 16, true);\r\n // data sub-chunk\r\n writeUTFBytes(view, 36, 'data');\r\n view.setUint32(40, interleaved.length * 2, true);\r\n\r\n // write the PCM samples\r\n var lng = interleaved.length;\r\n var index = 44;\r\n var volume = 1;\r\n for (var i = 0; i < lng; i++) {\r\n view.setInt16(index, interleaved[i] * (0x7FFF * volume), true);\r\n index += 2;\r\n }\r\n\r\n return view;\r\n }\r\n\r\n // helper methods to save waves\r\n function interleave(leftChannel, rightChannel) {\r\n var length = leftChannel.length + rightChannel.length;\r\n var result = new Float32Array(length);\r\n\r\n var inputIndex = 0;\r\n\r\n for (var index = 0; index < length;) {\r\n result[index++] = leftChannel[inputIndex];\r\n result[index++] = rightChannel[inputIndex];\r\n inputIndex++;\r\n }\r\n return result;\r\n }\r\n\r\n function writeUTFBytes(view, offset, string) {\r\n var lng = string.length;\r\n for (var i = 0; i < lng; i++) {\r\n view.setUint8(offset + i, string.charCodeAt(i));\r\n }\r\n }\r\n\r\n return {\r\n convertToWav: convertToWav,\r\n midiToFreq: midiToFreq,\r\n noteToFreq: noteToFreq\r\n };\r\n\r\n});\r\n","define([\"Tone/core/Tone\", \"Tone/signal/Signal\", \"Tone/core/Gain\"], function(Tone){\n\n\t\"use strict\";\n\n\t/**\n\t * @class Add a signal and a number or two signals. When no value is\n\t * passed into the constructor, Tone.Add will sum input[0]\n\t * and input[1]. If a value is passed into the constructor, \n\t * the it will be added to the input.\n\t * \n\t * @constructor\n\t * @extends {Tone.Signal}\n\t * @param {number=} value If no value is provided, Tone.Add will sum the first\n\t * and second inputs. \n\t * @example\n\t * var signal = new Tone.Signal(2);\n\t * var add = new Tone.Add(2);\n\t * signal.connect(add);\n\t * //the output of add equals 4\n\t * @example\n\t * //if constructed with no arguments\n\t * //it will add the first and second inputs\n\t * var add = new Tone.Add();\n\t * var sig0 = new Tone.Signal(3).connect(add, 0, 0);\n\t * var sig1 = new Tone.Signal(4).connect(add, 0, 1);\n\t * //the output of add equals 7. \n\t */\n\tTone.Add = function(value){\n\n\t\tthis.createInsOuts(2, 0);\n\n\t\t/**\n\t\t * the summing node\n\t\t * @type {GainNode}\n\t\t * @private\n\t\t */\n\t\tthis._sum = this.input[0] = this.input[1] = this.output = new Tone.Gain();\n\n\t\t/**\n\t\t * @private\n\t\t * @type {Tone.Signal}\n\t\t */\n\t\tthis._param = this.input[1] = new Tone.Signal(value);\n\n\t\tthis._param.connect(this._sum);\n\t};\n\n\tTone.extend(Tone.Add, Tone.Signal);\n\t\n\t/**\n\t * Clean up.\n\t * @returns {Tone.Add} this\n\t */\n\tTone.Add.prototype.dispose = function(){\n\t\tTone.prototype.dispose.call(this);\n\t\tthis._sum.dispose();\n\t\tthis._sum = null;\n\t\tthis._param.dispose();\n\t\tthis._param = null;\n\t\treturn this;\n\t}; \n\n\treturn Tone.Add;\n});","define([\"Tone/core/Tone\", \"Tone/type/Time\", \"Tone/type/Frequency\", \"Tone/type/TransportTime\", \"Tone/core/Context\"],\nfunction (Tone) {\t\n\n\t///////////////////////////////////////////////////////////////////////////\n\t//\tTYPES\n\t///////////////////////////////////////////////////////////////////////////\n\n\t/**\n\t * Units which a value can take on.\n\t * @enum {String}\n\t */\n\tTone.Type = {\n\t\t/** \n\t\t * Default units\n\t\t * @typedef {Default}\n\t\t */\n\t\tDefault : \"number\",\n\t\t/**\n\t\t * Time can be described in a number of ways. Read more [Time](https://github.com/Tonejs/Tone.js/wiki/Time).\n\t\t *\n\t\t *
\n\t\t *
Numbers, which will be taken literally as the time (in seconds).
\n\t\t *
Notation, (\"4n\", \"8t\") describes time in BPM and time signature relative values.
\n\t\t *
TransportTime, (\"4:3:2\") will also provide tempo and time signature relative times \n\t\t * in the form BARS:QUARTERS:SIXTEENTHS.
\n\t\t *
Frequency, (\"8hz\") is converted to the length of the cycle in seconds.
\n\t\t *
Now-Relative, (\"+1\") prefix any of the above with \"+\" and it will be interpreted as \n\t\t * \"the current time plus whatever expression follows\".
\n\t\t *
Expressions, (\"3:0 + 2 - (1m / 7)\") any of the above can also be combined \n\t\t * into a mathematical expression which will be evaluated to compute the desired time.
\n\t\t *
No Argument, for methods which accept time, no argument will be interpreted as \n\t\t * \"now\" (i.e. the currentTime).
\n\t\t *
\n\t\t * \n\t\t * @typedef {Time}\n\t\t */\n\t\tTime : \"time\",\n\t\t/**\n\t\t * Frequency can be described similar to time, except ultimately the\n\t\t * values are converted to frequency instead of seconds. A number\n\t\t * is taken literally as the value in hertz. Additionally any of the \n\t\t * Time encodings can be used. Note names in the form\n\t\t * of NOTE OCTAVE (i.e. C4) are also accepted and converted to their\n\t\t * frequency value. \n\t\t * @typedef {Frequency}\n\t\t */\n\t\tFrequency : \"frequency\",\n\t\t/**\n\t\t * TransportTime describes a position along the Transport's timeline. It is\n\t\t * similar to Time in that it uses all the same encodings, but TransportTime specifically\n\t\t * pertains to the Transport's timeline, which is startable, stoppable, loopable, and seekable. \n\t\t * [Read more](https://github.com/Tonejs/Tone.js/wiki/TransportTime)\n\t\t * @typedef {TransportTime}\n\t\t */\n\t\tTransportTime : \"transportTime\",\n\t\t/** \n\t\t * Ticks are the basic subunit of the Transport. They are\n\t\t * the smallest unit of time that the Transport supports.\n\t\t * @typedef {Ticks}\n\t\t */\n\t\tTicks : \"ticks\",\n\t\t/** \n\t\t * Normal values are within the range [0, 1].\n\t\t * @typedef {NormalRange}\n\t\t */\n\t\tNormalRange : \"normalRange\",\n\t\t/** \n\t\t * AudioRange values are between [-1, 1].\n\t\t * @typedef {AudioRange}\n\t\t */\n\t\tAudioRange : \"audioRange\",\n\t\t/** \n\t\t * Decibels are a logarithmic unit of measurement which is useful for volume\n\t\t * because of the logarithmic way that we perceive loudness. 0 decibels \n\t\t * means no change in volume. -10db is approximately half as loud and 10db \n\t\t * is twice is loud. \n\t\t * @typedef {Decibels}\n\t\t */\n\t\tDecibels : \"db\",\n\t\t/** \n\t\t * Half-step note increments, i.e. 12 is an octave above the root. and 1 is a half-step up.\n\t\t * @typedef {Interval}\n\t\t */\n\t\tInterval : \"interval\",\n\t\t/** \n\t\t * Beats per minute. \n\t\t * @typedef {BPM}\n\t\t */\n\t\tBPM : \"bpm\",\n\t\t/** \n\t\t * The value must be greater than or equal to 0.\n\t\t * @typedef {Positive}\n\t\t */\n\t\tPositive : \"positive\",\n\t\t/** \n\t\t * A cent is a hundredth of a semitone. \n\t\t * @typedef {Cents}\n\t\t */\n\t\tCents : \"cents\",\n\t\t/** \n\t\t * Angle between 0 and 360. \n\t\t * @typedef {Degrees}\n\t\t */\n\t\tDegrees : \"degrees\",\n\t\t/** \n\t\t * A number representing a midi note.\n\t\t * @typedef {MIDI}\n\t\t */\n\t\tMIDI : \"midi\",\n\t\t/** \n\t\t * A colon-separated representation of time in the form of\n\t\t * Bars:Beats:Sixteenths. \n\t\t * @typedef {BarsBeatsSixteenths}\n\t\t */\n\t\tBarsBeatsSixteenths : \"barsBeatsSixteenths\",\n\t\t/** \n\t\t * Sampling is the reduction of a continuous signal to a discrete signal.\n\t\t * Audio is typically sampled 44100 times per second. \n\t\t * @typedef {Samples}\n\t\t */\n\t\tSamples : \"samples\",\n\t\t/** \n\t\t * Hertz are a frequency representation defined as one cycle per second.\n\t\t * @typedef {Hertz}\n\t\t */\n\t\tHertz : \"hertz\",\n\t\t/** \n\t\t * A frequency represented by a letter name, \n\t\t * accidental and octave. This system is known as\n\t\t * [Scientific Pitch Notation](https://en.wikipedia.org/wiki/Scientific_pitch_notation).\n\t\t * @typedef {Note}\n\t\t */\n\t\tNote : \"note\",\n\t\t/** \n\t\t * One millisecond is a thousandth of a second. \n\t\t * @typedef {Milliseconds}\n\t\t */\n\t\tMilliseconds : \"milliseconds\",\n\t\t/** \n\t\t * Seconds are the time unit of the AudioContext. In the end, \n\t\t * all values need to be evaluated to seconds. \n\t\t * @typedef {Seconds}\n\t\t */\n\t\tSeconds : \"seconds\",\n\t\t/** \n\t\t * A string representing a duration relative to a measure. \n\t\t *
\n\t\t * \t
\"4n\" = quarter note
\n\t\t * \t
\"2m\" = two measures
\n\t\t * \t
\"8t\" = eighth-note triplet
\n\t\t *
\n\t\t * @typedef {Notation}\n\t\t */\n\t\tNotation : \"notation\",\n\t};\n\n\t///////////////////////////////////////////////////////////////////////////\n\t// AUGMENT TONE's PROTOTYPE\n\t///////////////////////////////////////////////////////////////////////////\n\n\t/**\n\t * Convert Time into seconds.\n\t * \n\t * Unlike the method which it overrides, this takes into account \n\t * transporttime and musical notation.\n\t *\n\t * Time : 1.40\n\t * Notation: 4n|1m|2t\n\t * Now Relative: +3n\n\t * Math: 3n+16n or even complicated expressions ((3n*2)/6 + 1)\n\t *\n\t * @param {Time} time \n\t * @return {Seconds} \n\t */\n\tTone.prototype.toSeconds = function(time){\n\t\tif (this.isNumber(time)){\n\t\t\treturn time;\n\t\t} else if (this.isUndef(time)){\n\t\t\treturn this.now();\t\t\t\n\t\t} else if (this.isString(time)){\n\t\t\treturn (new Tone.Time(time)).toSeconds();\n\t\t} else if (time instanceof Tone.TimeBase){\n\t\t\treturn time.toSeconds();\n\t\t}\n\t};\n\n\t/**\n\t * Convert a frequency representation into a number.\n\t * @param {Frequency} freq \n\t * @return {Hertz} the frequency in hertz\n\t */\n\tTone.prototype.toFrequency = function(freq){\n\t\tif (this.isNumber(freq)){\n\t\t\treturn freq;\n\t\t} else if (this.isString(freq) || this.isUndef(freq)){\n\t\t\treturn (new Tone.Frequency(freq)).valueOf();\n\t\t} else if (freq instanceof Tone.TimeBase){\n\t\t\treturn freq.toFrequency();\n\t\t}\n\t};\n\n\t/**\n\t * Convert a time representation into ticks.\n\t * @param {Time} time\n\t * @return {Ticks} the time in ticks\n\t */\n\tTone.prototype.toTicks = function(time){\n\t\tif (this.isNumber(time) || this.isString(time)){\n\t\t\treturn (new Tone.TransportTime(time)).toTicks();\n\t\t} else if (this.isUndef(time)){\n\t\t\treturn Tone.Transport.ticks;\t\t\t\n\t\t} else if (time instanceof Tone.TimeBase){\n\t\t\treturn time.toTicks();\n\t\t}\n\t};\n\n\treturn Tone;\n});","define([\"Tone/core/Tone\", \"Tone/core/Param\", \"Tone/type/Type\"], function (Tone) {\n\n\t\"use strict\";\n\n\t/**\n\t * createGain shim\n\t * @private\n\t */\n\tif (window.GainNode && !AudioContext.prototype.createGain){\n\t\tAudioContext.prototype.createGain = AudioContext.prototype.createGainNode;\n\t}\n\n\t/**\n\t * @class A thin wrapper around the Native Web Audio GainNode.\n\t * The GainNode is a basic building block of the Web Audio\n\t * API and is useful for routing audio and adjusting gains. \n\t * @extends {Tone}\n\t * @param {Number=} gain The initial gain of the GainNode\n\t * @param {Tone.Type=} units The units of the gain parameter. \n\t */\n\tTone.Gain = function(){\n\n\t\tvar options = this.optionsObject(arguments, [\"gain\", \"units\"], Tone.Gain.defaults);\n\n\t\t/**\n\t\t * The GainNode\n\t\t * @type {GainNode}\n\t\t * @private\n\t\t */\n\t\tthis.input = this.output = this._gainNode = this.context.createGain();\n\n\t\t/**\n\t\t * The gain parameter of the gain node.\n\t\t * @type {Tone.Param}\n\t\t * @signal\n\t\t */\n\t\tthis.gain = new Tone.Param({\n\t\t\t\"param\" : this._gainNode.gain, \n\t\t\t\"units\" : options.units,\n\t\t\t\"value\" : options.gain,\n\t\t\t\"convert\" : options.convert\n\t\t});\n\t\tthis._readOnly(\"gain\");\n\t};\n\n\tTone.extend(Tone.Gain);\n\n\t/**\n\t * The defaults\n\t * @const\n\t * @type {Object}\n\t */\n\tTone.Gain.defaults = {\n\t\t\"gain\" : 1,\n\t\t\"convert\" : true,\n\t};\n\n\t/**\n\t * Clean up.\n\t * @return {Tone.Gain} this\n\t */\n\tTone.Gain.prototype.dispose = function(){\n\t\tTone.Param.prototype.dispose.call(this);\n\t\tthis._gainNode.disconnect();\n\t\tthis._gainNode = null;\n\t\tthis._writable(\"gain\");\n\t\tthis.gain.dispose();\n\t\tthis.gain = null;\n\t};\n\n\t//STATIC///////////////////////////////////////////////////////////////////\n\n\t/**\n\t * Create input and outputs for this object.\n\t * @param {Number} input The number of inputs\n\t * @param {Number=} outputs The number of outputs\n\t * @return {Tone} this\n\t * @internal\n\t */\n\tTone.prototype.createInsOuts = function(inputs, outputs){\n\n\t\tif (inputs === 1){\n\t\t\tthis.input = new Tone.Gain();\n\t\t} else if (inputs > 1){\n\t\t\tthis.input = new Array(inputs);\n\t\t}\n\n\t\tif (outputs === 1){\n\t\t\tthis.output = new Tone.Gain();\n\t\t} else if (outputs > 1){\n\t\t\tthis.output = new Array(inputs);\n\t\t}\n\t};\n\n\t///////////////////////////////////////////////////////////////////////////\n\n\treturn Tone.Gain;\n});","'use strict';\r\n\r\ndefine(function () {\r\n /*\r\n Helper function to generate an error\r\n with a custom stack trace that points to the sketch\r\n and removes other parts of the stack trace.\r\n\r\n @private\r\n @class customError\r\n @constructor\r\n @param {String} name custom error name\r\n @param {String} errorTrace custom error trace\r\n @param {String} failedPath path to the file that failed to load\r\n @property {String} name custom error name\r\n @property {String} message custom error message\r\n @property {String} stack trace the error back to a line in the user's sketch.\r\n Note: this edits out stack trace within p5.js and p5.sound.\r\n @property {String} originalStack unedited, original stack trace\r\n @property {String} failedPath path to the file that failed to load\r\n @return {Error} returns a custom Error object\r\n */\r\n var CustomError = function(name, errorTrace, failedPath) {\r\n var err = new Error();\r\n var tempStack, splitStack;\r\n\r\n err.name = name;\r\n err.originalStack = err.stack + errorTrace;\r\n tempStack = err.stack + errorTrace;\r\n err.failedPath = failedPath;\r\n\r\n // only print the part of the stack trace that refers to the user code:\r\n var splitStack = tempStack.split('\\n');\r\n splitStack = splitStack.filter(function(ln) {\r\n return !ln.match(/(p5.|native code|globalInit)/g);\r\n });\r\n err.stack = splitStack.join('\\n');\r\n\r\n return err; // TODO: is this really a constructor?\r\n };\r\n\r\n return CustomError;\r\n});\r\n","define([\"Tone/core/Tone\", \"Tone/core/Emitter\"], function (Tone) {\n\n\t/**\n\t * shim\n\t * @private\n\t */\n\tif (!window.hasOwnProperty(\"AudioContext\") && window.hasOwnProperty(\"webkitAudioContext\")){\n\t\twindow.AudioContext = window.webkitAudioContext;\n\t}\n\n\t/**\n\t * @class Wrapper around the native AudioContext.\n\t * @extends {Tone.Emitter}\n\t * @param {AudioContext=} context optionally pass in a context\n\t */\n\tTone.Context = function(context){\n\n\t\tTone.Emitter.call(this);\n\n\t\tif (!context){\n\t\t\tcontext = new window.AudioContext();\n\t\t}\n\t\tthis._context = context;\n\t\t// extend all of the methods\n\t\tfor (var prop in this._context){\n\t\t\tthis._defineProperty(this._context, prop);\n\t\t}\n\n\t\t///////////////////////////////////////////////////////////////////////\n\t\t// WORKER\n\t\t///////////////////////////////////////////////////////////////////////\n\n\t\t/**\n\t\t * The default latency hint\n\t\t * @type {String}\n\t\t * @private\n\t\t */\n\t\tthis._latencyHint = \"interactive\";\n\n\t\t/**\n\t\t * The amount of time events are scheduled\n\t\t * into the future\n\t\t * @type {Number}\n\t\t * @private\n\t\t */\n\t\tthis._lookAhead = 0.1;\n\n\t\t/**\n\t\t * How often the update look runs\n\t\t * @type {Number}\n\t\t * @private\n\t\t */\n\t\tthis._updateInterval = this._lookAhead/3;\n\n\t\t/**\n\t\t * A reference to the actual computed update interval\n\t\t * @type {Number}\n\t\t * @private\n\t\t */\n\t\tthis._computedUpdateInterval = 0;\n\n\t\t/**\n\t\t * The web worker which is used to update Tone.Clock\n\t\t * @private\n\t\t * @type {WebWorker}\n\t\t */\n\t\tthis._worker = this._createWorker();\n\n\t\t/**\n\t\t * An object containing all of the constants AudioBufferSourceNodes\n\t\t * @type {Object}\n\t\t * @private\n\t\t */\n\t\tthis._constants = {};\n\n\t};\n\n\tTone.extend(Tone.Context, Tone.Emitter);\n\tTone.Emitter.mixin(Tone.Context);\n\n\t/**\n\t * Define a property on this Tone.Context. \n\t * This is used to extend the native AudioContext\n\t * @param {AudioContext} context\n\t * @param {String} prop \n\t * @private\n\t */\n\tTone.Context.prototype._defineProperty = function(context, prop){\n\t\tif (this.isUndef(this[prop])){\n\t\t\tObject.defineProperty(this, prop, {\n\t\t\t\tget : function(){\n\t\t\t\t\tif (typeof context[prop] === \"function\"){\n\t\t\t\t\t\treturn context[prop].bind(context);\n\t\t\t\t\t} else {\n\t\t\t\t\t\treturn context[prop];\n\t\t\t\t\t}\n\t\t\t\t},\n\t\t\t\tset : function(val){\n\t\t\t\t\tcontext[prop] = val;\n\t\t\t\t}\n\t\t\t});\n\t\t}\n\t};\n\n\t/**\n\t * The current audio context time\n\t * @return {Number}\n\t */\n\tTone.Context.prototype.now = function(){\n\t\treturn this._context.currentTime;\n\t};\n\n\t/**\n\t * Generate a web worker\n\t * @return {WebWorker}\n\t * @private\n\t */\n\tTone.Context.prototype._createWorker = function(){\n\t\t\n\t\t//URL Shim\n\t\twindow.URL = window.URL || window.webkitURL;\n\n\t\tvar blob = new Blob([\n\t\t\t//the initial timeout time\n\t\t\t\"var timeoutTime = \"+(this._updateInterval * 1000).toFixed(1)+\";\" +\n\t\t\t//onmessage callback\n\t\t\t\"self.onmessage = function(msg){\" +\n\t\t\t\"\ttimeoutTime = parseInt(msg.data);\" + \n\t\t\t\"};\" + \n\t\t\t//the tick function which posts a message\n\t\t\t//and schedules a new tick\n\t\t\t\"function tick(){\" +\n\t\t\t\"\tsetTimeout(tick, timeoutTime);\" +\n\t\t\t\"\tself.postMessage('tick');\" +\n\t\t\t\"}\" +\n\t\t\t//call tick initially\n\t\t\t\"tick();\"\n\t\t]);\n\t\tvar blobUrl = URL.createObjectURL(blob);\n\t\tvar worker = new Worker(blobUrl);\n\n\t\tworker.addEventListener(\"message\", function(){\n\t\t\t// tick the clock\n\t\t\tthis.emit(\"tick\");\n\t\t}.bind(this));\n\n\t\t//lag compensation\n\t\tworker.addEventListener(\"message\", function(){\n\t\t\tvar now = this.now();\n\t\t\tif (this.isNumber(this._lastUpdate)){\n\t\t\t\tvar diff = now - this._lastUpdate;\n\t\t\t\tthis._computedUpdateInterval = Math.max(diff, this._computedUpdateInterval * 0.97);\n\t\t\t}\n\t\t\tthis._lastUpdate = now;\n\t\t}.bind(this));\n\n\t\treturn worker;\n\t};\n\n\t/**\n\t * Generate a looped buffer at some constant value.\n\t * @param {Number} val\n\t * @return {BufferSourceNode}\n\t */\n\tTone.Context.prototype.getConstant = function(val){\n\t\tif (this._constants[val]){\n\t\t\treturn this._constants[val];\n\t\t} else {\n\t\t\tvar buffer = this._context.createBuffer(1, 128, this._context.sampleRate);\n\t\t\tvar arr = buffer.getChannelData(0);\n\t\t\tfor (var i = 0; i < arr.length; i++){\n\t\t\t\tarr[i] = val;\n\t\t\t}\n\t\t\tvar constant = this._context.createBufferSource();\n\t\t\tconstant.channelCount = 1;\n\t\t\tconstant.channelCountMode = \"explicit\";\n\t\t\tconstant.buffer = buffer;\n\t\t\tconstant.loop = true;\n\t\t\tconstant.start(0);\n\t\t\tthis._constants[val] = constant;\n\t\t\treturn constant;\n\t\t}\n\t};\n\n\t/**\n\t * This is the time that the clock is falling behind\n\t * the scheduled update interval. The Context automatically\n\t * adjusts for the lag and schedules further in advance.\n\t * @type {Number}\n\t * @memberOf Tone.Context\n\t * @name lag\n\t * @static\n\t * @readOnly\n\t */\n\tObject.defineProperty(Tone.Context.prototype, \"lag\", {\n\t\tget : function(){\n\t\t\tvar diff = this._computedUpdateInterval - this._updateInterval;\n\t\t\tdiff = Math.max(diff, 0);\n\t\t\treturn diff;\n\t\t}\n\t});\n\n\t/**\n\t * The amount of time in advance that events are scheduled.\n\t * The lookAhead will adjust slightly in response to the \n\t * measured update time to try to avoid clicks.\n\t * @type {Number}\n\t * @memberOf Tone.Context\n\t * @name lookAhead\n\t * @static\n\t */\n\tObject.defineProperty(Tone.Context.prototype, \"lookAhead\", {\n\t\tget : function(){\n\t\t\treturn this._lookAhead;\n\t\t},\n\t\tset : function(lA){\n\t\t\tthis._lookAhead = lA;\n\t\t}\n\t});\n\n\t/**\n\t * How often the Web Worker callback is invoked.\n\t * This number corresponds to how responsive the scheduling\n\t * can be. Context.updateInterval + Context.lookAhead gives you the\n\t * total latency between scheduling an event and hearing it.\n\t * @type {Number}\n\t * @memberOf Tone.Context\n\t * @name updateInterval\n\t * @static\n\t */\n\tObject.defineProperty(Tone.Context.prototype, \"updateInterval\", {\n\t\tget : function(){\n\t\t\treturn this._updateInterval;\n\t\t},\n\t\tset : function(interval){\n\t\t\tthis._updateInterval = Math.max(interval, Tone.prototype.blockTime);\n\t\t\tthis._worker.postMessage(Math.max(interval * 1000, 1));\n\t\t}\n\t});\n\n\t/**\n\t * The type of playback, which affects tradeoffs between audio \n\t * output latency and responsiveness. \n\t * \n\t * In addition to setting the value in seconds, the latencyHint also\n\t * accepts the strings \"interactive\" (prioritizes low latency), \n\t * \"playback\" (prioritizes sustained playback), \"balanced\" (balances\n\t * latency and performance), and \"fastest\" (lowest latency, might glitch more often). \n\t * @type {String|Seconds}\n\t * @memberOf Tone.Context#\n\t * @name latencyHint\n\t * @static\n\t * @example\n\t * //set the lookAhead to 0.3 seconds\n\t * Tone.context.latencyHint = 0.3;\n\t */\n\tObject.defineProperty(Tone.Context.prototype, \"latencyHint\", {\n\t\tget : function(){\n\t\t\treturn this._latencyHint;\n\t\t},\n\t\tset : function(hint){\n\t\t\tvar lookAhead = hint;\n\t\t\tthis._latencyHint = hint;\n\t\t\tif (this.isString(hint)){\n\t\t\t\tswitch(hint){\n\t\t\t\t\tcase \"interactive\" :\n\t\t\t\t\t\tlookAhead = 0.1;\n\t\t\t\t\t\tthis._context.latencyHint = hint;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase \"playback\" :\n\t\t\t\t\t\tlookAhead = 0.8;\n\t\t\t\t\t\tthis._context.latencyHint = hint;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase \"balanced\" :\n\t\t\t\t\t\tlookAhead = 0.25;\n\t\t\t\t\t\tthis._context.latencyHint = hint;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase \"fastest\" :\n\t\t\t\t\t\tlookAhead = 0.01;\n\t\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t\tthis.lookAhead = lookAhead;\n\t\t\tthis.updateInterval = lookAhead/3;\n\t\t}\n\t});\n\n\t/**\n\t * Shim all connect/disconnect and some deprecated methods which are still in\n\t * some older implementations.\n\t * @private\n\t */\n\tfunction shimConnect(){\n\n\t\tvar nativeConnect = AudioNode.prototype.connect;\n\t\tvar nativeDisconnect = AudioNode.prototype.disconnect;\n\n\t\t//replace the old connect method\n\t\tfunction toneConnect(B, outNum, inNum){\n\t\t\tif (B.input){\n\t\t\t\tif (Array.isArray(B.input)){\n\t\t\t\t\tif (Tone.prototype.isUndef(inNum)){\n\t\t\t\t\t\tinNum = 0;\n\t\t\t\t\t}\n\t\t\t\t\tthis.connect(B.input[inNum]);\n\t\t\t\t} else {\n\t\t\t\t\tthis.connect(B.input, outNum, inNum);\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\ttry {\n\t\t\t\t\tif (B instanceof AudioNode){\n\t\t\t\t\t\tnativeConnect.call(this, B, outNum, inNum);\n\t\t\t\t\t} else {\n\t\t\t\t\t\tnativeConnect.call(this, B, outNum);\n\t\t\t\t\t}\n\t\t\t\t} catch (e) {\n\t\t\t\t\tthrow new Error(\"error connecting to node: \"+B+\"\\n\"+e);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t//replace the old disconnect method\n\t\tfunction toneDisconnect(B, outNum, inNum){\n\t\t\tif (B && B.input && Array.isArray(B.input)){\n\t\t\t\tif (Tone.prototype.isUndef(inNum)){\n\t\t\t\t\tinNum = 0;\n\t\t\t\t}\n\t\t\t\tthis.disconnect(B.input[inNum], outNum, inNum);\n\t\t\t} else if (B && B.input){\n\t\t\t\tthis.disconnect(B.input, outNum, inNum);\n\t\t\t} else {\n\t\t\t\ttry {\n\t\t\t\t\tnativeDisconnect.apply(this, arguments);\n\t\t\t\t} catch (e) {\n\t\t\t\t\tthrow new Error(\"error disconnecting node: \"+B+\"\\n\"+e);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tif (AudioNode.prototype.connect !== toneConnect){\n\t\t\tAudioNode.prototype.connect = toneConnect;\n\t\t\tAudioNode.prototype.disconnect = toneDisconnect;\n\t\t}\n\t}\n\n\t// set the audio context initially\n\tif (Tone.supported){\n\t\tshimConnect();\n\t\tTone.context = new Tone.Context();\n\t} else {\n\t\tconsole.warn(\"This browser does not support Tone.js\");\n\t}\n\n\treturn Tone.Context;\n});","define([\"Tone/core/Tone\", \"Tone/signal/Add\", \"Tone/signal/Multiply\", \"Tone/signal/Signal\"], function(Tone){\n\n\t\"use strict\";\n\t\n\t/**\n\t * @class Performs a linear scaling on an input signal.\n\t * Scales a NormalRange input to between\n\t * outputMin and outputMax.\n\t *\n\t * @constructor\n\t * @extends {Tone.SignalBase}\n\t * @param {number} [outputMin=0] The output value when the input is 0. \n\t * @param {number} [outputMax=1]\tThe output value when the input is 1. \n\t * @example\n\t * var scale = new Tone.Scale(50, 100);\n\t * var signal = new Tone.Signal(0.5).connect(scale);\n\t * //the output of scale equals 75\n\t */\n\tTone.Scale = function(outputMin, outputMax){\n\n\t\t/** \n\t\t * @private\n\t\t * @type {number}\n\t\t */\n\t\tthis._outputMin = this.defaultArg(outputMin, 0);\n\n\t\t/** \n\t\t * @private\n\t\t * @type {number}\n\t\t */\n\t\tthis._outputMax = this.defaultArg(outputMax, 1);\n\n\n\t\t/** \n\t\t * @private\n\t\t * @type {Tone.Multiply}\n\t\t * @private\n\t\t */\n\t\tthis._scale = this.input = new Tone.Multiply(1);\n\t\t\n\t\t/** \n\t\t * @private\n\t\t * @type {Tone.Add}\n\t\t * @private\n\t\t */\n\t\tthis._add = this.output = new Tone.Add(0);\n\n\t\tthis._scale.connect(this._add);\n\t\tthis._setRange();\n\t};\n\n\tTone.extend(Tone.Scale, Tone.SignalBase);\n\n\t/**\n\t * The minimum output value. This number is output when \n\t * the value input value is 0. \n\t * @memberOf Tone.Scale#\n\t * @type {number}\n\t * @name min\n\t */\n\tObject.defineProperty(Tone.Scale.prototype, \"min\", {\n\t\tget : function(){\n\t\t\treturn this._outputMin;\n\t\t},\n\t\tset : function(min){\n\t\t\tthis._outputMin = min;\n\t\t\tthis._setRange();\n\t\t}\n\t});\n\n\t/**\n\t * The maximum output value. This number is output when \n\t * the value input value is 1. \n\t * @memberOf Tone.Scale#\n\t * @type {number}\n\t * @name max\n\t */\n\tObject.defineProperty(Tone.Scale.prototype, \"max\", {\n\t\tget : function(){\n\t\t\treturn this._outputMax;\n\t\t},\n\t\tset : function(max){\n\t\t\tthis._outputMax = max;\n\t\t\tthis._setRange();\n\t\t}\n\t});\n\n\t/**\n\t * set the values\n\t * @private\n\t */\n\tTone.Scale.prototype._setRange = function() {\n\t\tthis._add.value = this._outputMin;\n\t\tthis._scale.value = this._outputMax - this._outputMin;\n\t};\n\n\t/**\n\t * Clean up.\n\t * @returns {Tone.Scale} this\n\t */\n\tTone.Scale.prototype.dispose = function(){\n\t\tTone.prototype.dispose.call(this);\n\t\tthis._add.dispose();\n\t\tthis._add = null;\n\t\tthis._scale.dispose();\n\t\tthis._scale = null;\n\t\treturn this;\n\t}; \n\n\treturn Tone.Scale;\n});\n","define([\"Tone/core/Tone\", \"Tone/signal/Signal\", \"Tone/core/Timeline\"], function (Tone) {\n\n\t\"use strict\";\n\n\t/**\n\t * @class A signal which adds the method getValueAtTime. \n\t * Code and inspiration from https://github.com/jsantell/web-audio-automation-timeline\n\t * @extends {Tone.Param}\n\t * @param {Number=} value The initial value of the signal\n\t * @param {String=} units The conversion units of the signal.\n\t */\n\tTone.TimelineSignal = function(){\n\n\t\tvar options = this.optionsObject(arguments, [\"value\", \"units\"], Tone.Signal.defaults);\n\t\t\n\t\t/**\n\t\t * The scheduled events\n\t\t * @type {Tone.Timeline}\n\t\t * @private\n\t\t */\n\t\tthis._events = new Tone.Timeline(10);\n\n\t\t//constructors\n\t\tTone.Signal.apply(this, options);\n\t\toptions.param = this._param;\n\t\tTone.Param.call(this, options);\n\n\t\t/**\n\t\t * The initial scheduled value\n\t\t * @type {Number}\n\t\t * @private\n\t\t */\n\t\tthis._initial = this._fromUnits(this._param.value);\n\t};\n\n\tTone.extend(Tone.TimelineSignal, Tone.Param);\n\n\t/**\n\t * The event types of a schedulable signal.\n\t * @enum {String}\n\t * @private\n\t */\n\tTone.TimelineSignal.Type = {\n\t\tLinear : \"linear\",\n\t\tExponential : \"exponential\",\n\t\tTarget : \"target\",\n\t\tCurve : \"curve\",\n\t\tSet : \"set\"\n\t};\n\n\t/**\n\t * The current value of the signal. \n\t * @memberOf Tone.TimelineSignal#\n\t * @type {Number}\n\t * @name value\n\t */\n\tObject.defineProperty(Tone.TimelineSignal.prototype, \"value\", {\n\t\tget : function(){\n\t\t\tvar now = this.now();\n\t\t\tvar val = this.getValueAtTime(now);\n\t\t\treturn this._toUnits(val);\n\t\t},\n\t\tset : function(value){\n\t\t\tvar convertedVal = this._fromUnits(value);\n\t\t\tthis._initial = convertedVal;\n\t\t\tthis.cancelScheduledValues();\n\t\t\tthis._param.value = convertedVal;\n\t\t}\n\t});\n\n\t///////////////////////////////////////////////////////////////////////////\n\t//\tSCHEDULING\n\t///////////////////////////////////////////////////////////////////////////\n\n\t/**\n\t * Schedules a parameter value change at the given time.\n\t * @param {*}\tvalue The value to set the signal.\n\t * @param {Time} time The time when the change should occur.\n\t * @returns {Tone.TimelineSignal} this\n\t * @example\n\t * //set the frequency to \"G4\" in exactly 1 second from now. \n\t * freq.setValueAtTime(\"G4\", \"+1\");\n\t */\n\tTone.TimelineSignal.prototype.setValueAtTime = function (value, startTime) {\n\t\tvalue = this._fromUnits(value);\n\t\tstartTime = this.toSeconds(startTime);\n\t\tthis._events.add({\n\t\t\t\"type\" : Tone.TimelineSignal.Type.Set,\n\t\t\t\"value\" : value,\n\t\t\t\"time\" : startTime\n\t\t});\n\t\t//invoke the original event\n\t\tthis._param.setValueAtTime(value, startTime);\n\t\treturn this;\n\t};\n\n\t/**\n\t * Schedules a linear continuous change in parameter value from the \n\t * previous scheduled parameter value to the given value.\n\t * \n\t * @param {number} value \n\t * @param {Time} endTime \n\t * @returns {Tone.TimelineSignal} this\n\t */\n\tTone.TimelineSignal.prototype.linearRampToValueAtTime = function (value, endTime) {\n\t\tvalue = this._fromUnits(value);\n\t\tendTime = this.toSeconds(endTime);\n\t\tthis._events.add({\n\t\t\t\"type\" : Tone.TimelineSignal.Type.Linear,\n\t\t\t\"value\" : value,\n\t\t\t\"time\" : endTime\n\t\t});\n\t\tthis._param.linearRampToValueAtTime(value, endTime);\n\t\treturn this;\n\t};\n\n\t/**\n\t * Schedules an exponential continuous change in parameter value from \n\t * the previous scheduled parameter value to the given value.\n\t * \n\t * @param {number} value \n\t * @param {Time} endTime \n\t * @returns {Tone.TimelineSignal} this\n\t */\n\tTone.TimelineSignal.prototype.exponentialRampToValueAtTime = function (value, endTime) {\n\t\t//get the previous event and make sure it's not starting from 0\n\t\tendTime = this.toSeconds(endTime);\n\t\tvar beforeEvent = this._searchBefore(endTime);\n\t\tif (beforeEvent && beforeEvent.value === 0){\n\t\t\t//reschedule that event\n\t\t\tthis.setValueAtTime(this._minOutput, beforeEvent.time);\n\t\t}\n\t\tvalue = this._fromUnits(value);\n\t\tvar setValue = Math.max(value, this._minOutput);\n\t\tthis._events.add({\n\t\t\t\"type\" : Tone.TimelineSignal.Type.Exponential,\n\t\t\t\"value\" : setValue,\n\t\t\t\"time\" : endTime\n\t\t});\n\t\t//if the ramped to value is 0, make it go to the min output, and then set to 0.\n\t\tif (value < this._minOutput){\n\t\t\tthis._param.exponentialRampToValueAtTime(this._minOutput, endTime - this.sampleTime);\n\t\t\tthis.setValueAtTime(0, endTime);\n\t\t} else {\n\t\t\tthis._param.exponentialRampToValueAtTime(value, endTime);\n\t\t}\n\t\treturn this;\n\t};\n\n\t/**\n\t * Start exponentially approaching the target value at the given time with\n\t * a rate having the given time constant.\n\t * @param {number} value \n\t * @param {Time} startTime \n\t * @param {number} timeConstant \n\t * @returns {Tone.TimelineSignal} this \n\t */\n\tTone.TimelineSignal.prototype.setTargetAtTime = function (value, startTime, timeConstant) {\n\t\tvalue = this._fromUnits(value);\n\t\tvalue = Math.max(this._minOutput, value);\n\t\ttimeConstant = Math.max(this._minOutput, timeConstant);\n\t\tstartTime = this.toSeconds(startTime);\n\t\tthis._events.add({\n\t\t\t\"type\" : Tone.TimelineSignal.Type.Target,\n\t\t\t\"value\" : value,\n\t\t\t\"time\" : startTime,\n\t\t\t\"constant\" : timeConstant\n\t\t});\n\t\tthis._param.setTargetAtTime(value, startTime, timeConstant);\n\t\treturn this;\n\t};\n\n\t/**\n\t * Set an array of arbitrary values starting at the given time for the given duration.\n\t * @param {Float32Array} values \n\t * @param {Time} startTime \n\t * @param {Time} duration\n\t * @param {NormalRange} [scaling=1] If the values in the curve should be scaled by some value\n\t * @returns {Tone.TimelineSignal} this \n\t */\n\tTone.TimelineSignal.prototype.setValueCurveAtTime = function (values, startTime, duration, scaling) {\n\t\tscaling = this.defaultArg(scaling, 1);\n\t\t//copy the array\n\t\tvar floats = new Array(values.length);\n\t\tfor (var i = 0; i < floats.length; i++){\n\t\t\tfloats[i] = this._fromUnits(values[i]) * scaling;\n\t\t}\n\t\tstartTime = this.toSeconds(startTime);\n\t\tduration = this.toSeconds(duration);\n\t\tthis._events.add({\n\t\t\t\"type\" : Tone.TimelineSignal.Type.Curve,\n\t\t\t\"value\" : floats,\n\t\t\t\"time\" : startTime,\n\t\t\t\"duration\" : duration\n\t\t});\n\t\t//set the first value\n\t\tthis._param.setValueAtTime(floats[0], startTime);\n\t\t//schedule a lienar ramp for each of the segments\n\t\tfor (var j = 1; j < floats.length; j++){\n\t\t\tvar segmentTime = startTime + (j / (floats.length - 1) * duration);\n\t\t\tthis._param.linearRampToValueAtTime(floats[j], segmentTime);\n\t\t}\n\t\treturn this;\n\t};\n\n\t/**\n\t * Cancels all scheduled parameter changes with times greater than or \n\t * equal to startTime.\n\t * \n\t * @param {Time} startTime\n\t * @returns {Tone.TimelineSignal} this\n\t */\n\tTone.TimelineSignal.prototype.cancelScheduledValues = function (after) {\n\t\tafter = this.toSeconds(after);\n\t\tthis._events.cancel(after);\n\t\tthis._param.cancelScheduledValues(after);\n\t\treturn this;\n\t};\n\n\t/**\n\t * Sets the computed value at the given time. This provides\n\t * a point from which a linear or exponential curve\n\t * can be scheduled after. Will cancel events after \n\t * the given time and shorten the currently scheduled\n\t * linear or exponential ramp so that it ends at `time` .\n\t * This is to avoid discontinuities and clicks in envelopes. \n\t * @param {Time} time When to set the ramp point\n\t * @returns {Tone.TimelineSignal} this\n\t */\n\tTone.TimelineSignal.prototype.setRampPoint = function (time) {\n\t\ttime = this.toSeconds(time);\n\t\t//get the value at the given time\n\t\tvar val = this._toUnits(this.getValueAtTime(time));\n\t\t//if there is an event at the given time\n\t\t//and that even is not a \"set\"\n\t\tvar before = this._searchBefore(time);\n\t\tif (before && before.time === time){\n\t\t\t//remove everything after\n\t\t\tthis.cancelScheduledValues(time + this.sampleTime);\n\t\t} else if (before && \n\t\t\t\t before.type === Tone.TimelineSignal.Type.Curve &&\n\t\t\t\t before.time + before.duration > time){\n\t\t\t//if the curve is still playing\n\t\t\t//cancel the curve\n\t\t\tthis.cancelScheduledValues(time);\n\t\t\tthis.linearRampToValueAtTime(val, time);\n\t\t} else {\n\t\t\t//reschedule the next event to end at the given time\n\t\t\tvar after = this._searchAfter(time);\n\t\t\tif (after){\n\t\t\t\t//cancel the next event(s)\n\t\t\t\tthis.cancelScheduledValues(time);\n\t\t\t\tif (after.type === Tone.TimelineSignal.Type.Linear){\n\t\t\t\t\tthis.linearRampToValueAtTime(val, time);\n\t\t\t\t} else if (after.type === Tone.TimelineSignal.Type.Exponential){\n\t\t\t\t\tthis.exponentialRampToValueAtTime(val, time);\n\t\t\t\t}\n\t\t\t}\n\t\t\tthis.setValueAtTime(val, time);\n\t\t}\n\t\treturn this;\n\t};\n\n\t/**\n\t * Do a linear ramp to the given value between the start and finish times.\n\t * @param {Number} value The value to ramp to.\n\t * @param {Time} start The beginning anchor point to do the linear ramp\n\t * @param {Time} finish The ending anchor point by which the value of\n\t * the signal will equal the given value.\n\t * @returns {Tone.TimelineSignal} this\n\t */\n\tTone.TimelineSignal.prototype.linearRampToValueBetween = function (value, start, finish) {\n\t\tthis.setRampPoint(start);\n\t\tthis.linearRampToValueAtTime(value, finish);\n\t\treturn this;\n\t};\n\n\t/**\n\t * Do a exponential ramp to the given value between the start and finish times.\n\t * @param {Number} value The value to ramp to.\n\t * @param {Time} start The beginning anchor point to do the exponential ramp\n\t * @param {Time} finish The ending anchor point by which the value of\n\t * the signal will equal the given value.\n\t * @returns {Tone.TimelineSignal} this\n\t */\n\tTone.TimelineSignal.prototype.exponentialRampToValueBetween = function (value, start, finish) {\n\t\tthis.setRampPoint(start);\n\t\tthis.exponentialRampToValueAtTime(value, finish);\n\t\treturn this;\n\t};\n\n\t///////////////////////////////////////////////////////////////////////////\n\t//\tGETTING SCHEDULED VALUES\n\t///////////////////////////////////////////////////////////////////////////\n\n\t/**\n\t * Returns the value before or equal to the given time\n\t * @param {Number} time The time to query\n\t * @return {Object} The event at or before the given time.\n\t * @private\n\t */\n\tTone.TimelineSignal.prototype._searchBefore = function(time){\n\t\treturn this._events.get(time);\n\t};\n\n\t/**\n\t * The event after the given time\n\t * @param {Number} time The time to query.\n\t * @return {Object} The next event after the given time\n\t * @private\n\t */\n\tTone.TimelineSignal.prototype._searchAfter = function(time){\n\t\treturn this._events.getAfter(time);\n\t};\n\n\t/**\n\t * Get the scheduled value at the given time. This will\n\t * return the unconverted (raw) value.\n\t * @param {Number} time The time in seconds.\n\t * @return {Number} The scheduled value at the given time.\n\t */\n\tTone.TimelineSignal.prototype.getValueAtTime = function(time){\n\t\ttime = this.toSeconds(time);\n\t\tvar after = this._searchAfter(time);\n\t\tvar before = this._searchBefore(time);\n\t\tvar value = this._initial;\n\t\t//if it was set by\n\t\tif (before === null){\n\t\t\tvalue = this._initial;\n\t\t} else if (before.type === Tone.TimelineSignal.Type.Target){\n\t\t\tvar previous = this._events.getBefore(before.time);\n\t\t\tvar previouVal;\n\t\t\tif (previous === null){\n\t\t\t\tpreviouVal = this._initial;\n\t\t\t} else {\n\t\t\t\tpreviouVal = previous.value;\n\t\t\t}\n\t\t\tvalue = this._exponentialApproach(before.time, previouVal, before.value, before.constant, time);\n\t\t} else if (before.type === Tone.TimelineSignal.Type.Curve){\n\t\t\tvalue = this._curveInterpolate(before.time, before.value, before.duration, time);\n\t\t} else if (after === null){\n\t\t\tvalue = before.value;\n\t\t} else if (after.type === Tone.TimelineSignal.Type.Linear){\n\t\t\tvalue = this._linearInterpolate(before.time, before.value, after.time, after.value, time);\n\t\t} else if (after.type === Tone.TimelineSignal.Type.Exponential){\n\t\t\tvalue = this._exponentialInterpolate(before.time, before.value, after.time, after.value, time);\n\t\t} else {\n\t\t\tvalue = before.value;\n\t\t}\n\t\treturn value;\n\t};\n\n\t/**\n\t * When signals connect to other signals or AudioParams, \n\t * they take over the output value of that signal or AudioParam. \n\t * For all other nodes, the behavior is the same as a default connect. \n\t *\n\t * @override\n\t * @param {AudioParam|AudioNode|Tone.Signal|Tone} node \n\t * @param {number} [outputNumber=0] The output number to connect from.\n\t * @param {number} [inputNumber=0] The input number to connect to.\n\t * @returns {Tone.TimelineSignal} this\n\t * @method\n\t */\n\tTone.TimelineSignal.prototype.connect = Tone.SignalBase.prototype.connect;\n\n\n\t///////////////////////////////////////////////////////////////////////////\n\t//\tAUTOMATION CURVE CALCULATIONS\n\t//\tMIT License, copyright (c) 2014 Jordan Santell\n\t///////////////////////////////////////////////////////////////////////////\n\n\t/**\n\t * Calculates the the value along the curve produced by setTargetAtTime\n\t * @private\n\t */\n\tTone.TimelineSignal.prototype._exponentialApproach = function (t0, v0, v1, timeConstant, t) {\n\t\treturn v1 + (v0 - v1) * Math.exp(-(t - t0) / timeConstant);\n\t};\n\n\t/**\n\t * Calculates the the value along the curve produced by linearRampToValueAtTime\n\t * @private\n\t */\n\tTone.TimelineSignal.prototype._linearInterpolate = function (t0, v0, t1, v1, t) {\n\t\treturn v0 + (v1 - v0) * ((t - t0) / (t1 - t0));\n\t};\n\n\t/**\n\t * Calculates the the value along the curve produced by exponentialRampToValueAtTime\n\t * @private\n\t */\n\tTone.TimelineSignal.prototype._exponentialInterpolate = function (t0, v0, t1, v1, t) {\n\t\tv0 = Math.max(this._minOutput, v0);\n\t\treturn v0 * Math.pow(v1 / v0, (t - t0) / (t1 - t0));\n\t};\n\n\t/**\n\t * Calculates the the value along the curve produced by setValueCurveAtTime\n\t * @private\n\t */\n\tTone.TimelineSignal.prototype._curveInterpolate = function (start, curve, duration, time) {\n\t\tvar len = curve.length;\n\t\t// If time is after duration, return the last curve value\n\t\tif (time >= start + duration) {\n\t\t\treturn curve[len - 1];\n\t\t} else if (time <= start){\n\t\t\treturn curve[0];\n\t\t} else {\n\t\t\tvar progress = (time - start) / duration;\n\t\t\tvar lowerIndex = Math.floor((len - 1) * progress);\n\t\t\tvar upperIndex = Math.ceil((len - 1) * progress);\n\t\t\tvar lowerVal = curve[lowerIndex];\n\t\t\tvar upperVal = curve[upperIndex];\n\t\t\tif (upperIndex === lowerIndex){\n\t\t\t\treturn lowerVal;\n\t\t\t} else {\n\t\t\t\treturn this._linearInterpolate(lowerIndex, lowerVal, upperIndex, upperVal, progress * (len - 1));\n\t\t\t}\n\t\t}\n\t};\n\n\t/**\n\t * Clean up.\n\t * @return {Tone.TimelineSignal} this\n\t */\n\tTone.TimelineSignal.prototype.dispose = function(){\n\t\tTone.Signal.prototype.dispose.call(this);\n\t\tTone.Param.prototype.dispose.call(this);\n\t\tthis._events.dispose();\n\t\tthis._events = null;\n\t};\n\n\treturn Tone.TimelineSignal;\n});","'use strict';\r\n\r\ndefine(function (require) {\r\n var Effect = require('effect');\r\n\r\n /**\r\n *
A p5.Filter uses a Web Audio Biquad Filter to filter\r\n * the frequency response of an input source. Subclasses\r\n * include:
\r\n * p5.LowPass:\r\n * Allows frequencies below the cutoff frequency to pass through,\r\n * and attenuates frequencies above the cutoff. \r\n * p5.HighPass:\r\n * The opposite of a lowpass filter. \r\n * p5.BandPass:\r\n * Allows a range of frequencies to pass through and attenuates\r\n * the frequencies below and above this frequency range. \r\n *\r\n * The .res() method controls either width of the\r\n * bandpass, or resonance of the low/highpass cutoff frequency.\r\n *\r\n * This class extends p5.Effect.\r\n * Methods amp(), chain(),\r\n * drywet(), connect(), and\r\n * disconnect() are available.\r\n *\r\n * @class p5.Filter\r\n * @extends p5.Effect\r\n * @constructor\r\n * @param {String} [type] 'lowpass' (default), 'highpass', 'bandpass'\r\n * @example\r\n *
\r\n * var fft, noise, filter;\r\n *\r\n * function setup() {\r\n * fill(255, 40, 255);\r\n *\r\n * filter = new p5.BandPass();\r\n *\r\n * noise = new p5.Noise();\r\n * // disconnect unfiltered noise,\r\n * // and connect to filter\r\n * noise.disconnect();\r\n * noise.connect(filter);\r\n * noise.start();\r\n *\r\n * fft = new p5.FFT();\r\n * }\r\n *\r\n * function draw() {\r\n * background(30);\r\n *\r\n * // set the BandPass frequency based on mouseX\r\n * var freq = map(mouseX, 0, width, 20, 10000);\r\n * filter.freq(freq);\r\n * // give the filter a narrow band (lower res = wider bandpass)\r\n * filter.res(50);\r\n *\r\n * // draw filtered spectrum\r\n * var spectrum = fft.analyze();\r\n * noStroke();\r\n * for (var i = 0; i < spectrum.length; i++) {\r\n * var x = map(i, 0, spectrum.length, 0, width);\r\n * var h = -height + map(spectrum[i], 0, 255, height, 0);\r\n * rect(x, height, width/spectrum.length, h);\r\n * }\r\n *\r\n * isMouseOverCanvas();\r\n * }\r\n *\r\n * function isMouseOverCanvas() {\r\n * var mX = mouseX, mY = mouseY;\r\n * if (mX > 0 && mX < width && mY < height && mY > 0) {\r\n * noise.amp(0.5, 0.2);\r\n * } else {\r\n * noise.amp(0, 0.2);\r\n * }\r\n * }\r\n *
\r\n */\r\n p5.Filter = function (type) {\r\n\r\n Effect.call(this);\r\n //add extend Effect by adding a Biquad Filter\r\n\r\n /**\r\n * The p5.Filter is built with a\r\n * \r\n * Web Audio BiquadFilter Node.\r\n *\r\n * @property {DelayNode} biquadFilter\r\n\t */\r\n\r\n this.biquad = this.ac.createBiquadFilter();\r\n\r\n this.input.connect(this.biquad);\r\n\r\n this.biquad.connect(this.wet);\r\n\r\n if (type) {\r\n this.setType(type);\r\n }\r\n\r\n //Properties useful for the toggle method.\r\n this._on = true;\r\n this._untoggledType = this.biquad.type;\r\n };\r\n p5.Filter.prototype = Object.create(Effect.prototype);\r\n\r\n\r\n /**\r\n * Filter an audio signal according to a set\r\n * of filter parameters.\r\n *\r\n * @method process\r\n * @param {Object} Signal An object that outputs audio\r\n * @param {Number} [freq] Frequency in Hz, from 10 to 22050\r\n * @param {Number} [res] Resonance/Width of the filter frequency\r\n * from 0.001 to 1000\r\n */\r\n p5.Filter.prototype.process = function(src, freq, res, time) {\r\n src.connect(this.input);\r\n this.set(freq, res, time);\r\n };\r\n\r\n\r\n /**\r\n * Set the frequency and the resonance of the filter.\r\n *\r\n * @method set\r\n * @param {Number} [freq] Frequency in Hz, from 10 to 22050\r\n * @param {Number} [res] Resonance (Q) from 0.001 to 1000\r\n * @param {Number} [timeFromNow] schedule this event to happen\r\n * seconds from now\r\n */\r\n p5.Filter.prototype.set = function(freq, res, time) {\r\n if (freq) {\r\n this.freq(freq, time);\r\n }\r\n if (res) {\r\n this.res(res, time);\r\n }\r\n };\r\n\r\n /**\r\n * Set the filter frequency, in Hz, from 10 to 22050 (the range of\r\n * human hearing, although in reality most people hear in a narrower\r\n * range).\r\n *\r\n * @method freq\r\n * @param {Number} freq Filter Frequency\r\n * @param {Number} [timeFromNow] schedule this event to happen\r\n * seconds from now\r\n * @return {Number} value Returns the current frequency value\r\n */\r\n p5.Filter.prototype.freq = function(freq, time) {\r\n var t = time || 0;\r\n if (freq <= 0) {\r\n freq = 1;\r\n }\r\n if (typeof freq === 'number') {\r\n this.biquad.frequency.cancelScheduledValues(this.ac.currentTime + 0.01 + t);\r\n this.biquad.frequency.exponentialRampToValueAtTime(freq, this.ac.currentTime + 0.02 + t);\r\n } else if (freq) {\r\n freq.connect(this.biquad.frequency);\r\n }\r\n return this.biquad.frequency.value;\r\n };\r\n\r\n /**\r\n * Controls either width of a bandpass frequency,\r\n * or the resonance of a low/highpass cutoff frequency.\r\n *\r\n * @method res\r\n * @param {Number} res Resonance/Width of filter freq\r\n * from 0.001 to 1000\r\n * @param {Number} [timeFromNow] schedule this event to happen\r\n * seconds from now\r\n * @return {Number} value Returns the current res value\r\n */\r\n p5.Filter.prototype.res = function(res, time) {\r\n var t = time || 0;\r\n if (typeof res === 'number') {\r\n this.biquad.Q.value = res;\r\n this.biquad.Q.cancelScheduledValues(this.ac.currentTime + 0.01 + t);\r\n this.biquad.Q.linearRampToValueAtTime(res, this.ac.currentTime + 0.02 + t);\r\n } else if (res) {\r\n res.connect(this.biquad.Q);\r\n }\r\n return this.biquad.Q.value;\r\n };\r\n\r\n /**\r\n * Controls the gain attribute of a Biquad Filter.\r\n * This is distinctly different from .amp() which is inherited from p5.Effect\r\n * .amp() controls the volume via the output gain node\r\n * p5.Filter.gain() controls the gain parameter of a Biquad Filter node.\r\n *\r\n * @method gain\r\n * @param {Number} gain\r\n * @return {Number} Returns the current or updated gain value\r\n */\r\n p5.Filter.prototype.gain = function(gain, time) {\r\n var t = time || 0;\r\n if (typeof gain === 'number') {\r\n this.biquad.gain.value = gain;\r\n this.biquad.gain.cancelScheduledValues(this.ac.currentTime + 0.01 + t);\r\n this.biquad.gain.linearRampToValueAtTime(gain, this.ac.currentTime + 0.02 + t);\r\n } else if (gain) {\r\n gain.connect(this.biquad.gain);\r\n }\r\n return this.biquad.gain.value;\r\n };\r\n\r\n\r\n /**\r\n * Toggle function. Switches between the specified type and allpass\r\n *\r\n * @method toggle\r\n * @return {boolean} [Toggle value]\r\n */\r\n p5.Filter.prototype.toggle = function() {\r\n this._on = !this._on;\r\n\r\n if (this._on === true) {\r\n this.biquad.type = this._untoggledType;\r\n } else if (this._on === false) {\r\n this.biquad.type = 'allpass';\r\n }\r\n\r\n return this._on;\r\n };\r\n\r\n /**\r\n * Set the type of a p5.Filter. Possible types include:\r\n * \"lowpass\" (default), \"highpass\", \"bandpass\",\r\n * \"lowshelf\", \"highshelf\", \"peaking\", \"notch\",\r\n * \"allpass\".\r\n *\r\n * @method setType\r\n * @param {String} t\r\n */\r\n p5.Filter.prototype.setType = function(t) {\r\n this.biquad.type = t;\r\n this._untoggledType = this.biquad.type;\r\n };\r\n\r\n p5.Filter.prototype.dispose = function() {\r\n // remove reference from soundArray\r\n Effect.prototype.dispose.apply(this);\r\n if (this.biquad) {\r\n this.biquad.disconnect();\r\n delete this.biquad;\r\n }\r\n };\r\n\r\n /**\r\n * Constructor: new p5.LowPass() Filter.\r\n * This is the same as creating a p5.Filter and then calling\r\n * its method setType('lowpass').\r\n * See p5.Filter for methods.\r\n *\r\n * @class p5.LowPass\r\n * @constructor\r\n * @extends p5.Filter\r\n */\r\n p5.LowPass = function() {\r\n p5.Filter.call(this, 'lowpass');\r\n };\r\n p5.LowPass.prototype = Object.create(p5.Filter.prototype);\r\n\r\n /**\r\n * Constructor: new p5.HighPass() Filter.\r\n * This is the same as creating a p5.Filter and then calling\r\n * its method setType('highpass').\r\n * See p5.Filter for methods.\r\n *\r\n * @class p5.HighPass\r\n * @constructor\r\n * @extends p5.Filter\r\n */\r\n p5.HighPass = function() {\r\n p5.Filter.call(this, 'highpass');\r\n };\r\n p5.HighPass.prototype = Object.create(p5.Filter.prototype);\r\n\r\n /**\r\n * Constructor: new p5.BandPass() Filter.\r\n * This is the same as creating a p5.Filter and then calling\r\n * its method setType('bandpass').\r\n * See p5.Filter for methods.\r\n *\r\n * @class p5.BandPass\r\n * @constructor\r\n * @extends p5.Filter\r\n */\r\n p5.BandPass = function() {\r\n p5.Filter.call(this, 'bandpass');\r\n };\r\n p5.BandPass.prototype = Object.create(p5.Filter.prototype);\r\n\r\n return p5.Filter;\r\n});\r\n","define([\"Tone/core/Tone\", \"Tone/signal/Add\", \"Tone/signal/Negate\", \"Tone/signal/Signal\", \"Tone/core/Gain\"], function(Tone){\n\n\t\"use strict\";\n\n\t/**\n\t * @class Subtract the signal connected to input[1] from the signal connected \n\t * to input[0]. If an argument is provided in the constructor, the \n\t * signals .value will be subtracted from the incoming signal.\n\t *\n\t * @extends {Tone.Signal}\n\t * @constructor\n\t * @param {number=} value The value to subtract from the incoming signal. If the value\n\t * is omitted, it will subtract the second signal from the first.\n\t * @example\n\t * var sub = new Tone.Subtract(1);\n\t * var sig = new Tone.Signal(4).connect(sub);\n\t * //the output of sub is 3. \n\t * @example\n\t * var sub = new Tone.Subtract();\n\t * var sigA = new Tone.Signal(10);\n\t * var sigB = new Tone.Signal(2.5);\n\t * sigA.connect(sub, 0, 0);\n\t * sigB.connect(sub, 0, 1);\n\t * //output of sub is 7.5\n\t */\n\tTone.Subtract = function(value){\n\n\t\tthis.createInsOuts(2, 0);\n\n\t\t/**\n\t\t * the summing node\n\t\t * @type {GainNode}\n\t\t * @private\n\t\t */\n\t\tthis._sum = this.input[0] = this.output = new Tone.Gain();\n\n\t\t/**\n\t\t * negate the input of the second input before connecting it\n\t\t * to the summing node.\n\t\t * @type {Tone.Negate}\n\t\t * @private\n\t\t */\n\t\tthis._neg = new Tone.Negate();\n\n\t\t/**\n\t\t * the node where the value is set\n\t\t * @private\n\t\t * @type {Tone.Signal}\n\t\t */\n\t\tthis._param = this.input[1] = new Tone.Signal(value);\n\n\t\tthis._param.chain(this._neg, this._sum);\n\t};\n\n\tTone.extend(Tone.Subtract, Tone.Signal);\n\n\t/**\n\t * Clean up.\n\t * @returns {Tone.SignalBase} this\n\t */\n\tTone.Subtract.prototype.dispose = function(){\n\t\tTone.prototype.dispose.call(this);\n\t\tthis._neg.dispose();\n\t\tthis._neg = null;\n\t\tthis._sum.disconnect();\n\t\tthis._sum = null;\n\t\tthis._param.dispose();\n\t\tthis._param = null;\n\t\treturn this;\n\t};\n\n\treturn Tone.Subtract;\n});","'use strict';\r\n\r\nglobal.TONE_SILENCE_VERSION_LOGGING = true;\r\n\r\ndefine(['startaudiocontext', 'Tone/core/Context', 'Tone/core/Tone'], function (StartAudioContext, Context, Tone) {\r\n // Create the Audio Context\r\n const audiocontext = new window.AudioContext();\r\n\r\n // Tone and p5.sound share the same audio context\r\n Tone.context.dispose();\r\n Tone.setContext(audiocontext);\r\n\r\n /**\r\n *
Returns the Audio Context for this sketch. Useful for users\r\n * who would like to dig deeper into the Web Audio API\r\n * .
\r\n *\r\n *
Some browsers require users to startAudioContext\r\n * with a user gesture, such as touchStarted in the example below.
\r\n *\r\n * @method getAudioContext\r\n * @return {Object} AudioContext for this sketch\r\n * @example\r\n *
\r\n * function draw() {\r\n * background(255);\r\n * textAlign(CENTER);\r\n *\r\n * if (getAudioContext().state !== 'running') {\r\n * text('click to start audio', width/2, height/2);\r\n * } else {\r\n * text('audio is enabled', width/2, height/2);\r\n * }\r\n * }\r\n *\r\n * function touchStarted() {\r\n * if (getAudioContext().state !== 'running') {\r\n * getAudioContext().resume();\r\n * }\r\n * var synth = new p5.MonoSynth();\r\n * synth.play('A4', 0.5, 0, 0.2);\r\n * }\r\n *\r\n *
It is a good practice to give users control over starting audio playback.\r\n * This practice is enforced by Google Chrome's autoplay policy as of r70\r\n * (info), iOS Safari, and other browsers.\r\n *
\r\n *\r\n *
\r\n * userStartAudio() starts the Audio Context on a user gesture. It utilizes\r\n * the StartAudioContext library by\r\n * Yotam Mann (MIT Licence, 2016). Read more at https://github.com/tambien/StartAudioContext.\r\n *
\r\n *\r\n *
Starting the audio context on a user gesture can be as simple as userStartAudio().\r\n * Optional parameters let you decide on a specific element that will start the audio context,\r\n * and/or call a function once the audio context is started.
\r\n * @param {Element|Array} [element(s)] This argument can be an Element,\r\n * Selector String, NodeList, p5.Element,\r\n * jQuery Element, or an Array of any of those.\r\n * @param {Function} [callback] Callback to invoke when the AudioContext has started\r\n * @return {Promise} Returns a Promise which is resolved when\r\n * the AudioContext state is 'running'\r\n * @method userStartAudio\r\n * @for p5\r\n * @example\r\n *
\r\n * function setup() {\r\n * var myDiv = createDiv('click to start audio');\r\n * myDiv.position(0, 0);\r\n *\r\n * var mySynth = new p5.MonoSynth();\r\n *\r\n * // This won't play until the context has started\r\n * mySynth.play('A6');\r\n *\r\n * // Start the audio context on a click/touch event\r\n * userStartAudio().then(function() {\r\n * myDiv.remove();\r\n * });\r\n * }\r\n *
\r\n */\r\n p5.prototype.userStartAudio = function(elements, callback) {\r\n var elt = elements;\r\n if (elements instanceof p5.Element) {\r\n elt = elements.elt;\r\n } else if (elements instanceof Array && elements[0] instanceof p5.Element ) {\r\n elt = elements.map(function(e) { return e.elt});\r\n }\r\n return StartAudioContext(audiocontext, elt, callback);\r\n };\r\n\r\n return audiocontext;\r\n});\r\n","define([\"Tone/core/Tone\"], function (Tone) {\n\n\t\"use strict\";\n\n\t/**\n\t * @class Tone.Emitter gives classes which extend it\n\t * the ability to listen for and emit events. \n\t * Inspiration and reference from Jerome Etienne's [MicroEvent](https://github.com/jeromeetienne/microevent.js).\n\t * MIT (c) 2011 Jerome Etienne.\n\t * \n\t * @extends {Tone}\n\t */\n\tTone.Emitter = function(){\n\t\t/**\n\t\t * Contains all of the events.\n\t\t * @private\n\t\t * @type {Object}\n\t\t */\n\t\tthis._events = {};\n\t};\n\n\tTone.extend(Tone.Emitter);\n\n\t/**\n\t * Bind a callback to a specific event.\n\t * @param {String} event The name of the event to listen for.\n\t * @param {Function} callback The callback to invoke when the\n\t * event is emitted\n\t * @return {Tone.Emitter} this\n\t */\n\tTone.Emitter.prototype.on = function(event, callback){\n\t\t//split the event\n\t\tvar events = event.split(/\\W+/);\n\t\tfor (var i = 0; i < events.length; i++){\n\t\t\tvar eventName = events[i];\n\t\t\tif (!this._events.hasOwnProperty(eventName)){\n\t\t\t\tthis._events[eventName] = [];\n\t\t\t}\n\t\t\tthis._events[eventName].push(callback);\n\t\t}\n\t\treturn this;\n\t};\n\n\t/**\n\t * Remove the event listener.\n\t * @param {String} event The event to stop listening to.\n\t * @param {Function=} callback The callback which was bound to \n\t * the event with Tone.Emitter.on.\n\t * If no callback is given, all callbacks\n\t * events are removed.\n\t * @return {Tone.Emitter} this\n\t */\n\tTone.Emitter.prototype.off = function(event, callback){\n\t\tvar events = event.split(/\\W+/);\n\t\tfor (var ev = 0; ev < events.length; ev++){\n\t\t\tevent = events[ev];\n\t\t\tif (this._events.hasOwnProperty(event)){\n\t\t\t\tif (Tone.prototype.isUndef(callback)){\n\t\t\t\t\tthis._events[event] = [];\n\t\t\t\t} else {\n\t\t\t\t\tvar eventList = this._events[event];\n\t\t\t\t\tfor (var i = 0; i < eventList.length; i++){\n\t\t\t\t\t\tif (eventList[i] === callback){\n\t\t\t\t\t\t\teventList.splice(i, 1);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\treturn this;\n\t};\n\n\t/**\n\t * Invoke all of the callbacks bound to the event\n\t * with any arguments passed in. \n\t * @param {String} event The name of the event.\n\t * @param {*...} args The arguments to pass to the functions listening.\n\t * @return {Tone.Emitter} this\n\t */\n\tTone.Emitter.prototype.emit = function(event){\n\t\tif (this._events){\n\t\t\tvar args = Array.apply(null, arguments).slice(1);\n\t\t\tif (this._events.hasOwnProperty(event)){\n\t\t\t\tvar eventList = this._events[event];\n\t\t\t\tfor (var i = 0, len = eventList.length; i < len; i++){\n\t\t\t\t\teventList[i].apply(this, args);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\treturn this;\n\t};\n\n\t/**\n\t * Add Emitter functions (on/off/emit) to the object\n\t * @param {Object|Function} object The object or class to extend.\n\t */\n\tTone.Emitter.mixin = function(object){\n\t\tvar functions = [\"on\", \"off\", \"emit\"];\n\t\tobject._events = {};\n\t\tfor (var i = 0; i < functions.length; i++){\n\t\t\tvar func = functions[i];\n\t\t\tvar emitterFunc = Tone.Emitter.prototype[func];\n\t\t\tobject[func] = emitterFunc;\n\t\t}\n\t};\n\n\t/**\n\t * Clean up\n\t * @return {Tone.Emitter} this\n\t */\n\tTone.Emitter.prototype.dispose = function(){\n\t\tTone.prototype.dispose.call(this);\n\t\tthis._events = null;\n\t\treturn this;\n\t};\n\n\treturn Tone.Emitter;\n});","module.exports = {\r\n recorderProcessor: 'recorder-processor',\r\n soundFileProcessor: 'sound-file-processor',\r\n amplitudeProcessor: 'amplitude-processor'\r\n};\r\n","define([\"Tone/core/Tone\"], function(Tone){\n\n\t\"use strict\";\n\n\t/**\n\t * @class Base class for all Signals. Used Internally. \n\t *\n\t * @constructor\n\t * @extends {Tone}\n\t */\n\tTone.SignalBase = function(){};\n\n\tTone.extend(Tone.SignalBase);\n\n\t/**\n\t * When signals connect to other signals or AudioParams, \n\t * they take over the output value of that signal or AudioParam. \n\t * For all other nodes, the behavior is the same as a default connect. \n\t *\n\t * @override\n\t * @param {AudioParam|AudioNode|Tone.Signal|Tone} node \n\t * @param {number} [outputNumber=0] The output number to connect from.\n\t * @param {number} [inputNumber=0] The input number to connect to.\n\t * @returns {Tone.SignalBase} this\n\t */\n\tTone.SignalBase.prototype.connect = function(node, outputNumber, inputNumber){\n\t\t//zero it out so that the signal can have full control\n\t\tif ((Tone.Signal && Tone.Signal === node.constructor) || \n\t\t\t\t(Tone.Param && Tone.Param === node.constructor) || \n\t\t\t\t(Tone.TimelineSignal && Tone.TimelineSignal === node.constructor)){\n\t\t\t//cancel changes\n\t\t\tnode._param.cancelScheduledValues(0);\n\t\t\t//reset the value\n\t\t\tnode._param.value = 0;\n\t\t\t//mark the value as overridden\n\t\t\tnode.overridden = true;\n\t\t} else if (node instanceof AudioParam){\n\t\t\tnode.cancelScheduledValues(0);\n\t\t\tnode.value = 0;\n\t\t} \n\t\tTone.prototype.connect.call(this, node, outputNumber, inputNumber);\n\t\treturn this;\n\t};\n\n\treturn Tone.SignalBase;\n});","define([\"Tone/core/Tone\", \"Tone/type/TimeBase\"], function (Tone) {\n\n\t/**\n\t * @class Tone.Time is a primitive type for encoding Time values. \n\t * Eventually all time values are evaluated to seconds\n\t * using the `eval` method. Tone.Time can be constructed\n\t * with or without the `new` keyword. Tone.Time can be passed\n\t * into the parameter of any method which takes time as an argument. \n\t * @constructor\n\t * @extends {Tone.TimeBase}\n\t * @param {String|Number} val The time value.\n\t * @param {String=} units The units of the value.\n\t * @example\n\t * var t = Tone.Time(\"4n\");//encodes a quarter note\n\t * t.mult(4); // multiply that value by 4\n\t * t.toNotation(); //returns \"1m\"\n\t */\n\tTone.Time = function(val, units){\n\t\tif (this instanceof Tone.Time){\n\n\t\t\t/**\n\t\t\t * If the current clock time should\n\t\t\t * be added to the output\n\t\t\t * @type {Boolean}\n\t\t\t * @private\n\t\t\t */\n\t\t\tthis._plusNow = false;\n\t\t\t\n\t\t\tTone.TimeBase.call(this, val, units);\n\n\t\t} else {\n\t\t\treturn new Tone.Time(val, units);\n\t\t}\n\t};\n\n\tTone.extend(Tone.Time, Tone.TimeBase);\n\n\t//clone the expressions so that \n\t//we can add more without modifying the original\n\tTone.Time.prototype._unaryExpressions = Object.create(Tone.TimeBase.prototype._unaryExpressions);\n\n\t/*\n\t * Adds an additional unary expression\n\t * which quantizes values to the next subdivision\n\t * @type {Object}\n\t * @private\n\t */\n\tTone.Time.prototype._unaryExpressions.quantize = {\n\t\tregexp : /^@/,\n\t\tmethod : function(rh){\n\t\t\treturn Tone.Transport.nextSubdivision(rh());\n\t\t}\n\t};\n\n\t/*\n\t * Adds an additional unary expression\n\t * which adds the current clock time.\n\t * @type {Object}\n\t * @private\n\t */\n\tTone.Time.prototype._unaryExpressions.now = {\n\t\tregexp : /^\\+/,\n\t\tmethod : function(lh){\n\t\t\tthis._plusNow = true;\n\t\t\treturn lh();\n\t\t}\n\t};\n\n\t/**\n\t * Quantize the time by the given subdivision. Optionally add a\n\t * percentage which will move the time value towards the ideal\n\t * quantized value by that percentage. \n\t * @param {Number|Time} val The subdivision to quantize to\n\t * @param {NormalRange} [percent=1] Move the time value\n\t * towards the quantized value by\n\t * a percentage.\n\t * @return {Tone.Time} this\n\t * @example\n\t * Tone.Time(21).quantize(2) //returns 22\n\t * Tone.Time(0.6).quantize(\"4n\", 0.5) //returns 0.55\n\t */\n\tTone.Time.prototype.quantize = function(subdiv, percent){\n\t\tpercent = this.defaultArg(percent, 1);\n\t\tthis._expr = function(expr, subdivision, percent){\n\t\t\texpr = expr();\n\t\t\tsubdivision = subdivision.toSeconds();\n\t\t\tvar multiple = Math.round(expr / subdivision);\n\t\t\tvar ideal = multiple * subdivision;\n\t\t\tvar diff = ideal - expr;\n\t\t\treturn expr + diff * percent;\n\t\t}.bind(this, this._expr, new this.constructor(subdiv), percent);\n\t\treturn this;\n\t};\n\n\t/**\n\t * Adds the clock time to the time expression at the \n\t * moment of evaluation. \n\t * @return {Tone.Time} this\n\t */\n\tTone.Time.prototype.addNow = function(){\n\t\tthis._plusNow = true;\n\t\treturn this;\n\t};\n\n\t/**\n\t * @override\n\t * Override the default value return when no arguments are passed in.\n\t * The default value is 'now'\n\t * @private\n\t */\n\tTone.Time.prototype._defaultExpr = function(){\n\t\tthis._plusNow = true;\n\t\treturn this._noOp;\n\t};\n\n\t/**\n\t * Copies the value of time to this Time\n\t * @param {Tone.Time} time\n\t * @return {Time}\n\t */\n\tTone.Time.prototype.copy = function(time){\n\t\tTone.TimeBase.prototype.copy.call(this, time);\n\t\tthis._plusNow = time._plusNow;\n\t\treturn this;\n\t};\n\n\t//CONVERSIONS//////////////////////////////////////////////////////////////\n\n\t/**\n\t * Convert a Time to Notation. Values will be thresholded to the nearest 128th note. \n\t * @return {Notation} \n\t * @example\n\t * //if the Transport is at 120bpm:\n\t * Tone.Time(2).toNotation();//returns \"1m\"\n\t */\n\tTone.Time.prototype.toNotation = function(){\n\t\tvar time = this.toSeconds();\n\t\tvar testNotations = [\"1m\", \"2n\", \"4n\", \"8n\", \"16n\", \"32n\", \"64n\", \"128n\"];\n\t\tvar retNotation = this._toNotationHelper(time, testNotations);\n\t\t//try the same thing but with tripelets\n\t\tvar testTripletNotations = [\"1m\", \"2n\", \"2t\", \"4n\", \"4t\", \"8n\", \"8t\", \"16n\", \"16t\", \"32n\", \"32t\", \"64n\", \"64t\", \"128n\"];\n\t\tvar retTripletNotation = this._toNotationHelper(time, testTripletNotations);\n\t\t//choose the simpler expression of the two\n\t\tif (retTripletNotation.split(\"+\").length < retNotation.split(\"+\").length){\n\t\t\treturn retTripletNotation;\n\t\t} else {\n\t\t\treturn retNotation;\n\t\t}\n\t};\n\n\t/**\n\t * Helper method for Tone.toNotation\n\t * @param {Number} units \n\t * @param {Array} testNotations\n\t * @return {String}\n\t * @private\n\t */\n\tTone.Time.prototype._toNotationHelper = function(units, testNotations){\n\t\t//the threshold is the last value in the array\n\t\tvar threshold = this._notationToUnits(testNotations[testNotations.length - 1]);\n\t\tvar retNotation = \"\";\n\t\tfor (var i = 0; i < testNotations.length; i++){\n\t\t\tvar notationTime = this._notationToUnits(testNotations[i]);\n\t\t\t//account for floating point errors (i.e. round up if the value is 0.999999)\n\t\t\tvar multiple = units / notationTime;\n\t\t\tvar floatingPointError = 0.000001;\n\t\t\tif (1 - multiple % 1 < floatingPointError){\n\t\t\t\tmultiple += floatingPointError;\n\t\t\t}\n\t\t\tmultiple = Math.floor(multiple);\n\t\t\tif (multiple > 0){\n\t\t\t\tif (multiple === 1){\n\t\t\t\t\tretNotation += testNotations[i];\n\t\t\t\t} else {\n\t\t\t\t\tretNotation += multiple.toString() + \"*\" + testNotations[i];\n\t\t\t\t}\n\t\t\t\tunits -= multiple * notationTime;\n\t\t\t\tif (units < threshold){\n\t\t\t\t\tbreak;\n\t\t\t\t} else {\n\t\t\t\t\tretNotation += \" + \";\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tif (retNotation === \"\"){\n\t\t\tretNotation = \"0\";\n\t\t}\n\t\treturn retNotation;\n\t};\n\n\t/**\n\t * Convert a notation value to the current units\n\t * @param {Notation} notation \n\t * @return {Number} \n\t * @private\n\t */\n\tTone.Time.prototype._notationToUnits = function(notation){\n\t\tvar primaryExprs = this._primaryExpressions;\n\t\tvar notationExprs = [primaryExprs.n, primaryExprs.t, primaryExprs.m];\n\t\tfor (var i = 0; i < notationExprs.length; i++){\n\t\t\tvar expr = notationExprs[i];\n\t\t\tvar match = notation.match(expr.regexp);\n\t\t\tif (match){\n\t\t\t\treturn expr.method.call(this, match[1]);\n\t\t\t}\n\t\t}\n\t};\n\n\t/**\n\t * Return the time encoded as Bars:Beats:Sixteenths.\n\t * @return {BarsBeatsSixteenths}\n\t */\n\tTone.Time.prototype.toBarsBeatsSixteenths = function(){\n\t\tvar quarterTime = this._beatsToUnits(1);\n\t\tvar quarters = this.toSeconds() / quarterTime;\n\t\tvar measures = Math.floor(quarters / this._timeSignature());\n\t\tvar sixteenths = (quarters % 1) * 4;\n\t\tquarters = Math.floor(quarters) % this._timeSignature();\n\t\tsixteenths = sixteenths.toString();\n\t\tif (sixteenths.length > 3){\n\t\t\tsixteenths = parseFloat(sixteenths).toFixed(3);\n\t\t}\n\t\tvar progress = [measures, quarters, sixteenths];\n\t\treturn progress.join(\":\");\n\t};\n\n\t/**\n\t * Return the time in ticks.\n\t * @return {Ticks}\n\t */\n\tTone.Time.prototype.toTicks = function(){\n\t\tvar quarterTime = this._beatsToUnits(1);\n\t\tvar quarters = this.valueOf() / quarterTime;\n\t\treturn Math.floor(quarters * Tone.Transport.PPQ);\n\t};\n\n\t/**\n\t * Return the time in samples\n\t * @return {Samples} \n\t */\n\tTone.Time.prototype.toSamples = function(){\n\t\treturn this.toSeconds() * this.context.sampleRate;\n\t};\n\n\t/**\n\t * Return the time as a frequency value\n\t * @return {Frequency} \n\t * @example\n\t * Tone.Time(2).toFrequency(); //0.5\n\t */\n\tTone.Time.prototype.toFrequency = function(){\n\t\treturn 1/this.toSeconds();\n\t};\n\n\t/**\n\t * Return the time in seconds.\n\t * @return {Seconds} \n\t */\n\tTone.Time.prototype.toSeconds = function(){\n\t\treturn this.valueOf();\n\t};\n\n\t/**\n\t * Return the time in milliseconds.\n\t * @return {Milliseconds} \n\t */\n\tTone.Time.prototype.toMilliseconds = function(){\n\t\treturn this.toSeconds() * 1000;\n\t};\n\n\t/**\n\t * Return the time in seconds.\n\t * @return {Seconds} \n\t */\n\tTone.Time.prototype.valueOf = function(){\n\t\tvar val = this._expr();\n\t\treturn val + (this._plusNow?this.now():0);\n\t};\n\n\treturn Tone.Time;\n});","define([\"Tone/core/Tone\"], function (Tone) {\n\n\t/**\n\t * @class Tone.TimeBase is a flexible encoding of time\n\t * which can be evaluated to and from a string.\n\t * Parsing code modified from https://code.google.com/p/tapdigit/\n\t * Copyright 2011 2012 Ariya Hidayat, New BSD License\n\t * @extends {Tone}\n\t * @param {Time} val The time value as a number or string\n\t * @param {String=} units Unit values\n\t * @example\n\t * Tone.TimeBase(4, \"n\")\n\t * Tone.TimeBase(2, \"t\")\n\t * Tone.TimeBase(\"2t\").add(\"1m\")\n\t * Tone.TimeBase(\"2t + 1m\");\n\t */\n\tTone.TimeBase = function(val, units){\n\n\t\t//allows it to be constructed with or without 'new'\n\t\tif (this instanceof Tone.TimeBase) {\n\n\t\t\t/**\n\t\t\t * Any expressions parsed from the Time\n\t\t\t * @type {Array}\n\t\t\t * @private\n\t\t\t */\n\t\t\tthis._expr = this._noOp;\n\n\t\t\tif (val instanceof Tone.TimeBase){\n\t\t\t\tthis.copy(val);\n\t\t\t} else if (!this.isUndef(units) || this.isNumber(val)){\n\t\t\t\t//default units\n\t\t\t\tunits = this.defaultArg(units, this._defaultUnits);\n\t\t\t\tvar method = this._primaryExpressions[units].method;\n\t\t\t\tthis._expr = method.bind(this, val);\n\t\t\t} else if (this.isString(val)){\n\t\t\t\tthis.set(val);\n\t\t\t} else if (this.isUndef(val)){\n\t\t\t\t//default expression\n\t\t\t\tthis._expr = this._defaultExpr();\n\t\t\t}\n\t\t} else {\n\n\t\t\treturn new Tone.TimeBase(val, units);\n\t\t}\n\t};\n\n\tTone.extend(Tone.TimeBase);\n\n\t/**\n\t * Repalce the current time value with the value\n\t * given by the expression string.\n\t * @param {String} exprString\n\t * @return {Tone.TimeBase} this\n\t */\n\tTone.TimeBase.prototype.set = function(exprString){\n\t\tthis._expr = this._parseExprString(exprString);\n\t\treturn this;\n\t};\n\n\t/**\n\t * Return a clone of the TimeBase object.\n\t * @return {Tone.TimeBase} The new cloned Tone.TimeBase\n\t */\n\tTone.TimeBase.prototype.clone = function(){\n\t\tvar instance = new this.constructor();\n\t\tinstance.copy(this);\n\t\treturn instance;\n\t};\n\n\t/**\n\t * Copies the value of time to this Time\n\t * @param {Tone.TimeBase} time\n\t * @return {TimeBase}\n\t */\n\tTone.TimeBase.prototype.copy = function(time){\n\t\tvar val = time._expr();\n\t\treturn this.set(val);\n\t};\n\n\t///////////////////////////////////////////////////////////////////////////\n\t//\tABSTRACT SYNTAX TREE PARSER\n\t///////////////////////////////////////////////////////////////////////////\n\n\t/**\n\t * All the primary expressions.\n\t * @private\n\t * @type {Object}\n\t */\n\tTone.TimeBase.prototype._primaryExpressions = {\n\t\t\"n\" : {\n\t\t\tregexp : /^(\\d+)n/i,\n\t\t\tmethod : function(value){\n\t\t\t\tvalue = parseInt(value);\n\t\t\t\tif (value === 1){\n\t\t\t\t\treturn this._beatsToUnits(this._timeSignature());\n\t\t\t\t} else {\n\t\t\t\t\treturn this._beatsToUnits(4 / value);\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\t\t\"t\" : {\n\t\t\tregexp : /^(\\d+)t/i,\n\t\t\tmethod : function(value){\n\t\t\t\tvalue = parseInt(value);\n\t\t\t\treturn this._beatsToUnits(8 / (parseInt(value) * 3));\n\t\t\t}\n\t\t},\n\t\t\"m\" : {\n\t\t\tregexp : /^(\\d+)m/i,\n\t\t\tmethod : function(value){\n\t\t\t\treturn this._beatsToUnits(parseInt(value) * this._timeSignature());\n\t\t\t}\n\t\t},\n\t\t\"i\" : {\n\t\t\tregexp : /^(\\d+)i/i,\n\t\t\tmethod : function(value){\n\t\t\t\treturn this._ticksToUnits(parseInt(value));\n\t\t\t}\n\t\t},\n\t\t\"hz\" : {\n\t\t\tregexp : /^(\\d+(?:\\.\\d+)?)hz/i,\n\t\t\tmethod : function(value){\n\t\t\t\treturn this._frequencyToUnits(parseFloat(value));\n\t\t\t}\n\t\t},\n\t\t\"tr\" : {\n\t\t\tregexp : /^(\\d+(?:\\.\\d+)?):(\\d+(?:\\.\\d+)?):?(\\d+(?:\\.\\d+)?)?/,\n\t\t\tmethod : function(m, q, s){\n\t\t\t\tvar total = 0;\n\t\t\t\tif (m && m !== \"0\"){\n\t\t\t\t\ttotal += this._beatsToUnits(this._timeSignature() * parseFloat(m));\n\t\t\t\t}\n\t\t\t\tif (q && q !== \"0\"){\n\t\t\t\t\ttotal += this._beatsToUnits(parseFloat(q));\n\t\t\t\t}\n\t\t\t\tif (s && s !== \"0\"){\n\t\t\t\t\ttotal += this._beatsToUnits(parseFloat(s) / 4);\n\t\t\t\t}\n\t\t\t\treturn total;\n\t\t\t}\n\t\t},\n\t\t\"s\" : {\n\t\t\tregexp : /^(\\d+(?:\\.\\d+)?s)/,\n\t\t\tmethod : function(value){\n\t\t\t\treturn this._secondsToUnits(parseFloat(value));\n\t\t\t}\n\t\t},\n\t\t\"samples\" : {\n\t\t\tregexp : /^(\\d+)samples/,\n\t\t\tmethod : function(value){\n\t\t\t\treturn parseInt(value) / this.context.sampleRate;\n\t\t\t}\n\t\t},\n\t\t\"default\" : {\n\t\t\tregexp : /^(\\d+(?:\\.\\d+)?)/,\n\t\t\tmethod : function(value){\n\t\t\t\treturn this._primaryExpressions[this._defaultUnits].method.call(this, value);\n\t\t\t}\n\t\t}\n\t};\n\n\t/**\n\t * All the binary expressions that TimeBase can accept.\n\t * @private\n\t * @type {Object}\n\t */\n\tTone.TimeBase.prototype._binaryExpressions = {\n\t\t\"+\" : {\n\t\t\tregexp : /^\\+/,\n\t\t\tprecedence : 2,\n\t\t\tmethod : function(lh, rh){\n\t\t\t\treturn lh() + rh();\n\t\t\t}\n\t\t},\n\t\t\"-\" : {\n\t\t\tregexp : /^\\-/,\n\t\t\tprecedence : 2,\n\t\t\tmethod : function(lh, rh){\n\t\t\t\treturn lh() - rh();\n\t\t\t}\n\t\t},\n\t\t\"*\" : {\n\t\t\tregexp : /^\\*/,\n\t\t\tprecedence : 1,\n\t\t\tmethod : function(lh, rh){\n\t\t\t\treturn lh() * rh();\n\t\t\t}\n\t\t},\n\t\t\"/\" : {\n\t\t\tregexp : /^\\//,\n\t\t\tprecedence : 1,\n\t\t\tmethod : function(lh, rh){\n\t\t\t\treturn lh() / rh();\n\t\t\t}\n\t\t}\n\t};\n\n\t/**\n\t * All the unary expressions.\n\t * @private\n\t * @type {Object}\n\t */\n\tTone.TimeBase.prototype._unaryExpressions = {\n\t\t\"neg\" : {\n\t\t\tregexp : /^\\-/,\n\t\t\tmethod : function(lh){\n\t\t\t\treturn -lh();\n\t\t\t}\n\t\t}\n\t};\n\n\t/**\n\t * Syntactic glue which holds expressions together\n\t * @private\n\t * @type {Object}\n\t */\n\tTone.TimeBase.prototype._syntaxGlue = {\n\t\t\"(\" : {\n\t\t\tregexp : /^\\(/\n\t\t},\n\t\t\")\" : {\n\t\t\tregexp : /^\\)/\n\t\t}\n\t};\n\n\t/**\n\t * tokenize the expression based on the Expressions object\n\t * @param {string} expr \n\t * @return {Object} returns two methods on the tokenized list, next and peek\n\t * @private\n\t */\n\tTone.TimeBase.prototype._tokenize = function(expr){\n\t\tvar position = -1;\n\t\tvar tokens = [];\n\n\t\twhile(expr.length > 0){\n\t\t\texpr = expr.trim();\n\t\t\tvar token = getNextToken(expr, this);\n\t\t\ttokens.push(token);\n\t\t\texpr = expr.substr(token.value.length);\n\t\t}\n\n\t\tfunction getNextToken(expr, context){\n\t\t\tvar expressions = [\"_binaryExpressions\", \"_unaryExpressions\", \"_primaryExpressions\", \"_syntaxGlue\"];\n\t\t\tfor (var i = 0; i < expressions.length; i++){\n\t\t\t\tvar group = context[expressions[i]];\n\t\t\t\tfor (var opName in group){\n\t\t\t\t\tvar op = group[opName];\n\t\t\t\t\tvar reg = op.regexp;\n\t\t\t\t\tvar match = expr.match(reg);\n\t\t\t\t\tif (match !== null){\n\t\t\t\t\t\treturn {\n\t\t\t\t\t\t\tmethod : op.method,\n\t\t\t\t\t\t\tprecedence : op.precedence,\n\t\t\t\t\t\t\tregexp : op.regexp,\n\t\t\t\t\t\t\tvalue : match[0],\n\t\t\t\t\t\t};\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\tthrow new SyntaxError(\"Tone.TimeBase: Unexpected token \"+expr);\n\t\t}\n\n\t\treturn {\n\t\t\tnext : function(){\n\t\t\t\treturn tokens[++position];\n\t\t\t},\n\t\t\tpeek : function(){\n\t\t\t\treturn tokens[position + 1];\n\t\t\t}\n\t\t};\n\t};\n\n\t/**\n\t * Given a token, find the value within the groupName\n\t * @param {Object} token\n\t * @param {String} groupName\n\t * @param {Number} precedence\n\t * @private\n\t */\n\tTone.TimeBase.prototype._matchGroup = function(token, group, prec) {\n\t\tvar ret = false;\n\t\tif (!this.isUndef(token)){\n\t\t\tfor (var opName in group){\n\t\t\t\tvar op = group[opName];\n\t\t\t\tif (op.regexp.test(token.value)){\n\t\t\t\t\tif (!this.isUndef(prec)){\n\t\t\t\t\t\tif(op.precedence === prec){\t\n\t\t\t\t\t\t\treturn op;\n\t\t\t\t\t\t}\n\t\t\t\t\t} else {\n\t\t\t\t\t\treturn op;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\treturn ret;\n\t};\n\n\t/**\n\t * Match a binary expression given the token and the precedence\n\t * @param {Lexer} lexer\n\t * @param {Number} precedence\n\t * @private\n\t */\n\tTone.TimeBase.prototype._parseBinary = function(lexer, precedence){\n\t\tif (this.isUndef(precedence)){\n\t\t\tprecedence = 2;\n\t\t}\n\t\tvar expr;\n\t\tif (precedence < 0){\n\t\t\texpr = this._parseUnary(lexer);\n\t\t} else {\n\t\t\texpr = this._parseBinary(lexer, precedence - 1);\n\t\t}\n\t\tvar token = lexer.peek();\n\t\twhile (token && this._matchGroup(token, this._binaryExpressions, precedence)){\n\t\t\ttoken = lexer.next();\n\t\t\texpr = token.method.bind(this, expr, this._parseBinary(lexer, precedence - 1));\n\t\t\ttoken = lexer.peek();\n\t\t}\n\t\treturn expr;\n\t};\n\n\t/**\n\t * Match a unary expression.\n\t * @param {Lexer} lexer\n\t * @private\n\t */\n\tTone.TimeBase.prototype._parseUnary = function(lexer){\n\t\tvar token, expr;\n\t\ttoken = lexer.peek();\n\t\tvar op = this._matchGroup(token, this._unaryExpressions);\n\t\tif (op) {\n\t\t\ttoken = lexer.next();\n\t\t\texpr = this._parseUnary(lexer);\n\t\t\treturn op.method.bind(this, expr);\n\t\t}\n\t\treturn this._parsePrimary(lexer);\n\t};\n\n\t/**\n\t * Match a primary expression (a value).\n\t * @param {Lexer} lexer\n\t * @private\n\t */\n\tTone.TimeBase.prototype._parsePrimary = function(lexer){\n\t\tvar token, expr;\n\t\ttoken = lexer.peek();\n\t\tif (this.isUndef(token)) {\n\t\t\tthrow new SyntaxError(\"Tone.TimeBase: Unexpected end of expression\");\n\t\t}\n\t\tif (this._matchGroup(token, this._primaryExpressions)) {\n\t\t\ttoken = lexer.next();\n\t\t\tvar matching = token.value.match(token.regexp);\n\t\t\treturn token.method.bind(this, matching[1], matching[2], matching[3]);\n\t\t}\n\t\tif (token && token.value === \"(\"){\n\t\t\tlexer.next();\n\t\t\texpr = this._parseBinary(lexer);\n\t\t\ttoken = lexer.next();\n\t\t\tif (!(token && token.value === \")\")) {\n\t\t\t\tthrow new SyntaxError(\"Expected )\");\n\t\t\t}\n\t\t\treturn expr;\n\t\t}\n\t\tthrow new SyntaxError(\"Tone.TimeBase: Cannot process token \" + token.value);\n\t};\n\n\t/**\n\t * Recursively parse the string expression into a syntax tree.\n\t * @param {string} expr \n\t * @return {Function} the bound method to be evaluated later\n\t * @private\n\t */\n\tTone.TimeBase.prototype._parseExprString = function(exprString){\n\t\tif (!this.isString(exprString)){\n\t\t\texprString = exprString.toString();\n\t\t}\n\t\tvar lexer = this._tokenize(exprString);\n\t\tvar tree = this._parseBinary(lexer);\n\t\treturn tree;\n\t};\n\n\t///////////////////////////////////////////////////////////////////////////\n\t//\tDEFAULTS\n\t///////////////////////////////////////////////////////////////////////////\n\n\t/**\n\t * The initial expression value\n\t * @return {Number} The initial value 0\n\t * @private\n\t */\n\tTone.TimeBase.prototype._noOp = function(){\n\t\treturn 0;\n\t};\n\n\t/**\n\t * The default expression value if no arguments are given\n\t * @private\n\t */\n\tTone.TimeBase.prototype._defaultExpr = function(){\n\t\treturn this._noOp;\n\t};\n\n\t/**\n\t * The default units if none are given.\n\t * @private\n\t */\n\tTone.TimeBase.prototype._defaultUnits = \"s\";\n\n\t///////////////////////////////////////////////////////////////////////////\n\t//\tUNIT CONVERSIONS\n\t///////////////////////////////////////////////////////////////////////////\n\n\t/**\n\t * Returns the value of a frequency in the current units\n\t * @param {Frequency} freq\n\t * @return {Number}\n\t * @private\n\t */\n\tTone.TimeBase.prototype._frequencyToUnits = function(freq){\n\t\treturn 1/freq;\n\t};\n\n\t/**\n\t * Return the value of the beats in the current units\n\t * @param {Number} beats\n\t * @return {Number}\n\t * @private\n\t */\n\tTone.TimeBase.prototype._beatsToUnits = function(beats){\n\t\treturn (60 / Tone.Transport.bpm.value) * beats;\n\t};\n\n\t/**\n\t * Returns the value of a second in the current units\n\t * @param {Seconds} seconds\n\t * @return {Number}\n\t * @private\n\t */\n\tTone.TimeBase.prototype._secondsToUnits = function(seconds){\n\t\treturn seconds;\n\t};\n\n\t/**\n\t * Returns the value of a tick in the current time units\n\t * @param {Ticks} ticks\n\t * @return {Number}\n\t * @private\n\t */\n\tTone.TimeBase.prototype._ticksToUnits = function(ticks){\n\t\treturn ticks * (this._beatsToUnits(1) / Tone.Transport.PPQ);\n\t};\n\n\t/**\n\t * Return the time signature.\n\t * @return {Number}\n\t * @private\n\t */\n\tTone.TimeBase.prototype._timeSignature = function(){\n\t\treturn Tone.Transport.timeSignature;\n\t};\n\n\t///////////////////////////////////////////////////////////////////////////\n\t//\tEXPRESSIONS\n\t///////////////////////////////////////////////////////////////////////////\n\n\t/**\n\t * Push an expression onto the expression list\n\t * @param {Time} val\n\t * @param {String} type\n\t * @param {String} units\n\t * @return {Tone.TimeBase} \n\t * @private\n\t */\n\tTone.TimeBase.prototype._pushExpr = function(val, name, units){\n\t\t//create the expression\n\t\tif (!(val instanceof Tone.TimeBase)){\n\t\t\tval = new this.constructor(val, units);\n\t\t}\n\t\tthis._expr = this._binaryExpressions[name].method.bind(this, this._expr, val._expr);\n\t\treturn this;\n\t};\n\n\t/**\n\t * Add to the current value.\n\t * @param {Time} val The value to add\n\t * @param {String=} units Optional units to use with the value.\n\t * @return {Tone.TimeBase} this\n\t * @example\n\t * Tone.TimeBase(\"2m\").add(\"1m\"); //\"3m\"\n\t */\n\tTone.TimeBase.prototype.add = function(val, units){\n\t\treturn this._pushExpr(val, \"+\", units);\n\t};\n\n\t/**\n\t * Subtract the value from the current time.\n\t * @param {Time} val The value to subtract\n\t * @param {String=} units Optional units to use with the value.\n\t * @return {Tone.TimeBase} this\n\t * @example\n\t * Tone.TimeBase(\"2m\").sub(\"1m\"); //\"1m\"\n\t */\n\tTone.TimeBase.prototype.sub = function(val, units){\n\t\treturn this._pushExpr(val, \"-\", units);\n\t};\n\n\t/**\n\t * Multiply the current value by the given time.\n\t * @param {Time} val The value to multiply\n\t * @param {String=} units Optional units to use with the value.\n\t * @return {Tone.TimeBase} this\n\t * @example\n\t * Tone.TimeBase(\"2m\").mult(\"2\"); //\"4m\"\n\t */\n\tTone.TimeBase.prototype.mult = function(val, units){\n\t\treturn this._pushExpr(val, \"*\", units);\n\t};\n\n\t/**\n\t * Divide the current value by the given time.\n\t * @param {Time} val The value to divide by\n\t * @param {String=} units Optional units to use with the value.\n\t * @return {Tone.TimeBase} this\n\t * @example\n\t * Tone.TimeBase(\"2m\").div(2); //\"1m\"\n\t */\n\tTone.TimeBase.prototype.div = function(val, units){\n\t\treturn this._pushExpr(val, \"/\", units);\n\t};\n\n\t/**\n\t * Evaluate the time value. Returns the time\n\t * in seconds.\n\t * @return {Seconds} \n\t */\n\tTone.TimeBase.prototype.valueOf = function(){\n\t\treturn this._expr();\n\t};\n\n\t/**\n\t * Clean up\n\t * @return {Tone.TimeBase} this\n\t */\n\tTone.TimeBase.prototype.dispose = function(){\n\t\tthis._expr = null;\n\t};\n\n\treturn Tone.TimeBase;\n});","define([\"Tone/core/Tone\", \"Tone/type/Type\"], function(Tone){\n\n\t\"use strict\";\n\n\t/**\n\t * @class Tone.Param wraps the native Web Audio's AudioParam to provide\n\t * additional unit conversion functionality. It also\n\t * serves as a base-class for classes which have a single,\n\t * automatable parameter. \n\t * @extends {Tone}\n\t * @param {AudioParam} param The parameter to wrap.\n\t * @param {Tone.Type} units The units of the audio param.\n\t * @param {Boolean} convert If the param should be converted.\n\t */\n\tTone.Param = function(){\n\n\t\tvar options = this.optionsObject(arguments, [\"param\", \"units\", \"convert\"], Tone.Param.defaults);\n\n\t\t/**\n\t\t * The native parameter to control\n\t\t * @type {AudioParam}\n\t\t * @private\n\t\t */\n\t\tthis._param = this.input = options.param;\n\n\t\t/**\n\t\t * The units of the parameter\n\t\t * @type {Tone.Type}\n\t\t */\n\t\tthis.units = options.units;\n\n\t\t/**\n\t\t * If the value should be converted or not\n\t\t * @type {Boolean}\n\t\t */\n\t\tthis.convert = options.convert;\n\n\t\t/**\n\t\t * True if the signal value is being overridden by \n\t\t * a connected signal.\n\t\t * @readOnly\n\t\t * @type {boolean}\n\t\t * @private\n\t\t */\n\t\tthis.overridden = false;\n\n\t\t/**\n\t\t * If there is an LFO, this is where it is held.\n\t\t * @type {Tone.LFO}\n\t\t * @private\n\t\t */\n\t\tthis._lfo = null;\n\n\t\tif (this.isObject(options.lfo)){\n\t\t\tthis.value = options.lfo;\n\t\t} else if (!this.isUndef(options.value)){\n\t\t\tthis.value = options.value;\n\t\t}\n\t};\n\n\tTone.extend(Tone.Param);\n\t\n\t/**\n\t * Defaults\n\t * @type {Object}\n\t * @const\n\t */\n\tTone.Param.defaults = {\n\t\t\"units\" : Tone.Type.Default,\n\t\t\"convert\" : true,\n\t\t\"param\" : undefined\n\t};\n\n\t/**\n\t * The current value of the parameter. \n\t * @memberOf Tone.Param#\n\t * @type {Number}\n\t * @name value\n\t */\n\tObject.defineProperty(Tone.Param.prototype, \"value\", {\n\t\tget : function(){\n\t\t\treturn this._toUnits(this._param.value);\n\t\t},\n\t\tset : function(value){\n\t\t\tif (this.isObject(value)){\n\t\t\t\t//throw an error if the LFO needs to be included\n\t\t\t\tif (this.isUndef(Tone.LFO)){\n\t\t\t\t\tthrow new Error(\"Include 'Tone.LFO' to use an LFO as a Param value.\");\n\t\t\t\t}\n\t\t\t\t//remove the old one\n\t\t\t\tif (this._lfo){\n\t\t\t\t\tthis._lfo.dispose();\n\t\t\t\t}\n\t\t\t\tthis._lfo = new Tone.LFO(value).start();\n\t\t\t\tthis._lfo.connect(this.input);\n\t\t\t} else {\n\t\t\t\tvar convertedVal = this._fromUnits(value);\n\t\t\t\tthis._param.cancelScheduledValues(0);\n\t\t\t\tthis._param.value = convertedVal;\n\t\t\t}\n\t\t}\n\t});\n\n\t/**\n\t * Convert the given value from the type specified by Tone.Param.units\n\t * into the destination value (such as Gain or Frequency).\n\t * @private\n\t * @param {*} val the value to convert\n\t * @return {number} the number which the value should be set to\n\t */\n\tTone.Param.prototype._fromUnits = function(val){\n\t\tif (this.convert || this.isUndef(this.convert)){\n\t\t\tswitch(this.units){\n\t\t\t\tcase Tone.Type.Time: \n\t\t\t\t\treturn this.toSeconds(val);\n\t\t\t\tcase Tone.Type.Frequency: \n\t\t\t\t\treturn this.toFrequency(val);\n\t\t\t\tcase Tone.Type.Decibels: \n\t\t\t\t\treturn this.dbToGain(val);\n\t\t\t\tcase Tone.Type.NormalRange: \n\t\t\t\t\treturn Math.min(Math.max(val, 0), 1);\n\t\t\t\tcase Tone.Type.AudioRange: \n\t\t\t\t\treturn Math.min(Math.max(val, -1), 1);\n\t\t\t\tcase Tone.Type.Positive: \n\t\t\t\t\treturn Math.max(val, 0);\n\t\t\t\tdefault:\n\t\t\t\t\treturn val;\n\t\t\t}\n\t\t} else {\n\t\t\treturn val;\n\t\t}\n\t};\n\n\t/**\n\t * Convert the parameters value into the units specified by Tone.Param.units.\n\t * @private\n\t * @param {number} val the value to convert\n\t * @return {number}\n\t */\n\tTone.Param.prototype._toUnits = function(val){\n\t\tif (this.convert || this.isUndef(this.convert)){\n\t\t\tswitch(this.units){\n\t\t\t\tcase Tone.Type.Decibels: \n\t\t\t\t\treturn this.gainToDb(val);\n\t\t\t\tdefault:\n\t\t\t\t\treturn val;\n\t\t\t}\n\t\t} else {\n\t\t\treturn val;\n\t\t}\n\t};\n\n\t/**\n\t * the minimum output value\n\t * @type {Number}\n\t * @private\n\t */\n\tTone.Param.prototype._minOutput = 0.00001;\n\n\t/**\n\t * Schedules a parameter value change at the given time.\n\t * @param {*}\tvalue The value to set the signal.\n\t * @param {Time} time The time when the change should occur.\n\t * @returns {Tone.Param} this\n\t * @example\n\t * //set the frequency to \"G4\" in exactly 1 second from now. \n\t * freq.setValueAtTime(\"G4\", \"+1\");\n\t */\n\tTone.Param.prototype.setValueAtTime = function(value, time){\n\t\tvalue = this._fromUnits(value);\n\t\ttime = this.toSeconds(time);\n\t\tif (time <= this.now() + this.blockTime){\n\t\t\tthis._param.value = value;\n\t\t} else {\n\t\t\tthis._param.setValueAtTime(value, time);\n\t\t}\n\t\treturn this;\n\t};\n\n\t/**\n\t * Creates a schedule point with the current value at the current time.\n\t * This is useful for creating an automation anchor point in order to \n\t * schedule changes from the current value. \n\t *\n\t * @param {number=} now (Optionally) pass the now value in. \n\t * @returns {Tone.Param} this\n\t */\n\tTone.Param.prototype.setRampPoint = function(now){\n\t\tnow = this.defaultArg(now, this.now());\n\t\tvar currentVal = this._param.value;\n\t\t// exponentialRampToValueAt cannot ever ramp from or to 0\n\t\t// More info: https://bugzilla.mozilla.org/show_bug.cgi?id=1125600#c2\n\t\tif (currentVal === 0){\n\t\t\tcurrentVal = this._minOutput;\n\t\t}\n\t\tthis._param.setValueAtTime(currentVal, now);\n\t\treturn this;\n\t};\n\n\t/**\n\t * Schedules a linear continuous change in parameter value from the \n\t * previous scheduled parameter value to the given value.\n\t * \n\t * @param {number} value \n\t * @param {Time} endTime \n\t * @returns {Tone.Param} this\n\t */\n\tTone.Param.prototype.linearRampToValueAtTime = function(value, endTime){\n\t\tvalue = this._fromUnits(value);\n\t\tthis._param.linearRampToValueAtTime(value, this.toSeconds(endTime));\n\t\treturn this;\n\t};\n\n\t/**\n\t * Schedules an exponential continuous change in parameter value from \n\t * the previous scheduled parameter value to the given value.\n\t * \n\t * @param {number} value \n\t * @param {Time} endTime \n\t * @returns {Tone.Param} this\n\t */\n\tTone.Param.prototype.exponentialRampToValueAtTime = function(value, endTime){\n\t\tvalue = this._fromUnits(value);\n\t\tvalue = Math.max(this._minOutput, value);\n\t\tthis._param.exponentialRampToValueAtTime(value, this.toSeconds(endTime));\n\t\treturn this;\n\t};\n\n\t/**\n\t * Schedules an exponential continuous change in parameter value from \n\t * the current time and current value to the given value over the \n\t * duration of the rampTime.\n\t * \n\t * @param {number} value The value to ramp to.\n\t * @param {Time} rampTime the time that it takes the \n\t * value to ramp from it's current value\n\t * @param {Time}\t[startTime=now] \tWhen the ramp should start. \n\t * @returns {Tone.Param} this\n\t * @example\n\t * //exponentially ramp to the value 2 over 4 seconds. \n\t * signal.exponentialRampToValue(2, 4);\n\t */\n\tTone.Param.prototype.exponentialRampToValue = function(value, rampTime, startTime){\n\t\tstartTime = this.toSeconds(startTime);\n\t\tthis.setRampPoint(startTime);\n\t\tthis.exponentialRampToValueAtTime(value, startTime + this.toSeconds(rampTime));\n\t\treturn this;\n\t};\n\n\t/**\n\t * Schedules an linear continuous change in parameter value from \n\t * the current time and current value to the given value over the \n\t * duration of the rampTime.\n\t * \n\t * @param {number} value The value to ramp to.\n\t * @param {Time} rampTime the time that it takes the \n\t * value to ramp from it's current value\n\t * @param {Time}\t[startTime=now] \tWhen the ramp should start. \n\t * @returns {Tone.Param} this\n\t * @example\n\t * //linearly ramp to the value 4 over 3 seconds. \n\t * signal.linearRampToValue(4, 3);\n\t */\n\tTone.Param.prototype.linearRampToValue = function(value, rampTime, startTime){\n\t\tstartTime = this.toSeconds(startTime);\n\t\tthis.setRampPoint(startTime);\n\t\tthis.linearRampToValueAtTime(value, startTime + this.toSeconds(rampTime));\n\t\treturn this;\n\t};\n\n\t/**\n\t * Start exponentially approaching the target value at the given time with\n\t * a rate having the given time constant.\n\t * @param {number} value \n\t * @param {Time} startTime \n\t * @param {number} timeConstant \n\t * @returns {Tone.Param} this \n\t */\n\tTone.Param.prototype.setTargetAtTime = function(value, startTime, timeConstant){\n\t\tvalue = this._fromUnits(value);\n\t\t// The value will never be able to approach without timeConstant > 0.\n\t\t// http://www.w3.org/TR/webaudio/#dfn-setTargetAtTime, where the equation\n\t\t// is described. 0 results in a division by 0.\n\t\tvalue = Math.max(this._minOutput, value);\n\t\ttimeConstant = Math.max(this._minOutput, timeConstant);\n\t\tthis._param.setTargetAtTime(value, this.toSeconds(startTime), timeConstant);\n\t\treturn this;\n\t};\n\n\t/**\n\t * Sets an array of arbitrary parameter values starting at the given time\n\t * for the given duration.\n\t * \t\n\t * @param {Array} values \n\t * @param {Time} startTime \n\t * @param {Time} duration \n\t * @returns {Tone.Param} this\n\t */\n\tTone.Param.prototype.setValueCurveAtTime = function(values, startTime, duration){\n\t\tfor (var i = 0; i < values.length; i++){\n\t\t\tvalues[i] = this._fromUnits(values[i]);\n\t\t}\n\t\tthis._param.setValueCurveAtTime(values, this.toSeconds(startTime), this.toSeconds(duration));\n\t\treturn this;\n\t};\n\n\t/**\n\t * Cancels all scheduled parameter changes with times greater than or \n\t * equal to startTime.\n\t * \n\t * @param {Time} startTime\n\t * @returns {Tone.Param} this\n\t */\n\tTone.Param.prototype.cancelScheduledValues = function(startTime){\n\t\tthis._param.cancelScheduledValues(this.toSeconds(startTime));\n\t\treturn this;\n\t};\n\n\t/**\n\t * Ramps to the given value over the duration of the rampTime. \n\t * Automatically selects the best ramp type (exponential or linear)\n\t * depending on the `units` of the signal\n\t * \n\t * @param {number} value \n\t * @param {Time} rampTime \tThe time that it takes the \n\t * value to ramp from it's current value\n\t * @param {Time}\t[startTime=now] \tWhen the ramp should start. \n\t * @returns {Tone.Param} this\n\t * @example\n\t * //ramp to the value either linearly or exponentially \n\t * //depending on the \"units\" value of the signal\n\t * signal.rampTo(0, 10);\n\t * @example\n\t * //schedule it to ramp starting at a specific time\n\t * signal.rampTo(0, 10, 5)\n\t */\n\tTone.Param.prototype.rampTo = function(value, rampTime, startTime){\n\t\trampTime = this.defaultArg(rampTime, 0);\n\t\tif (this.units === Tone.Type.Frequency || this.units === Tone.Type.BPM || this.units === Tone.Type.Decibels){\n\t\t\tthis.exponentialRampToValue(value, rampTime, startTime);\n\t\t} else {\n\t\t\tthis.linearRampToValue(value, rampTime, startTime);\n\t\t}\n\t\treturn this;\n\t};\n\n\t/**\n\t * The LFO created by the signal instance. If none\n\t * was created, this is null.\n\t * @type {Tone.LFO}\n\t * @readOnly\n\t * @memberOf Tone.Param#\n\t * @name lfo\n\t */\n\tObject.defineProperty(Tone.Param.prototype, \"lfo\", {\n\t\tget : function(){\n\t\t\treturn this._lfo;\n\t\t}\n\t});\n\n\t/**\n\t * Clean up\n\t * @returns {Tone.Param} this\n\t */\n\tTone.Param.prototype.dispose = function(){\n\t\tTone.prototype.dispose.call(this);\n\t\tthis._param = null;\n\t\tif (this._lfo){\n\t\t\tthis._lfo.dispose();\n\t\t\tthis._lfo = null;\n\t\t}\n\t\treturn this;\n\t};\n\n\treturn Tone.Param;\n});","'use strict';\r\n\r\ndefine(function (require) {\r\n var p5sound = require('master');\r\n\r\n var Add = require('Tone/signal/Add');\r\n var Mult = require('Tone/signal/Multiply');\r\n var Scale = require('Tone/signal/Scale');\r\n\r\n /**\r\n *
Creates a signal that oscillates between -1.0 and 1.0.\r\n * By default, the oscillation takes the form of a sinusoidal\r\n * shape ('sine'). Additional types include 'triangle',\r\n * 'sawtooth' and 'square'. The frequency defaults to\r\n * 440 oscillations per second (440Hz, equal to the pitch of an\r\n * 'A' note).
\r\n *\r\n *
Set the type of oscillation with setType(), or by instantiating a\r\n * specific oscillator: p5.SinOsc, p5.TriOsc, p5.SqrOsc, or p5.SawOsc.\r\n *
\r\n *\r\n * @class p5.Oscillator\r\n * @constructor\r\n * @param {Number} [freq] frequency defaults to 440Hz\r\n * @param {String} [type] type of oscillator. Options:\r\n * 'sine' (default), 'triangle',\r\n * 'sawtooth', 'square'\r\n * @example\r\n *
\r\n * var osc;\r\n * var playing = false;\r\n *\r\n * function setup() {\r\n * backgroundColor = color(255,0,255);\r\n * textAlign(CENTER);\r\n *\r\n * osc = new p5.Oscillator();\r\n * osc.setType('sine');\r\n * osc.freq(240);\r\n * osc.amp(0);\r\n * osc.start();\r\n * }\r\n *\r\n * function draw() {\r\n * background(backgroundColor)\r\n * text('click to play', width/2, height/2);\r\n * }\r\n *\r\n * function mouseClicked() {\r\n * if (mouseX > 0 && mouseX < width && mouseY < height && mouseY > 0) {\r\n * if (!playing) {\r\n * // ramp amplitude to 0.5 over 0.05 seconds\r\n * osc.amp(0.5, 0.05);\r\n * playing = true;\r\n * backgroundColor = color(0,255,255);\r\n * } else {\r\n * // ramp amplitude to 0 over 0.5 seconds\r\n * osc.amp(0, 0.5);\r\n * playing = false;\r\n * backgroundColor = color(255,0,255);\r\n * }\r\n * }\r\n * }\r\n *
\r\n */\r\n p5.Oscillator = function(freq, type) {\r\n if (typeof freq === 'string') {\r\n var f = type;\r\n type = freq;\r\n freq = f;\r\n } if (typeof type === 'number') {\r\n var f = type;\r\n type = freq;\r\n freq = f;\r\n }\r\n this.started = false;\r\n\r\n // components\r\n this.phaseAmount = undefined;\r\n this.oscillator = p5sound.audiocontext.createOscillator();\r\n this.f = freq || 440.0; // frequency\r\n this.oscillator.type = type || 'sine';\r\n this.oscillator.frequency.setValueAtTime(this.f, p5sound.audiocontext.currentTime);\r\n\r\n // connections\r\n this.output = p5sound.audiocontext.createGain();\r\n\r\n this._freqMods = []; // modulators connected to this oscillator's frequency\r\n\r\n // set default output gain to 0.5\r\n this.output.gain.value = 0.5;\r\n this.output.gain.setValueAtTime(0.5, p5sound.audiocontext.currentTime);\r\n\r\n this.oscillator.connect(this.output);\r\n // stereo panning\r\n this.panPosition = 0.0;\r\n this.connection = p5sound.input; // connect to p5sound by default\r\n this.panner = new p5.Panner(this.output, this.connection, 1);\r\n\r\n //array of math operation signal chaining\r\n this.mathOps = [this.output];\r\n\r\n // add to the soundArray so we can dispose of the osc later\r\n p5sound.soundArray.push(this);\r\n };\r\n\r\n /**\r\n * Start an oscillator. Accepts an optional parameter to\r\n * determine how long (in seconds from now) until the\r\n * oscillator starts.\r\n *\r\n * @method start\r\n * @for p5.Oscillator\r\n * @param {Number} [time] startTime in seconds from now.\r\n * @param {Number} [frequency] frequency in Hz.\r\n */\r\n p5.Oscillator.prototype.start = function(time, f) {\r\n if (this.started) {\r\n var now = p5sound.audiocontext.currentTime;\r\n this.stop(now);\r\n }\r\n if (!this.started) {\r\n var freq = f || this.f;\r\n var type = this.oscillator.type;\r\n\r\n // set old osc free to be garbage collected (memory)\r\n if (this.oscillator) {\r\n this.oscillator.disconnect();\r\n delete this.oscillator;\r\n }\r\n\r\n // var detune = this.oscillator.frequency.value;\r\n this.oscillator = p5sound.audiocontext.createOscillator();\r\n this.oscillator.frequency.value = Math.abs(freq);\r\n this.oscillator.type = type;\r\n // this.oscillator.detune.value = detune;\r\n this.oscillator.connect(this.output);\r\n time = time || 0;\r\n this.oscillator.start(time + p5sound.audiocontext.currentTime);\r\n this.freqNode = this.oscillator.frequency;\r\n\r\n // if other oscillators are already connected to this osc's freq\r\n for (var i in this._freqMods) {\r\n if (typeof this._freqMods[i].connect !== 'undefined') {\r\n this._freqMods[i].connect(this.oscillator.frequency);\r\n }\r\n }\r\n\r\n this.started = true;\r\n }\r\n };\r\n\r\n /**\r\n * Stop an oscillator. Accepts an optional parameter\r\n * to determine how long (in seconds from now) until the\r\n * oscillator stops.\r\n *\r\n * @method stop\r\n * @for p5.Oscillator\r\n * @param {Number} secondsFromNow Time, in seconds from now.\r\n */\r\n p5.Oscillator.prototype.stop = function(time) {\r\n if (this.started) {\r\n var t = time || 0;\r\n var now = p5sound.audiocontext.currentTime;\r\n this.oscillator.stop(t + now);\r\n this.started = false;\r\n }\r\n };\r\n\r\n /**\r\n * Set the amplitude between 0 and 1.0. Or, pass in an object\r\n * such as an oscillator to modulate amplitude with an audio signal.\r\n *\r\n * @method amp\r\n * @for p5.Oscillator\r\n * @param {Number|Object} vol between 0 and 1.0\r\n * or a modulating signal/oscillator\r\n * @param {Number} [rampTime] create a fade that lasts rampTime\r\n * @param {Number} [timeFromNow] schedule this event to happen\r\n * seconds from now\r\n * @return {AudioParam} gain If no value is provided,\r\n * returns the Web Audio API\r\n * AudioParam that controls\r\n * this oscillator's\r\n * gain/amplitude/volume)\r\n */\r\n p5.Oscillator.prototype.amp = function(vol, rampTime, tFromNow) {\r\n var self = this;\r\n if (typeof vol === 'number') {\r\n var rampTime = rampTime || 0;\r\n var tFromNow = tFromNow || 0;\r\n var now = p5sound.audiocontext.currentTime;\r\n this.output.gain.linearRampToValueAtTime(vol, now + tFromNow + rampTime);\r\n }\r\n\r\n else if (vol) {\r\n vol.connect(self.output.gain);\r\n } else {\r\n // return the Gain Node\r\n return this.output.gain;\r\n }\r\n };\r\n\r\n // these are now the same thing\r\n p5.Oscillator.prototype.fade = p5.Oscillator.prototype.amp;\r\n\r\n p5.Oscillator.prototype.getAmp = function() {\r\n return this.output.gain.value;\r\n };\r\n\r\n /**\r\n * Set frequency of an oscillator to a value. Or, pass in an object\r\n * such as an oscillator to modulate the frequency with an audio signal.\r\n *\r\n * @method freq\r\n * @for p5.Oscillator\r\n * @param {Number|Object} Frequency Frequency in Hz\r\n * or modulating signal/oscillator\r\n * @param {Number} [rampTime] Ramp time (in seconds)\r\n * @param {Number} [timeFromNow] Schedule this event to happen\r\n * at x seconds from now\r\n * @return {AudioParam} Frequency If no value is provided,\r\n * returns the Web Audio API\r\n * AudioParam that controls\r\n * this oscillator's frequency\r\n * @example\r\n *
\r\n * var osc = new p5.Oscillator(300);\r\n * osc.start();\r\n * osc.freq(40, 10);\r\n *
\r\n */\r\n p5.Oscillator.prototype.freq = function(val, rampTime, tFromNow) {\r\n if (typeof val === 'number' && !isNaN(val)) {\r\n this.f = val;\r\n var now = p5sound.audiocontext.currentTime;\r\n var rampTime = rampTime || 0;\r\n var tFromNow = tFromNow || 0;\r\n var t = now + tFromNow + rampTime;\r\n // var currentFreq = this.oscillator.frequency.value;\r\n // this.oscillator.frequency.cancelScheduledValues(now);\r\n\r\n if (rampTime === 0) {\r\n this.oscillator.frequency.setValueAtTime(val, tFromNow + now);\r\n } else {\r\n if (val > 0 ) {\r\n this.oscillator.frequency.exponentialRampToValueAtTime(val, tFromNow + rampTime + now);\r\n } else {\r\n this.oscillator.frequency.linearRampToValueAtTime(val, tFromNow + rampTime + now);\r\n }\r\n }\r\n\r\n // reset phase if oscillator has a phase\r\n if (this.phaseAmount) {\r\n this.phase(this.phaseAmount);\r\n }\r\n\r\n } else if (val) {\r\n if (val.output) {\r\n val = val.output;\r\n }\r\n val.connect(this.oscillator.frequency);\r\n\r\n // keep track of what is modulating this param\r\n // so it can be re-connected if\r\n this._freqMods.push( val );\r\n } else {\r\n // return the Frequency Node\r\n return this.oscillator.frequency;\r\n }\r\n };\r\n\r\n p5.Oscillator.prototype.getFreq = function() {\r\n return this.oscillator.frequency.value;\r\n };\r\n\r\n /**\r\n * Set type to 'sine', 'triangle', 'sawtooth' or 'square'.\r\n *\r\n * @method setType\r\n * @for p5.Oscillator\r\n * @param {String} type 'sine', 'triangle', 'sawtooth' or 'square'.\r\n */\r\n p5.Oscillator.prototype.setType = function(type) {\r\n this.oscillator.type = type;\r\n };\r\n\r\n p5.Oscillator.prototype.getType = function() {\r\n return this.oscillator.type;\r\n };\r\n\r\n /**\r\n * Connect to a p5.sound / Web Audio object.\r\n *\r\n * @method connect\r\n * @for p5.Oscillator\r\n * @param {Object} unit A p5.sound or Web Audio object\r\n */\r\n p5.Oscillator.prototype.connect = function(unit) {\r\n if (!unit) {\r\n this.panner.connect(p5sound.input);\r\n }\r\n else if (unit.hasOwnProperty('input')) {\r\n this.panner.connect(unit.input);\r\n this.connection = unit.input;\r\n }\r\n else {\r\n this.panner.connect(unit);\r\n this.connection = unit;\r\n }\r\n };\r\n\r\n /**\r\n * Disconnect all outputs\r\n *\r\n * @method disconnect\r\n * @for p5.Oscillator\r\n */\r\n p5.Oscillator.prototype.disconnect = function() {\r\n if (this.output) {\r\n this.output.disconnect();\r\n }\r\n if (this.panner) {\r\n this.panner.disconnect();\r\n if (this.output) {\r\n this.output.connect(this.panner);\r\n }\r\n }\r\n this.oscMods = [];\r\n };\r\n\r\n /**\r\n * Pan between Left (-1) and Right (1)\r\n *\r\n * @method pan\r\n * @for p5.Oscillator\r\n * @param {Number} panning Number between -1 and 1\r\n * @param {Number} timeFromNow schedule this event to happen\r\n * seconds from now\r\n */\r\n p5.Oscillator.prototype.pan = function(pval, tFromNow) {\r\n this.panPosition = pval;\r\n this.panner.pan(pval, tFromNow);\r\n };\r\n\r\n p5.Oscillator.prototype.getPan = function() {\r\n return this.panPosition;\r\n };\r\n\r\n // get rid of the oscillator\r\n p5.Oscillator.prototype.dispose = function() {\r\n // remove reference from soundArray\r\n var index = p5sound.soundArray.indexOf(this);\r\n p5sound.soundArray.splice(index, 1);\r\n\r\n if (this.oscillator) {\r\n var now = p5sound.audiocontext.currentTime;\r\n this.stop(now);\r\n this.disconnect();\r\n this.panner = null;\r\n this.oscillator = null;\r\n }\r\n // if it is a Pulse\r\n if (this.osc2) {\r\n this.osc2.dispose();\r\n }\r\n };\r\n\r\n /**\r\n * Set the phase of an oscillator between 0.0 and 1.0.\r\n * In this implementation, phase is a delay time\r\n * based on the oscillator's current frequency.\r\n *\r\n * @method phase\r\n * @for p5.Oscillator\r\n * @param {Number} phase float between 0.0 and 1.0\r\n */\r\n p5.Oscillator.prototype.phase = function(p) {\r\n var delayAmt = p5.prototype.map(p, 0, 1.0, 0, 1/this.f);\r\n var now = p5sound.audiocontext.currentTime;\r\n\r\n this.phaseAmount = p;\r\n\r\n if (!this.dNode) {\r\n // create a delay node\r\n this.dNode = p5sound.audiocontext.createDelay();\r\n // put the delay node in between output and panner\r\n this.oscillator.disconnect();\r\n this.oscillator.connect(this.dNode);\r\n this.dNode.connect(this.output);\r\n }\r\n\r\n // set delay time to match phase:\r\n this.dNode.delayTime.setValueAtTime(delayAmt, now);\r\n };\r\n\r\n // ========================== //\r\n // SIGNAL MATH FOR MODULATION //\r\n // ========================== //\r\n\r\n // return sigChain(this, scale, thisChain, nextChain, Scale);\r\n var sigChain = function(o, mathObj, thisChain, nextChain, type) {\r\n var chainSource = o.oscillator;\r\n // if this type of math already exists in the chain, replace it\r\n for (var i in o.mathOps) {\r\n if (o.mathOps[i] instanceof type) {\r\n chainSource.disconnect();\r\n o.mathOps[i].dispose();\r\n thisChain = i;\r\n // assume nextChain is output gain node unless...\r\n if (thisChain < o.mathOps.length - 2) {\r\n nextChain = o.mathOps[i+1];\r\n }\r\n }\r\n }\r\n if (thisChain === o.mathOps.length - 1) {\r\n o.mathOps.push(nextChain);\r\n }\r\n // assume source is the oscillator unless i > 0\r\n if (i > 0) {\r\n chainSource = o.mathOps[i-1];\r\n }\r\n chainSource.disconnect();\r\n chainSource.connect(mathObj);\r\n mathObj.connect(nextChain);\r\n o.mathOps[thisChain] = mathObj;\r\n return o;\r\n };\r\n\r\n /**\r\n * Add a value to the p5.Oscillator's output amplitude,\r\n * and return the oscillator. Calling this method again\r\n * will override the initial add() with a new value.\r\n *\r\n * @method add\r\n * @for p5.Oscillator\r\n * @param {Number} number Constant number to add\r\n * @return {p5.Oscillator} Oscillator Returns this oscillator\r\n * with scaled output\r\n *\r\n */\r\n p5.Oscillator.prototype.add = function(num) {\r\n var add = new Add(num);\r\n var thisChain = this.mathOps.length-1;\r\n var nextChain = this.output;\r\n return sigChain(this, add, thisChain, nextChain, Add);\r\n };\r\n\r\n /**\r\n * Multiply the p5.Oscillator's output amplitude\r\n * by a fixed value (i.e. turn it up!). Calling this method\r\n * again will override the initial mult() with a new value.\r\n *\r\n * @method mult\r\n * @for p5.Oscillator\r\n * @param {Number} number Constant number to multiply\r\n * @return {p5.Oscillator} Oscillator Returns this oscillator\r\n * with multiplied output\r\n */\r\n p5.Oscillator.prototype.mult = function(num) {\r\n var mult = new Mult(num);\r\n var thisChain = this.mathOps.length-1;\r\n var nextChain = this.output;\r\n return sigChain(this, mult, thisChain, nextChain, Mult);\r\n };\r\n\r\n /**\r\n * Scale this oscillator's amplitude values to a given\r\n * range, and return the oscillator. Calling this method\r\n * again will override the initial scale() with new values.\r\n *\r\n * @method scale\r\n * @for p5.Oscillator\r\n * @param {Number} inMin input range minumum\r\n * @param {Number} inMax input range maximum\r\n * @param {Number} outMin input range minumum\r\n * @param {Number} outMax input range maximum\r\n * @return {p5.Oscillator} Oscillator Returns this oscillator\r\n * with scaled output\r\n */\r\n p5.Oscillator.prototype.scale = function(inMin, inMax, outMin, outMax) {\r\n var mapOutMin, mapOutMax;\r\n if (arguments.length === 4) {\r\n mapOutMin = p5.prototype.map(outMin, inMin, inMax, 0, 1) - 0.5;\r\n mapOutMax = p5.prototype.map(outMax, inMin, inMax, 0, 1) - 0.5;\r\n }\r\n else {\r\n mapOutMin = arguments[0];\r\n mapOutMax = arguments[1];\r\n }\r\n var scale = new Scale(mapOutMin, mapOutMax);\r\n var thisChain = this.mathOps.length-1;\r\n var nextChain = this.output;\r\n return sigChain(this, scale, thisChain, nextChain, Scale);\r\n\r\n // this.output.disconnect();\r\n // this.output.connect(scale)\r\n };\r\n\r\n // ============================== //\r\n // SinOsc, TriOsc, SqrOsc, SawOsc //\r\n // ============================== //\r\n\r\n /**\r\n * Constructor: new p5.SinOsc().\r\n * This creates a Sine Wave Oscillator and is\r\n * equivalent to new p5.Oscillator('sine')\r\n * or creating a p5.Oscillator and then calling\r\n * its method setType('sine').\r\n * See p5.Oscillator for methods.\r\n *\r\n * @class p5.SinOsc\r\n * @constructor\r\n * @extends p5.Oscillator\r\n * @param {Number} [freq] Set the frequency\r\n */\r\n p5.SinOsc = function(freq) {\r\n p5.Oscillator.call(this, freq, 'sine');\r\n };\r\n\r\n p5.SinOsc.prototype = Object.create(p5.Oscillator.prototype);\r\n\r\n /**\r\n * Constructor: new p5.TriOsc().\r\n * This creates a Triangle Wave Oscillator and is\r\n * equivalent to new p5.Oscillator('triangle')\r\n * or creating a p5.Oscillator and then calling\r\n * its method setType('triangle').\r\n * See p5.Oscillator for methods.\r\n *\r\n * @class p5.TriOsc\r\n * @constructor\r\n * @extends p5.Oscillator\r\n * @param {Number} [freq] Set the frequency\r\n */\r\n p5.TriOsc = function(freq) {\r\n p5.Oscillator.call(this, freq, 'triangle');\r\n };\r\n\r\n p5.TriOsc.prototype = Object.create(p5.Oscillator.prototype);\r\n\r\n /**\r\n * Constructor: new p5.SawOsc().\r\n * This creates a SawTooth Wave Oscillator and is\r\n * equivalent to new p5.Oscillator('sawtooth')\r\n * or creating a p5.Oscillator and then calling\r\n * its method setType('sawtooth').\r\n * See p5.Oscillator for methods.\r\n *\r\n * @class p5.SawOsc\r\n * @constructor\r\n * @extends p5.Oscillator\r\n * @param {Number} [freq] Set the frequency\r\n */\r\n p5.SawOsc = function(freq) {\r\n p5.Oscillator.call(this, freq, 'sawtooth');\r\n };\r\n\r\n p5.SawOsc.prototype = Object.create(p5.Oscillator.prototype);\r\n\r\n /**\r\n * Constructor: new p5.SqrOsc().\r\n * This creates a Square Wave Oscillator and is\r\n * equivalent to new p5.Oscillator('square')\r\n * or creating a p5.Oscillator and then calling\r\n * its method setType('square').\r\n * See p5.Oscillator for methods.\r\n *\r\n * @class p5.SqrOsc\r\n * @constructor\r\n * @extends p5.Oscillator\r\n * @param {Number} [freq] Set the frequency\r\n */\r\n p5.SqrOsc = function(freq) {\r\n p5.Oscillator.call(this, freq, 'square');\r\n };\r\n\r\n p5.SqrOsc.prototype = Object.create(p5.Oscillator.prototype);\r\n\r\n});\r\n","define([\"Tone/core/Tone\", \"Tone/type/Type\"], function (Tone) {\n\n\t\"use strict\";\n\n\t/**\n\t * @class A Timeline class for scheduling and maintaining state\n\t * along a timeline. All events must have a \"time\" property. \n\t * Internally, events are stored in time order for fast \n\t * retrieval.\n\t * @extends {Tone}\n\t * @param {Positive} [memory=Infinity] The number of previous events that are retained.\n\t */\n\tTone.Timeline = function(){\n\n\t\tvar options = this.optionsObject(arguments, [\"memory\"], Tone.Timeline.defaults);\n\n\t\t/**\n\t\t * The array of scheduled timeline events\n\t\t * @type {Array}\n\t\t * @private\n\t\t */\n\t\tthis._timeline = [];\n\n\t\t/**\n\t\t * An array of items to remove from the list. \n\t\t * @type {Array}\n\t\t * @private\n\t\t */\n\t\tthis._toRemove = [];\n\n\t\t/**\n\t\t * Flag if the tieline is mid iteration\n\t\t * @private\n\t\t * @type {Boolean}\n\t\t */\n\t\tthis._iterating = false;\n\n\t\t/**\n\t\t * The memory of the timeline, i.e.\n\t\t * how many events in the past it will retain\n\t\t * @type {Positive}\n\t\t */\n\t\tthis.memory = options.memory;\n\t};\n\n\tTone.extend(Tone.Timeline);\n\n\t/**\n\t * the default parameters\n\t * @static\n\t * @const\n\t */\n\tTone.Timeline.defaults = {\n\t\t\"memory\" : Infinity\n\t};\n\n\t/**\n\t * The number of items in the timeline.\n\t * @type {Number}\n\t * @memberOf Tone.Timeline#\n\t * @name length\n\t * @readOnly\n\t */\n\tObject.defineProperty(Tone.Timeline.prototype, \"length\", {\n\t\tget : function(){\n\t\t\treturn this._timeline.length;\n\t\t}\n\t});\n\n\t/**\n\t * Insert an event object onto the timeline. Events must have a \"time\" attribute.\n\t * @param {Object} event The event object to insert into the \n\t * timeline. \n\t * @returns {Tone.Timeline} this\n\t */\n\tTone.Timeline.prototype.add = function(event){\n\t\t//the event needs to have a time attribute\n\t\tif (this.isUndef(event.time)){\n\t\t\tthrow new Error(\"Tone.Timeline: events must have a time attribute\");\n\t\t}\n\t\tif (this._timeline.length){\n\t\t\tvar index = this._search(event.time);\n\t\t\tthis._timeline.splice(index + 1, 0, event);\n\t\t} else {\n\t\t\tthis._timeline.push(event);\t\t\t\n\t\t}\n\t\t//if the length is more than the memory, remove the previous ones\n\t\tif (this.length > this.memory){\n\t\t\tvar diff = this.length - this.memory;\n\t\t\tthis._timeline.splice(0, diff);\n\t\t}\n\t\treturn this;\n\t};\n\n\t/**\n\t * Remove an event from the timeline.\n\t * @param {Object} event The event object to remove from the list.\n\t * @returns {Tone.Timeline} this\n\t */\n\tTone.Timeline.prototype.remove = function(event){\n\t\tif (this._iterating){\n\t\t\tthis._toRemove.push(event);\n\t\t} else {\n\t\t\tvar index = this._timeline.indexOf(event);\n\t\t\tif (index !== -1){\n\t\t\t\tthis._timeline.splice(index, 1);\n\t\t\t}\n\t\t}\n\t\treturn this;\n\t};\n\n\t/**\n\t * Get the nearest event whose time is less than or equal to the given time.\n\t * @param {Number} time The time to query.\n\t * @returns {Object} The event object set after that time.\n\t */\n\tTone.Timeline.prototype.get = function(time){\n\t\tvar index = this._search(time);\n\t\tif (index !== -1){\n\t\t\treturn this._timeline[index];\n\t\t} else {\n\t\t\treturn null;\n\t\t}\n\t};\n\n\t/**\n\t * Return the first event in the timeline without removing it\n\t * @returns {Object} The first event object\n\t */\n\tTone.Timeline.prototype.peek = function(){\n\t\treturn this._timeline[0];\n\t};\n\n\t/**\n\t * Return the first event in the timeline and remove it\n\t * @returns {Object} The first event object\n\t */\n\tTone.Timeline.prototype.shift = function(){\n\t\treturn this._timeline.shift();\n\t};\n\n\t/**\n\t * Get the event which is scheduled after the given time.\n\t * @param {Number} time The time to query.\n\t * @returns {Object} The event object after the given time\n\t */\n\tTone.Timeline.prototype.getAfter = function(time){\n\t\tvar index = this._search(time);\n\t\tif (index + 1 < this._timeline.length){\n\t\t\treturn this._timeline[index + 1];\n\t\t} else {\n\t\t\treturn null;\n\t\t}\n\t};\n\n\t/**\n\t * Get the event before the event at the given time.\n\t * @param {Number} time The time to query.\n\t * @returns {Object} The event object before the given time\n\t */\n\tTone.Timeline.prototype.getBefore = function(time){\n\t\tvar len = this._timeline.length;\n\t\t//if it's after the last item, return the last item\n\t\tif (len > 0 && this._timeline[len - 1].time < time){\n\t\t\treturn this._timeline[len - 1];\n\t\t}\n\t\tvar index = this._search(time);\n\t\tif (index - 1 >= 0){\n\t\t\treturn this._timeline[index - 1];\n\t\t} else {\n\t\t\treturn null;\n\t\t}\n\t};\n\n\t/**\n\t * Cancel events after the given time\n\t * @param {Number} time The time to query.\n\t * @returns {Tone.Timeline} this\n\t */\n\tTone.Timeline.prototype.cancel = function(after){\n\t\tif (this._timeline.length > 1){\n\t\t\tvar index = this._search(after);\n\t\t\tif (index >= 0){\n\t\t\t\tif (this._timeline[index].time === after){\n\t\t\t\t\t//get the first item with that time\n\t\t\t\t\tfor (var i = index; i >= 0; i--){\n\t\t\t\t\t\tif (this._timeline[i].time === after){\n\t\t\t\t\t\t\tindex = i;\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tthis._timeline = this._timeline.slice(0, index);\n\t\t\t\t} else {\n\t\t\t\t\tthis._timeline = this._timeline.slice(0, index + 1);\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tthis._timeline = [];\n\t\t\t}\n\t\t} else if (this._timeline.length === 1){\n\t\t\t//the first item's time\n\t\t\tif (this._timeline[0].time >= after){\n\t\t\t\tthis._timeline = [];\n\t\t\t}\n\t\t}\n\t\treturn this;\n\t};\n\n\t/**\n\t * Cancel events before or equal to the given time.\n\t * @param {Number} time The time to cancel before.\n\t * @returns {Tone.Timeline} this\n\t */\n\tTone.Timeline.prototype.cancelBefore = function(time){\n\t\tif (this._timeline.length){\n\t\t\tvar index = this._search(time);\n\t\t\tif (index >= 0){\n\t\t\t\tthis._timeline = this._timeline.slice(index + 1);\n\t\t\t}\n\t\t}\n\t\treturn this;\n\t};\n\n\t/**\n\t * Does a binary serach on the timeline array and returns the \n\t * nearest event index whose time is after or equal to the given time.\n\t * If a time is searched before the first index in the timeline, -1 is returned.\n\t * If the time is after the end, the index of the last item is returned.\n\t * @param {Number} time \n\t * @return {Number} the index in the timeline array \n\t * @private\n\t */\n\tTone.Timeline.prototype._search = function(time){\n\t\tvar beginning = 0;\n\t\tvar len = this._timeline.length;\n\t\tvar end = len;\n\t\tif (len > 0 && this._timeline[len - 1].time <= time){\n\t\t\treturn len - 1;\n\t\t}\n\t\twhile (beginning < end){\n\t\t\t// calculate the midpoint for roughly equal partition\n\t\t\tvar midPoint = Math.floor(beginning + (end - beginning) / 2);\n\t\t\tvar event = this._timeline[midPoint];\n\t\t\tvar nextEvent = this._timeline[midPoint + 1];\n\t\t\tif (event.time === time){\n\t\t\t\t//choose the last one that has the same time\n\t\t\t\tfor (var i = midPoint; i < this._timeline.length; i++){\n\t\t\t\t\tvar testEvent = this._timeline[i];\n\t\t\t\t\tif (testEvent.time === time){\n\t\t\t\t\t\tmidPoint = i;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\treturn midPoint;\n\t\t\t} else if (event.time < time && nextEvent.time > time){\n\t\t\t\treturn midPoint;\n\t\t\t} else if (event.time > time){\n\t\t\t\t//search lower\n\t\t\t\tend = midPoint;\n\t\t\t} else if (event.time < time){\n\t\t\t\t//search upper\n\t\t\t\tbeginning = midPoint + 1;\n\t\t\t} \n\t\t}\n\t\treturn -1;\n\t};\n\n\t/**\n\t * Internal iterator. Applies extra safety checks for \n\t * removing items from the array. \n\t * @param {Function} callback \n\t * @param {Number=} lowerBound \n\t * @param {Number=} upperBound \n\t * @private\n\t */\n\tTone.Timeline.prototype._iterate = function(callback, lowerBound, upperBound){\n\t\tthis._iterating = true;\n\t\tlowerBound = this.defaultArg(lowerBound, 0);\n\t\tupperBound = this.defaultArg(upperBound, this._timeline.length - 1);\n\t\tfor (var i = lowerBound; i <= upperBound; i++){\n\t\t\tcallback(this._timeline[i]);\n\t\t}\n\t\tthis._iterating = false;\n\t\tif (this._toRemove.length > 0){\n\t\t\tfor (var j = 0; j < this._toRemove.length; j++){\n\t\t\t\tvar index = this._timeline.indexOf(this._toRemove[j]);\n\t\t\t\tif (index !== -1){\n\t\t\t\t\tthis._timeline.splice(index, 1);\n\t\t\t\t}\n\t\t\t}\n\t\t\tthis._toRemove = [];\n\t\t}\n\t};\n\n\t/**\n\t * Iterate over everything in the array\n\t * @param {Function} callback The callback to invoke with every item\n\t * @returns {Tone.Timeline} this\n\t */\n\tTone.Timeline.prototype.forEach = function(callback){\n\t\tthis._iterate(callback);\n\t\treturn this;\n\t};\n\n\t/**\n\t * Iterate over everything in the array at or before the given time.\n\t * @param {Number} time The time to check if items are before\n\t * @param {Function} callback The callback to invoke with every item\n\t * @returns {Tone.Timeline} this\n\t */\n\tTone.Timeline.prototype.forEachBefore = function(time, callback){\n\t\t//iterate over the items in reverse so that removing an item doesn't break things\n\t\tvar upperBound = this._search(time);\n\t\tif (upperBound !== -1){\n\t\t\tthis._iterate(callback, 0, upperBound);\n\t\t}\n\t\treturn this;\n\t};\n\n\t/**\n\t * Iterate over everything in the array after the given time.\n\t * @param {Number} time The time to check if items are before\n\t * @param {Function} callback The callback to invoke with every item\n\t * @returns {Tone.Timeline} this\n\t */\n\tTone.Timeline.prototype.forEachAfter = function(time, callback){\n\t\t//iterate over the items in reverse so that removing an item doesn't break things\n\t\tvar lowerBound = this._search(time);\n\t\tthis._iterate(callback, lowerBound + 1);\n\t\treturn this;\n\t};\n\n\t/**\n\t * Iterate over everything in the array at or after the given time. Similar to \n\t * forEachAfter, but includes the item(s) at the given time.\n\t * @param {Number} time The time to check if items are before\n\t * @param {Function} callback The callback to invoke with every item\n\t * @returns {Tone.Timeline} this\n\t */\n\tTone.Timeline.prototype.forEachFrom = function(time, callback){\n\t\t//iterate over the items in reverse so that removing an item doesn't break things\n\t\tvar lowerBound = this._search(time);\n\t\t//work backwards until the event time is less than time\n\t\twhile (lowerBound >= 0 && this._timeline[lowerBound].time >= time){\n\t\t\tlowerBound--;\n\t\t}\n\t\tthis._iterate(callback, lowerBound + 1);\n\t\treturn this;\n\t};\n\n\t/**\n\t * Iterate over everything in the array at the given time\n\t * @param {Number} time The time to check if items are before\n\t * @param {Function} callback The callback to invoke with every item\n\t * @returns {Tone.Timeline} this\n\t */\n\tTone.Timeline.prototype.forEachAtTime = function(time, callback){\n\t\t//iterate over the items in reverse so that removing an item doesn't break things\n\t\tvar upperBound = this._search(time);\n\t\tif (upperBound !== -1){\n\t\t\tthis._iterate(function(event){\n\t\t\t\tif (event.time === time){\n\t\t\t\t\tcallback(event);\n\t\t\t\t} \n\t\t\t}, 0, upperBound);\n\t\t}\n\t\treturn this;\n\t};\n\n\t/**\n\t * Clean up.\n\t * @return {Tone.Timeline} this\n\t */\n\tTone.Timeline.prototype.dispose = function(){\n\t\tTone.prototype.dispose.call(this);\n\t\tthis._timeline = null;\n\t\tthis._toRemove = null;\n\t};\n\n\treturn Tone.Timeline;\n});","define([\"Tone/core/Tone\", \"Tone/signal/Multiply\", \"Tone/signal/Signal\"], function(Tone){\n\n\t\"use strict\";\n\n\t/**\n\t * @class Negate the incoming signal. i.e. an input signal of 10 will output -10\n\t *\n\t * @constructor\n\t * @extends {Tone.SignalBase}\n\t * @example\n\t * var neg = new Tone.Negate();\n\t * var sig = new Tone.Signal(-2).connect(neg);\n\t * //output of neg is positive 2. \n\t */\n\tTone.Negate = function(){\n\t\t/**\n\t\t * negation is done by multiplying by -1\n\t\t * @type {Tone.Multiply}\n\t\t * @private\n\t\t */\n\t\tthis._multiply = this.input = this.output = new Tone.Multiply(-1);\n\t};\n\n\tTone.extend(Tone.Negate, Tone.SignalBase);\n\n\t/**\n\t * clean up\n\t * @returns {Tone.Negate} this\n\t */\n\tTone.Negate.prototype.dispose = function(){\n\t\tTone.prototype.dispose.call(this);\n\t\tthis._multiply.dispose();\n\t\tthis._multiply = null;\n\t\treturn this;\n\t}; \n\n\treturn Tone.Negate;\n});","define([\"Tone/core/Tone\", \"Tone/signal/Signal\", \"Tone/signal/Multiply\", \"Tone/signal/WaveShaper\"], \nfunction(Tone){\n\n\t\"use strict\";\n\n\t/**\n\t * @class GreaterThanZero outputs 1 when the input is strictly greater than zero\n\t * \n\t * @constructor\n\t * @extends {Tone.SignalBase}\n\t * @example\n\t * var gt0 = new Tone.GreaterThanZero();\n\t * var sig = new Tone.Signal(0.01).connect(gt0);\n\t * //the output of gt0 is 1. \n\t * sig.value = 0;\n\t * //the output of gt0 is 0. \n\t */\n\tTone.GreaterThanZero = function(){\n\t\t\n\t\t/**\n\t\t * @type {Tone.WaveShaper}\n\t\t * @private\n\t\t */\n\t\tthis._thresh = this.output = new Tone.WaveShaper(function(val){\n\t\t\tif (val <= 0){\n\t\t\t\treturn 0;\n\t\t\t} else {\n\t\t\t\treturn 1;\n\t\t\t}\n\t\t}, 127);\n\n\t\t/**\n\t\t * scale the first thresholded signal by a large value.\n\t\t * this will help with values which are very close to 0\n\t\t * @type {Tone.Multiply}\n\t\t * @private\n\t\t */\n\t\tthis._scale = this.input = new Tone.Multiply(10000);\n\n\t\t//connections\n\t\tthis._scale.connect(this._thresh);\n\t};\n\n\tTone.extend(Tone.GreaterThanZero, Tone.SignalBase);\n\n\t/**\n\t * dispose method\n\t * @returns {Tone.GreaterThanZero} this\n\t */\n\tTone.GreaterThanZero.prototype.dispose = function(){\n\t\tTone.prototype.dispose.call(this);\n\t\tthis._scale.dispose();\n\t\tthis._scale = null;\n\t\tthis._thresh.dispose();\n\t\tthis._thresh = null;\n\t\treturn this;\n\t};\n\n\treturn Tone.GreaterThanZero;\n});","define([\"Tone/core/Tone\", \"Tone/signal/TimelineSignal\", \"Tone/core/TimelineState\", \n\t\"Tone/core/Emitter\", \"Tone/core/Context\"], function (Tone) {\n\n\t\"use strict\";\n\n\t/**\n\t * @class A sample accurate clock which provides a callback at the given rate. \n\t * While the callback is not sample-accurate (it is still susceptible to\n\t * loose JS timing), the time passed in as the argument to the callback\n\t * is precise. For most applications, it is better to use Tone.Transport\n\t * instead of the Clock by itself since you can synchronize multiple callbacks.\n\t *\n\t * \t@constructor\n\t * @extends {Tone.Emitter}\n\t * \t@param {function} callback The callback to be invoked with the time of the audio event\n\t * \t@param {Frequency} frequency The rate of the callback\n\t * \t@example\n\t * //the callback will be invoked approximately once a second\n\t * //and will print the time exactly once a second apart.\n\t * var clock = new Tone.Clock(function(time){\n\t * \tconsole.log(time);\n\t * }, 1);\n\t */\n\tTone.Clock = function(){\n\n\t\tTone.Emitter.call(this);\n\n\t\tvar options = this.optionsObject(arguments, [\"callback\", \"frequency\"], Tone.Clock.defaults);\n\n\t\t/**\n\t\t * The callback function to invoke at the scheduled tick.\n\t\t * @type {Function}\n\t\t */\n\t\tthis.callback = options.callback;\n\n\t\t/**\n\t\t * The next time the callback is scheduled.\n\t\t * @type {Number}\n\t\t * @private\n\t\t */\n\t\tthis._nextTick = 0;\n\n\t\t/**\n\t\t * The last state of the clock.\n\t\t * @type {State}\n\t\t * @private\n\t\t */\n\t\tthis._lastState = Tone.State.Stopped;\n\n\t\t/**\n\t\t * The rate the callback function should be invoked. \n\t\t * @type {BPM}\n\t\t * @signal\n\t\t */\n\t\tthis.frequency = new Tone.TimelineSignal(options.frequency, Tone.Type.Frequency);\n\t\tthis._readOnly(\"frequency\");\n\n\t\t/**\n\t\t * The number of times the callback was invoked. Starts counting at 0\n\t\t * and increments after the callback was invoked. \n\t\t * @type {Ticks}\n\t\t * @readOnly\n\t\t */\n\t\tthis.ticks = 0;\n\n\t\t/**\n\t\t * The state timeline\n\t\t * @type {Tone.TimelineState}\n\t\t * @private\n\t\t */\n\t\tthis._state = new Tone.TimelineState(Tone.State.Stopped);\n\n\t\t/**\n\t\t * The loop function bound to its context. \n\t\t * This is necessary to remove the event in the end.\n\t\t * @type {Function}\n\t\t * @private\n\t\t */\n\t\tthis._boundLoop = this._loop.bind(this);\n\n\t\t//bind a callback to the worker thread\n \tthis.context.on(\"tick\", this._boundLoop);\n\t};\n\n\tTone.extend(Tone.Clock, Tone.Emitter);\n\n\t/**\n\t * The defaults\n\t * @const\n\t * @type {Object}\n\t */\n\tTone.Clock.defaults = {\n\t\t\"callback\" : Tone.noOp,\n\t\t\"frequency\" : 1,\n\t\t\"lookAhead\" : \"auto\",\n\t};\n\n\t/**\n\t * Returns the playback state of the source, either \"started\", \"stopped\" or \"paused\".\n\t * @type {Tone.State}\n\t * @readOnly\n\t * @memberOf Tone.Clock#\n\t * @name state\n\t */\n\tObject.defineProperty(Tone.Clock.prototype, \"state\", {\n\t\tget : function(){\n\t\t\treturn this._state.getValueAtTime(this.now());\n\t\t}\n\t});\n\n\t/**\n\t * Start the clock at the given time. Optionally pass in an offset\n\t * of where to start the tick counter from.\n\t * @param {Time} time The time the clock should start\n\t * @param {Ticks=} offset Where the tick counter starts counting from.\n\t * @return {Tone.Clock} this\n\t */\n\tTone.Clock.prototype.start = function(time, offset){\n\t\ttime = this.toSeconds(time);\n\t\tif (this._state.getValueAtTime(time) !== Tone.State.Started){\n\t\t\tthis._state.add({\n\t\t\t\t\"state\" : Tone.State.Started, \n\t\t\t\t\"time\" : time,\n\t\t\t\t\"offset\" : offset\n\t\t\t});\n\t\t}\n\t\treturn this;\t\n\t};\n\n\t/**\n\t * Stop the clock. Stopping the clock resets the tick counter to 0.\n\t * @param {Time} [time=now] The time when the clock should stop.\n\t * @returns {Tone.Clock} this\n\t * @example\n\t * clock.stop();\n\t */\n\tTone.Clock.prototype.stop = function(time){\n\t\ttime = this.toSeconds(time);\n\t\tthis._state.cancel(time);\n\t\tthis._state.setStateAtTime(Tone.State.Stopped, time);\n\t\treturn this;\t\n\t};\n\n\n\t/**\n\t * Pause the clock. Pausing does not reset the tick counter.\n\t * @param {Time} [time=now] The time when the clock should stop.\n\t * @returns {Tone.Clock} this\n\t */\n\tTone.Clock.prototype.pause = function(time){\n\t\ttime = this.toSeconds(time);\n\t\tif (this._state.getValueAtTime(time) === Tone.State.Started){\n\t\t\tthis._state.setStateAtTime(Tone.State.Paused, time);\n\t\t}\n\t\treturn this;\t\n\t};\n\n\t/**\n\t * The scheduling loop.\n\t * @param {Number} time The current page time starting from 0\n\t * when the page was loaded.\n\t * @private\n\t */\n\tTone.Clock.prototype._loop = function(){\n\t\t//get the frequency value to compute the value of the next loop\n\t\tvar now = this.now();\n\t\t//if it's started\n\t\tvar lookAhead = this.context.lookAhead;\n\t\tvar updateInterval = this.context.updateInterval;\n\t\tvar lagCompensation = this.context.lag * 2;\n\t\tvar loopInterval = now + lookAhead + updateInterval + lagCompensation;\n\t\twhile (loopInterval > this._nextTick && this._state){\n\t\t\tvar currentState = this._state.getValueAtTime(this._nextTick);\n\t\t\tif (currentState !== this._lastState){\n\t\t\t\tthis._lastState = currentState;\n\t\t\t\tvar event = this._state.get(this._nextTick);\n\t\t\t\t// emit an event\n\t\t\t\tif (currentState === Tone.State.Started){\n\t\t\t\t\t//correct the time\n\t\t\t\t\tthis._nextTick = event.time;\n\t\t\t\t\tif (!this.isUndef(event.offset)){\n\t\t\t\t\t\tthis.ticks = event.offset;\n\t\t\t\t\t}\n\t\t\t\t\tthis.emit(\"start\", event.time, this.ticks);\n\t\t\t\t} else if (currentState === Tone.State.Stopped){\n\t\t\t\t\tthis.ticks = 0;\n\n\t\t\t\t\tthis.emit(\"stop\", event.time);\n\t\t\t\t} else if (currentState === Tone.State.Paused){\n\t\t\t\t\tthis.emit(\"pause\", event.time);\n\t\t\t\t}\n\t\t\t}\n\t\t\tvar tickTime = this._nextTick;\n\t\t\tif (this.frequency){\n\t\t\t\tthis._nextTick += 1 / this.frequency.getValueAtTime(this._nextTick);\n\t\t\t\tif (currentState === Tone.State.Started){\n\t\t\t\t\tthis.callback(tickTime);\n\t\t\t\t\tthis.ticks++;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t};\n\n\t/**\n\t * Returns the scheduled state at the given time.\n\t * @param {Time} time The time to query.\n\t * @return {String} The name of the state input in setStateAtTime.\n\t * @example\n\t * clock.start(\"+0.1\");\n\t * clock.getStateAtTime(\"+0.1\"); //returns \"started\"\n\t */\n\tTone.Clock.prototype.getStateAtTime = function(time){\n\t\ttime = this.toSeconds(time);\n\t\treturn this._state.getValueAtTime(time);\n\t};\n\n\t/**\n\t * Clean up\n\t * @returns {Tone.Clock} this\n\t */\n\tTone.Clock.prototype.dispose = function(){\n\t\tTone.Emitter.prototype.dispose.call(this);\n\t\tthis.context.off(\"tick\", this._boundLoop);\n\t\tthis._writable(\"frequency\");\n\t\tthis.frequency.dispose();\n\t\tthis.frequency = null;\n\t\tthis._boundLoop = null;\n\t\tthis._nextTick = Infinity;\n\t\tthis.callback = null;\n\t\tthis._state.dispose();\n\t\tthis._state = null;\n\t};\n\n\treturn Tone.Clock;\n});","'use strict';\r\ndefine(function (require) {\r\n\r\n var p5sound = require('master');\r\n var AudioVoice = require('audioVoice');\r\n var noteToFreq = require('helpers').noteToFreq;\r\n\r\n var DEFAULT_SUSTAIN = 0.15;\r\n\r\n /**\r\n * A MonoSynth is used as a single voice for sound synthesis.\r\n * This is a class to be used in conjunction with the PolySynth\r\n * class. Custom synthetisers should be built inheriting from\r\n * this class.\r\n *\r\n * @class p5.MonoSynth\r\n * @constructor\r\n * @example\r\n *
\r\n * var monoSynth;\r\n *\r\n * function setup() {\r\n * var cnv = createCanvas(100, 100);\r\n * cnv.mousePressed(playSynth);\r\n *\r\n * monoSynth = new p5.MonoSynth();\r\n *\r\n * textAlign(CENTER);\r\n * text('click to play', width/2, height/2);\r\n * }\r\n *\r\n * function playSynth() {\r\n * // time from now (in seconds)\r\n * var time = 0;\r\n * // note duration (in seconds)\r\n * var dur = 0.25;\r\n * // velocity (volume, from 0 to 1)\r\n * var v = 0.2;\r\n *\r\n * monoSynth.play(\"G3\", v, time, dur);\r\n * monoSynth.play(\"C4\", v, time += dur, dur);\r\n *\r\n * background(random(255), random(255), 255);\r\n * text('click to play', width/2, height/2);\r\n * }\r\n *
\r\n **/\r\n\r\n p5.MonoSynth = function () {\r\n AudioVoice.call(this);\r\n\r\n this.oscillator = new p5.Oscillator();\r\n\r\n this.env = new p5.Envelope();\r\n this.env.setRange(1, 0);\r\n this.env.setExp(true);\r\n\r\n //set params\r\n this.setADSR(0.02, 0.25, 0.05, 0.35);\r\n\r\n // oscillator --> env --> this.output (gain) --> p5.soundOut\r\n this.oscillator.disconnect();\r\n this.oscillator.connect(this.output);\r\n\r\n this.env.disconnect();\r\n this.env.setInput(this.output.gain);\r\n\r\n // reset oscillator gain to 1.0\r\n this.oscillator.output.gain.value = 1.0;\r\n\r\n this.oscillator.start();\r\n this.connect();\r\n\r\n p5sound.soundArray.push(this);\r\n };\r\n\r\n p5.MonoSynth.prototype = Object.create(p5.AudioVoice.prototype);\r\n\r\n /**\r\n * Play tells the MonoSynth to start playing a note. This method schedules\r\n * the calling of .triggerAttack and .triggerRelease.\r\n *\r\n * @method play\r\n * @for p5.MonoSynth\r\n * @param {String | Number} note the note you want to play, specified as a\r\n * frequency in Hertz (Number) or as a midi\r\n * value in Note/Octave format (\"C4\", \"Eb3\"...etc\")\r\n * See \r\n * Tone. Defaults to 440 hz.\r\n * @param {Number} [velocity] velocity of the note to play (ranging from 0 to 1)\r\n * @param {Number} [secondsFromNow] time from now (in seconds) at which to play\r\n * @param {Number} [sustainTime] time to sustain before releasing the envelope\r\n * @example\r\n *
\r\n * var monoSynth;\r\n *\r\n * function setup() {\r\n * var cnv = createCanvas(100, 100);\r\n * cnv.mousePressed(playSynth);\r\n *\r\n * monoSynth = new p5.MonoSynth();\r\n *\r\n * textAlign(CENTER);\r\n * text('click to play', width/2, height/2);\r\n * }\r\n *\r\n * function playSynth() {\r\n * // time from now (in seconds)\r\n * var time = 0;\r\n * // note duration (in seconds)\r\n * var dur = 1/6;\r\n * // note velocity (volume, from 0 to 1)\r\n * var v = random();\r\n *\r\n * monoSynth.play(\"Fb3\", v, 0, dur);\r\n * monoSynth.play(\"Gb3\", v, time += dur, dur);\r\n *\r\n * background(random(255), random(255), 255);\r\n * text('click to play', width/2, height/2);\r\n * }\r\n *
\r\n *\r\n */\r\n p5.MonoSynth.prototype.play = function (note, velocity, secondsFromNow, susTime) {\r\n this.triggerAttack(note, velocity, ~~secondsFromNow);\r\n this.triggerRelease(~~secondsFromNow + (susTime || DEFAULT_SUSTAIN));\r\n };\r\n\r\n /**\r\n * Trigger the Attack, and Decay portion of the Envelope.\r\n * Similar to holding down a key on a piano, but it will\r\n * hold the sustain level until you let go.\r\n *\r\n * @param {String | Number} note the note you want to play, specified as a\r\n * frequency in Hertz (Number) or as a midi\r\n * value in Note/Octave format (\"C4\", \"Eb3\"...etc\")\r\n * See \r\n * Tone. Defaults to 440 hz\r\n * @param {Number} [velocity] velocity of the note to play (ranging from 0 to 1)\r\n * @param {Number} [secondsFromNow] time from now (in seconds) at which to play\r\n * @method triggerAttack\r\n * @for p5.MonoSynth\r\n * @example\r\n *
\r\n * var monoSynth = new p5.MonoSynth();\r\n *\r\n * function mousePressed() {\r\n * monoSynth.triggerAttack(\"E3\");\r\n * }\r\n *\r\n * function mouseReleased() {\r\n * monoSynth.triggerRelease();\r\n * }\r\n *
\r\n */\r\n p5.MonoSynth.prototype.triggerAttack = function (note, velocity, secondsFromNow) {\r\n var secondsFromNow = ~~secondsFromNow;\r\n var freq = noteToFreq(note);\r\n var vel = velocity || 0.1;\r\n this.oscillator.freq(freq, 0, secondsFromNow);\r\n this.env.ramp(this.output.gain, secondsFromNow, vel);\r\n };\r\n\r\n /**\r\n * Trigger the release of the Envelope. This is similar to releasing\r\n * the key on a piano and letting the sound fade according to the\r\n * release level and release time.\r\n *\r\n * @param {Number} secondsFromNow time to trigger the release\r\n * @method triggerRelease\r\n * @for p5.MonoSynth\r\n * @example\r\n *
\r\n * var monoSynth = new p5.MonoSynth();\r\n *\r\n * function mousePressed() {\r\n * monoSynth.triggerAttack(\"E3\");\r\n * }\r\n *\r\n * function mouseReleased() {\r\n * monoSynth.triggerRelease();\r\n * }\r\n *
\r\n */\r\n p5.MonoSynth.prototype.triggerRelease = function (secondsFromNow) {\r\n var secondsFromNow = secondsFromNow || 0;\r\n this.env.ramp(this.output.gain, secondsFromNow, 0);\r\n };\r\n\r\n /**\r\n * Set values like a traditional\r\n * \r\n * ADSR envelope\r\n * .\r\n *\r\n * @method setADSR\r\n * @for p5.MonoSynth\r\n * @param {Number} attackTime Time (in seconds before envelope\r\n * reaches Attack Level\r\n * @param {Number} [decayTime] Time (in seconds) before envelope\r\n * reaches Decay/Sustain Level\r\n * @param {Number} [susRatio] Ratio between attackLevel and releaseLevel, on a scale from 0 to 1,\r\n * where 1.0 = attackLevel, 0.0 = releaseLevel.\r\n * The susRatio determines the decayLevel and the level at which the\r\n * sustain portion of the envelope will sustain.\r\n * For example, if attackLevel is 0.4, releaseLevel is 0,\r\n * and susAmt is 0.5, the decayLevel would be 0.2. If attackLevel is\r\n * increased to 1.0 (using setRange),\r\n * then decayLevel would increase proportionally, to become 0.5.\r\n * @param {Number} [releaseTime] Time in seconds from now (defaults to 0)\r\n */\r\n p5.MonoSynth.prototype.setADSR = function (attack,decay,sustain,release) {\r\n this.env.setADSR(attack, decay, sustain, release);\r\n };\r\n\r\n\r\n /**\r\n * Getters and Setters\r\n * @property {Number} attack\r\n * @for p5.MonoSynth\r\n */\r\n /**\r\n * @property {Number} decay\r\n * @for p5.MonoSynth\r\n */\r\n /**\r\n * @property {Number} sustain\r\n * @for p5.MonoSynth\r\n */\r\n /**\r\n * @property {Number} release\r\n * @for p5.MonoSynth\r\n */\r\n Object.defineProperties(p5.MonoSynth.prototype, {\r\n 'attack': {\r\n get : function() {\r\n return this.env.aTime;\r\n },\r\n set : function(attack) {\r\n this.env.setADSR(attack, this.env.dTime,\r\n this.env.sPercent, this.env.rTime);\r\n }\r\n },\r\n 'decay': {\r\n get : function() {\r\n return this.env.dTime;\r\n },\r\n set : function(decay) {\r\n this.env.setADSR(this.env.aTime, decay,\r\n this.env.sPercent, this.env.rTime);\r\n }\r\n },\r\n 'sustain': {\r\n get : function() {\r\n return this.env.sPercent;\r\n },\r\n set : function(sustain) {\r\n this.env.setADSR(this.env.aTime, this.env.dTime,\r\n sustain, this.env.rTime);\r\n }\r\n },\r\n 'release': {\r\n get : function() {\r\n return this.env.rTime;\r\n },\r\n set : function(release) {\r\n this.env.setADSR(this.env.aTime, this.env.dTime,\r\n this.env.sPercent, release);\r\n }\r\n },\r\n });\r\n\r\n\r\n /**\r\n * MonoSynth amp\r\n * @method amp\r\n * @for p5.MonoSynth\r\n * @param {Number} vol desired volume\r\n * @param {Number} [rampTime] Time to reach new volume\r\n * @return {Number} new volume value\r\n */\r\n p5.MonoSynth.prototype.amp = function(vol, rampTime) {\r\n var t = rampTime || 0;\r\n if (typeof vol !== 'undefined') {\r\n this.oscillator.amp(vol, t);\r\n }\r\n return this.oscillator.amp().value;\r\n };\r\n\r\n /**\r\n * Connect to a p5.sound / Web Audio object.\r\n *\r\n * @method connect\r\n * @for p5.MonoSynth\r\n * @param {Object} unit A p5.sound or Web Audio object\r\n */\r\n\r\n p5.MonoSynth.prototype.connect = function(unit) {\r\n var u = unit || p5sound.input;\r\n this.output.connect(u.input ? u.input : u);\r\n };\r\n\r\n /**\r\n * Disconnect all outputs\r\n *\r\n * @method disconnect\r\n * @for p5.MonoSynth\r\n */\r\n p5.MonoSynth.prototype.disconnect = function() {\r\n if (this.output) {\r\n this.output.disconnect();\r\n }\r\n };\r\n\r\n\r\n /**\r\n * Get rid of the MonoSynth and free up its resources / memory.\r\n *\r\n * @method dispose\r\n * @for p5.MonoSynth\r\n */\r\n p5.MonoSynth.prototype.dispose = function() {\r\n AudioVoice.prototype.dispose.apply(this);\r\n\r\n if (this.env) {\r\n this.env.dispose();\r\n }\r\n if (this.oscillator) {\r\n this.oscillator.dispose();\r\n }\r\n };\r\n\r\n});\r\n","'use strict';\r\ndefine(function() {\r\n var p5sound = require('master');\r\n\r\n /**\r\n * Base class for monophonic synthesizers. Any extensions of this class\r\n * should follow the API and implement the methods below in order to\r\n * remain compatible with p5.PolySynth();\r\n *\r\n * @class p5.AudioVoice\r\n * @constructor\r\n */\r\n p5.AudioVoice = function () {\r\n\t this.ac = p5sound.audiocontext;\r\n\t this.output = this.ac.createGain();\r\n\t this.connect();\r\n\t p5sound.soundArray.push(this);\r\n };\r\n\r\n p5.AudioVoice.prototype.play = function (note, velocity, secondsFromNow, sustime) {\r\n };\r\n\r\n p5.AudioVoice.prototype.triggerAttack = function (note, velocity, secondsFromNow) {\r\n };\r\n\r\n p5.AudioVoice.prototype.triggerRelease = function (secondsFromNow) {\r\n };\r\n\r\n p5.AudioVoice.prototype.amp = function(vol, rampTime) {\r\n };\r\n\r\n /**\r\n * Connect to p5 objects or Web Audio Nodes\r\n * @method connect\r\n * @for p5.AudioVoice\r\n * @param {Object} unit\r\n */\r\n p5.AudioVoice.prototype.connect = function(unit) {\r\n var u = unit || p5sound.input;\r\n this.output.connect(u.input ? u.input : u);\r\n };\r\n\r\n /**\r\n * Disconnect from soundOut\r\n * @method disconnect\r\n * @for p5.AudioVoice\r\n */\r\n p5.AudioVoice.prototype.disconnect = function() {\r\n this.output.disconnect();\r\n };\r\n\r\n p5.AudioVoice.prototype.dispose = function() {\r\n if (this.output) {\r\n this.output.disconnect();\r\n delete this.output;\r\n }\r\n };\r\n\r\n return p5.AudioVoice;\r\n});\r\n","'use strict';\r\ndefine(function (require) {\r\n\r\n var p5sound = require('master');\r\n var TimelineSignal = require('Tone/signal/TimelineSignal');\r\n var noteToFreq = require('helpers').noteToFreq;\r\n\r\n /**\r\n * An AudioVoice is used as a single voice for sound synthesis.\r\n * The PolySynth class holds an array of AudioVoice, and deals\r\n * with voices allocations, with setting notes to be played, and\r\n * parameters to be set.\r\n *\r\n * @class p5.PolySynth\r\n * @constructor\r\n *\r\n * @param {Number} [synthVoice] A monophonic synth voice inheriting\r\n * the AudioVoice class. Defaults to p5.MonoSynth\r\n * @param {Number} [maxVoices] Number of voices, defaults to 8;\r\n * @example\r\n *
\r\n * var polySynth;\r\n *\r\n * function setup() {\r\n * var cnv = createCanvas(100, 100);\r\n * cnv.mousePressed(playSynth);\r\n *\r\n * polySynth = new p5.PolySynth();\r\n *\r\n * textAlign(CENTER);\r\n * text('click to play', width/2, height/2);\r\n * }\r\n *\r\n * function playSynth() {\r\n * // note duration (in seconds)\r\n * var dur = 1.5;\r\n *\r\n * // time from now (in seconds)\r\n * var time = 0;\r\n *\r\n * // velocity (volume, from 0 to 1)\r\n * var vel = 0.1;\r\n *\r\n * // notes can overlap with each other\r\n * polySynth.play(\"G2\", vel, 0, dur);\r\n * polySynth.play(\"C3\", vel, time += 1/3, dur);\r\n * polySynth.play(\"G3\", vel, time += 1/3, dur);\r\n *\r\n * background(random(255), random(255), 255);\r\n * text('click to play', width/2, height/2);\r\n * }\r\n *
\r\n **/\r\n p5.PolySynth = function(audioVoice, maxVoices) {\r\n //audiovoices will contain maxVoices many monophonic synths\r\n this.audiovoices = [];\r\n\r\n /**\r\n * An object that holds information about which notes have been played and\r\n * which notes are currently being played. New notes are added as keys\r\n * on the fly. While a note has been attacked, but not released, the value of the\r\n * key is the audiovoice which is generating that note. When notes are released,\r\n * the value of the key becomes undefined.\r\n * @property notes\r\n */\r\n this.notes = {};\r\n\r\n //indices of the most recently used, and least recently used audiovoice\r\n this._newest = 0;\r\n this._oldest = 0;\r\n\r\n /**\r\n * A PolySynth must have at least 1 voice, defaults to 8\r\n * @property polyvalue\r\n */\r\n this.maxVoices = maxVoices || 8;\r\n\r\n /**\r\n * Monosynth that generates the sound for each note that is triggered. The\r\n * p5.PolySynth defaults to using the p5.MonoSynth as its voice.\r\n * @property AudioVoice\r\n */\r\n this.AudioVoice = audioVoice === undefined ? p5.MonoSynth : audioVoice;\r\n\r\n /**\r\n * This value must only change as a note is attacked or released. Due to delay\r\n * and sustain times, Tone.TimelineSignal is required to schedule the change in value.\r\n\t * @private\r\n * @property {Tone.TimelineSignal} _voicesInUse\r\n */\r\n this._voicesInUse = new TimelineSignal(0);\r\n\r\n this.output = p5sound.audiocontext.createGain();\r\n this.connect();\r\n\r\n //Construct the appropriate number of audiovoices\r\n this._allocateVoices();\r\n p5sound.soundArray.push(this);\r\n };\r\n\r\n /**\r\n * Construct the appropriate number of audiovoices\r\n * @private\r\n * @for p5.PolySynth\r\n * @method _allocateVoices\r\n */\r\n p5.PolySynth.prototype._allocateVoices = function() {\r\n for(var i = 0; i< this.maxVoices; i++) {\r\n this.audiovoices.push(new this.AudioVoice());\r\n this.audiovoices[i].disconnect();\r\n this.audiovoices[i].connect(this.output);\r\n }\r\n };\r\n\r\n /**\r\n * Play a note by triggering noteAttack and noteRelease with sustain time\r\n *\r\n * @method play\r\n * @for p5.PolySynth\r\n * @param {Number} [note] midi note to play (ranging from 0 to 127 - 60 being a middle C)\r\n * @param {Number} [velocity] velocity of the note to play (ranging from 0 to 1)\r\n * @param {Number} [secondsFromNow] time from now (in seconds) at which to play\r\n * @param {Number} [sustainTime] time to sustain before releasing the envelope\r\n * @example\r\n *
\r\n * var polySynth;\r\n *\r\n * function setup() {\r\n * var cnv = createCanvas(100, 100);\r\n * cnv.mousePressed(playSynth);\r\n *\r\n * polySynth = new p5.PolySynth();\r\n *\r\n * textAlign(CENTER);\r\n * text('click to play', width/2, height/2);\r\n * }\r\n *\r\n * function playSynth() {\r\n * // note duration (in seconds)\r\n * var dur = 0.1;\r\n *\r\n * // time from now (in seconds)\r\n * var time = 0;\r\n *\r\n * // velocity (volume, from 0 to 1)\r\n * var vel = 0.1;\r\n *\r\n * polySynth.play(\"G2\", vel, 0, dur);\r\n * polySynth.play(\"C3\", vel, 0, dur);\r\n * polySynth.play(\"G3\", vel, 0, dur);\r\n *\r\n * background(random(255), random(255), 255);\r\n * text('click to play', width/2, height/2);\r\n * }\r\n *
\r\n */\r\n p5.PolySynth.prototype.play = function (note,velocity, secondsFromNow, susTime) {\r\n var susTime = susTime || 1;\r\n this.noteAttack(note, velocity, secondsFromNow);\r\n this.noteRelease(note, secondsFromNow + susTime);\r\n };\r\n\r\n\r\n /**\r\n * noteADSR sets the envelope for a specific note that has just been triggered.\r\n * Using this method modifies the envelope of whichever audiovoice is being used\r\n * to play the desired note. The envelope should be reset before noteRelease is called\r\n * in order to prevent the modified envelope from being used on other notes.\r\n *\r\n * @method noteADSR\r\n * @for p5.PolySynth\r\n * @param {Number} [note] Midi note on which ADSR should be set.\r\n * @param {Number} [attackTime] Time (in seconds before envelope\r\n * reaches Attack Level\r\n * @param {Number} [decayTime] Time (in seconds) before envelope\r\n * reaches Decay/Sustain Level\r\n * @param {Number} [susRatio] Ratio between attackLevel and releaseLevel, on a scale from 0 to 1,\r\n * where 1.0 = attackLevel, 0.0 = releaseLevel.\r\n * The susRatio determines the decayLevel and the level at which the\r\n * sustain portion of the envelope will sustain.\r\n * For example, if attackLevel is 0.4, releaseLevel is 0,\r\n * and susAmt is 0.5, the decayLevel would be 0.2. If attackLevel is\r\n * increased to 1.0 (using setRange),\r\n * then decayLevel would increase proportionally, to become 0.5.\r\n * @param {Number} [releaseTime] Time in seconds from now (defaults to 0)\r\n **/\r\n\r\n p5.PolySynth.prototype.noteADSR = function (note,a,d,s,r,timeFromNow) {\r\n var now = p5sound.audiocontext.currentTime;\r\n var timeFromNow = timeFromNow || 0;\r\n var t = now + timeFromNow\r\n this.audiovoices[ this.notes[note].getValueAtTime(t) ].setADSR(a,d,s,r);\r\n };\r\n\r\n\r\n /**\r\n * Set the PolySynths global envelope. This method modifies the envelopes of each\r\n * monosynth so that all notes are played with this envelope.\r\n *\r\n * @method setADSR\r\n * @for p5.PolySynth\r\n * @param {Number} [attackTime] Time (in seconds before envelope\r\n * reaches Attack Level\r\n * @param {Number} [decayTime] Time (in seconds) before envelope\r\n * reaches Decay/Sustain Level\r\n * @param {Number} [susRatio] Ratio between attackLevel and releaseLevel, on a scale from 0 to 1,\r\n * where 1.0 = attackLevel, 0.0 = releaseLevel.\r\n * The susRatio determines the decayLevel and the level at which the\r\n * sustain portion of the envelope will sustain.\r\n * For example, if attackLevel is 0.4, releaseLevel is 0,\r\n * and susAmt is 0.5, the decayLevel would be 0.2. If attackLevel is\r\n * increased to 1.0 (using setRange),\r\n * then decayLevel would increase proportionally, to become 0.5.\r\n * @param {Number} [releaseTime] Time in seconds from now (defaults to 0)\r\n **/\r\n p5.PolySynth.prototype.setADSR = function(a,d,s,r) {\r\n this.audiovoices.forEach(function(voice) {\r\n voice.setADSR(a,d,s,r);\r\n });\r\n };\r\n\r\n /**\r\n * Trigger the Attack, and Decay portion of a MonoSynth.\r\n * Similar to holding down a key on a piano, but it will\r\n * hold the sustain level until you let go.\r\n *\r\n * @method noteAttack\r\n * @for p5.PolySynth\r\n * @param {Number} [note] midi note on which attack should be triggered.\r\n * @param {Number} [velocity] velocity of the note to play (ranging from 0 to 1)/\r\n * @param {Number} [secondsFromNow] time from now (in seconds)\r\n * @example\r\n *
\r\n * var polySynth = new p5.PolySynth();\r\n * var pitches = [\"G\", \"D\", \"G\", \"C\"];\r\n * var octaves = [2, 3, 4];\r\n *\r\n * function mousePressed() {\r\n * // play a chord: multiple notes at the same time\r\n * for (var i = 0; i < 4; i++) {\r\n * var note = random(pitches) + random(octaves);\r\n * polySynth.noteAttack(note, 0.1);\r\n * }\r\n * }\r\n *\r\n * function mouseReleased() {\r\n * // release all voices\r\n * polySynth.noteRelease();\r\n * }\r\n *
\r\n */\r\n p5.PolySynth.prototype.noteAttack = function (_note, _velocity, secondsFromNow) {\r\n //this value goes to the audiovoices which handle their own scheduling\r\n var secondsFromNow = ~~secondsFromNow;\r\n\r\n //this value is used by this._voicesInUse\r\n var acTime = p5sound.audiocontext.currentTime + secondsFromNow;\r\n\r\n //Convert note to frequency if necessary. This is because entries into this.notes\r\n //should be based on frequency for the sake of consistency.\r\n var note = noteToFreq(_note);\r\n var velocity = _velocity || 0.1;\r\n\r\n var currentVoice;\r\n\r\n //Release the note if it is already playing\r\n if (this.notes[note] && this.notes[note].getValueAtTime(acTime) !== null) {\r\n this.noteRelease(note, 0);\r\n }\r\n\r\n //Check to see how many voices are in use at the time the note will start\r\n if (this._voicesInUse.getValueAtTime(acTime) < this.maxVoices) {\r\n currentVoice = Math.max(~~this._voicesInUse.getValueAtTime(acTime), 0);\r\n }\r\n //If we are exceeding the polyvalue, bump off the oldest notes and replace\r\n //with a new note\r\n else {\r\n currentVoice = this._oldest;\r\n\r\n var oldestNote = p5.prototype.freqToMidi(this.audiovoices[this._oldest].oscillator.freq().value);\r\n this.noteRelease(oldestNote);\r\n this._oldest = ( this._oldest + 1 ) % (this.maxVoices - 1);\r\n }\r\n\r\n //Overrite the entry in the notes object. A note (frequency value)\r\n //corresponds to the index of the audiovoice that is playing it\r\n this.notes[note] = new TimelineSignal();\r\n this.notes[note].setValueAtTime(currentVoice, acTime);\r\n\r\n //Find the scheduled change in this._voicesInUse that will be previous to this new note\r\n //Add 1 and schedule this value at time 't', when this note will start playing\r\n var previousVal = this._voicesInUse._searchBefore(acTime) === null ? 0 : this._voicesInUse._searchBefore(acTime).value;\r\n this._voicesInUse.setValueAtTime(previousVal + 1, acTime);\r\n\r\n //Then update all scheduled values that follow to increase by 1\r\n this._updateAfter(acTime, 1);\r\n\r\n this._newest = currentVoice;\r\n //The audiovoice handles the actual scheduling of the note\r\n if (typeof velocity === 'number') {\r\n var maxRange = 1 / this._voicesInUse.getValueAtTime(acTime) * 2;\r\n velocity = velocity > maxRange ? maxRange : velocity;\r\n }\r\n this.audiovoices[currentVoice].triggerAttack(note, velocity, secondsFromNow);\r\n };\r\n\r\n /**\r\n * Private method to ensure accurate values of this._voicesInUse\r\n * Any time a new value is scheduled, it is necessary to increment all subsequent\r\n * scheduledValues after attack, and decrement all subsequent\r\n * scheduledValues after release\r\n *\r\n * @private\r\n * @for p5.PolySynth\r\n * @param {[type]} time [description]\r\n * @param {[type]} value [description]\r\n * @return {[type]} [description]\r\n */\r\n p5.PolySynth.prototype._updateAfter = function(time, value) {\r\n if(this._voicesInUse._searchAfter(time) === null) {\r\n return;\r\n } else{\r\n this._voicesInUse._searchAfter(time).value += value;\r\n var nextTime = this._voicesInUse._searchAfter(time).time;\r\n this._updateAfter(nextTime, value);\r\n }\r\n };\r\n\r\n\r\n /**\r\n * Trigger the Release of an AudioVoice note. This is similar to releasing\r\n * the key on a piano and letting the sound fade according to the\r\n * release level and release time.\r\n *\r\n * @method noteRelease\r\n * @for p5.PolySynth\r\n * @param {Number} [note] midi note on which attack should be triggered.\r\n * If no value is provided, all notes will be released.\r\n * @param {Number} [secondsFromNow] time to trigger the release\r\n * @example\r\n *
\r\n * var pitches = [\"G\", \"D\", \"G\", \"C\"];\r\n * var octaves = [2, 3, 4];\r\n * var polySynth = new p5.PolySynth();\r\n *\r\n * function mousePressed() {\r\n * // play a chord: multiple notes at the same time\r\n * for (var i = 0; i < 4; i++) {\r\n * var note = random(pitches) + random(octaves);\r\n * polySynth.noteAttack(note, 0.1);\r\n * }\r\n * }\r\n *\r\n * function mouseReleased() {\r\n * // release all voices\r\n * polySynth.noteRelease();\r\n * }\r\n *
\r\n *\r\n */\r\n p5.PolySynth.prototype.noteRelease = function (_note,secondsFromNow) {\r\n var now = p5sound.audiocontext.currentTime;\r\n var tFromNow = secondsFromNow || 0;\r\n var t = now + tFromNow;\r\n\r\n // if a note value is not provided, release all voices\r\n if (!_note) {\r\n this.audiovoices.forEach(function(voice) {\r\n voice.triggerRelease(tFromNow)\r\n });\r\n this._voicesInUse.setValueAtTime(0, t);\r\n for (var n in this.notes) {\r\n this.notes[n].dispose();\r\n delete this.notes[n];\r\n }\r\n return;\r\n }\r\n\r\n //Make sure note is in frequency inorder to query the this.notes object\r\n var note = noteToFreq(_note);\r\n\r\n if (!this.notes[note] || this.notes[note].getValueAtTime(t) === null) {\r\n console.warn('Cannot release a note that is not already playing');\r\n } else {\r\n //Find the scheduled change in this._voicesInUse that will be previous to this new note\r\n //subtract 1 and schedule this value at time 't', when this note will stop playing\r\n var previousVal = Math.max(~~this._voicesInUse.getValueAtTime(t).value, 1);\r\n this._voicesInUse.setValueAtTime(previousVal - 1, t);\r\n //Then update all scheduled values that follow to decrease by 1 but never go below 0\r\n if (previousVal > 0) {\r\n this._updateAfter(t, -1);\r\n }\r\n\r\n this.audiovoices[ this.notes[note].getValueAtTime(t) ].triggerRelease(tFromNow);\r\n this.notes[note].dispose();\r\n delete this.notes[note];\r\n\r\n this._newest = this._newest === 0 ? 0 : (this._newest - 1) % (this.maxVoices - 1);\r\n }\r\n\r\n };\r\n\r\n /**\r\n * Connect to a p5.sound / Web Audio object.\r\n *\r\n * @method connect\r\n * @for p5.PolySynth\r\n * @param {Object} unit A p5.sound or Web Audio object\r\n */\r\n p5.PolySynth.prototype.connect = function (unit) {\r\n var u = unit || p5sound.input;\r\n this.output.connect(u.input ? u.input : u);\r\n };\r\n\r\n /**\r\n * Disconnect all outputs\r\n *\r\n * @method disconnect\r\n * @for p5.PolySynth\r\n */\r\n p5.PolySynth.prototype.disconnect = function() {\r\n if (this.output) {\r\n this.output.disconnect();\r\n }\r\n };\r\n\r\n /**\r\n * Get rid of the MonoSynth and free up its resources / memory.\r\n *\r\n * @method dispose\r\n * @for p5.PolySynth\r\n */\r\n p5.PolySynth.prototype.dispose = function() {\r\n this.audiovoices.forEach(function(voice) {\r\n voice.dispose();\r\n });\r\n\r\n if (this.output) {\r\n this.output.disconnect();\r\n delete this.output;\r\n }\r\n };\r\n\r\n});\r\n","'use strict';\r\n\r\ndefine(function (require) {\r\n\r\n require('audioworklet-polyfill');\r\n require('shims');\r\n require('audiocontext');\r\n var p5SOUND = require('master');\r\n require('helpers');\r\n require('errorHandler');\r\n require('audioWorklet');\r\n require('panner');\r\n require('soundfile');\r\n require('amplitude');\r\n require('fft');\r\n require('signal');\r\n require('oscillator');\r\n require('envelope');\r\n require('pulse');\r\n require('noise');\r\n require('audioin');\r\n require('filter');\r\n require('eq');\r\n require('panner3d');\r\n require('listener3d');\r\n require('delay');\r\n require('reverb');\r\n require('metro');\r\n require('looper');\r\n require('soundLoop');\r\n require('compressor');\r\n require('soundRecorder');\r\n require('peakDetect');\r\n require('gain');\r\n require('monosynth');\r\n require('polysynth');\r\n require('distortion');\r\n require('audioVoice');\r\n require('monosynth');\r\n require('polysynth');\r\n\r\n return p5SOUND;\r\n\r\n});\r\n","!function(){var e,t=[];function r(e){var r=this,n={},i=-1;this.parameters.forEach(function(e,o){var s=t[++i]||(t[i]=new Float32Array(r.bufferSize));s.fill(e.value),n[o]=s}),this.processor.realm.exec(\"self.sampleRate=sampleRate=\"+this.context.sampleRate+\";self.currentTime=currentTime=\"+this.context.currentTime);var s=o(e.inputBuffer),a=o(e.outputBuffer);this.instance.process([s],[a],n)}function o(e){for(var t=[],r=0;r= this.sampleLimit) {\\n this.stop();\\n return true;\\n }\\n\\n var input = inputs[0];\\n var output = outputs[0];\\n\\n for (var channel = 0; channel < output.length; ++channel) {\\n var inputChannel = input[channel];\\n\\n if (channel === 0) {\\n this.leftBuffers.push(inputChannel);\\n\\n if (this.numInputChannels === 1) {\\n this.rightBuffers.push(inputChannel);\\n }\\n } else if (channel === 1 && this.numInputChannels > 1) {\\n this.rightBuffers.push(inputChannel);\\n }\\n }\\n\\n this.recordedSamples += output[0].length;\\n return true;\\n }\\n }, {\\n key: \\\"record\\\",\\n value: function record(duration) {\\n if (duration) {\\n this.sampleLimit = Math.round(duration * sampleRate);\\n }\\n\\n this.recording = true;\\n }\\n }, {\\n key: \\\"stop\\\",\\n value: function stop() {\\n this.recording = false;\\n var buffers = this.getBuffers();\\n var leftBuffer = buffers[0].buffer;\\n var rightBuffer = buffers[1].buffer;\\n this.port.postMessage({\\n name: 'buffers',\\n leftBuffer: leftBuffer,\\n rightBuffer: rightBuffer\\n }, [leftBuffer, rightBuffer]);\\n this.clear();\\n }\\n }, {\\n key: \\\"getBuffers\\\",\\n value: function getBuffers() {\\n var buffers = [];\\n buffers.push(this.mergeBuffers(this.leftBuffers));\\n buffers.push(this.mergeBuffers(this.rightBuffers));\\n return buffers;\\n }\\n }, {\\n key: \\\"mergeBuffers\\\",\\n value: function mergeBuffers(channelBuffer) {\\n var result = new Float32Array(this.recordedSamples);\\n var offset = 0;\\n var lng = channelBuffer.length;\\n\\n for (var i = 0; i < lng; i++) {\\n var buffer = channelBuffer[i];\\n result.set(buffer, offset);\\n offset += buffer.length;\\n }\\n\\n return result;\\n }\\n }, {\\n key: \\\"clear\\\",\\n value: function clear() {\\n this.leftBuffers = [];\\n this.rightBuffers = [];\\n this.recordedSamples = 0;\\n this.sampleLimit = null;\\n }\\n }]);\\n\\n return RecorderProcessor;\\n}(_wrapNativeSuper(AudioWorkletProcessor));\\n\\nregisterProcessor(processorNames.recorderProcessor, RecorderProcessor);\"","export default \"function _typeof(obj) { if (typeof Symbol === \\\"function\\\" && typeof Symbol.iterator === \\\"symbol\\\") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === \\\"function\\\" && obj.constructor === Symbol && obj !== Symbol.prototype ? \\\"symbol\\\" : typeof obj; }; } return _typeof(obj); }\\n\\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\\\"Cannot call a class as a function\\\"); } }\\n\\nfunction _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if (\\\"value\\\" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }\\n\\nfunction _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }\\n\\nfunction _possibleConstructorReturn(self, call) { if (call && (_typeof(call) === \\\"object\\\" || typeof call === \\\"function\\\")) { return call; } return _assertThisInitialized(self); }\\n\\nfunction _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError(\\\"this hasn't been initialised - super() hasn't been called\\\"); } return self; }\\n\\nfunction _inherits(subClass, superClass) { if (typeof superClass !== \\\"function\\\" && superClass !== null) { throw new TypeError(\\\"Super expression must either be null or a function\\\"); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, writable: true, configurable: true } }); if (superClass) _setPrototypeOf(subClass, superClass); }\\n\\nfunction _wrapNativeSuper(Class) { var _cache = typeof Map === \\\"function\\\" ? new Map() : undefined; _wrapNativeSuper = function _wrapNativeSuper(Class) { if (Class === null || !_isNativeFunction(Class)) return Class; if (typeof Class !== \\\"function\\\") { throw new TypeError(\\\"Super expression must either be null or a function\\\"); } if (typeof _cache !== \\\"undefined\\\") { if (_cache.has(Class)) return _cache.get(Class); _cache.set(Class, Wrapper); } function Wrapper() { return _construct(Class, arguments, _getPrototypeOf(this).constructor); } Wrapper.prototype = Object.create(Class.prototype, { constructor: { value: Wrapper, enumerable: false, writable: true, configurable: true } }); return _setPrototypeOf(Wrapper, Class); }; return _wrapNativeSuper(Class); }\\n\\nfunction isNativeReflectConstruct() { if (typeof Reflect === \\\"undefined\\\" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === \\\"function\\\") return true; try { Date.prototype.toString.call(Reflect.construct(Date, [], function () {})); return true; } catch (e) { return false; } }\\n\\nfunction _construct(Parent, args, Class) { if (isNativeReflectConstruct()) { _construct = Reflect.construct; } else { _construct = function _construct(Parent, args, Class) { var a = [null]; a.push.apply(a, args); var Constructor = Function.bind.apply(Parent, a); var instance = new Constructor(); if (Class) _setPrototypeOf(instance, Class.prototype); return instance; }; } return _construct.apply(null, arguments); }\\n\\nfunction _isNativeFunction(fn) { return Function.toString.call(fn).indexOf(\\\"[native code]\\\") !== -1; }\\n\\nfunction _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); }\\n\\nfunction _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); }; return _getPrototypeOf(o); }\\n\\n// import processor name via preval.require so that it's available as a value at compile time\\nvar processorNames = {\\n \\\"recorderProcessor\\\": \\\"recorder-processor\\\",\\n \\\"soundFileProcessor\\\": \\\"sound-file-processor\\\",\\n \\\"amplitudeProcessor\\\": \\\"amplitude-processor\\\"\\n};\\n\\nvar SoundFileProcessor =\\n/*#__PURE__*/\\nfunction (_AudioWorkletProcesso) {\\n _inherits(SoundFileProcessor, _AudioWorkletProcesso);\\n\\n function SoundFileProcessor() {\\n _classCallCheck(this, SoundFileProcessor);\\n\\n return _possibleConstructorReturn(this, _getPrototypeOf(SoundFileProcessor).apply(this, arguments));\\n }\\n\\n _createClass(SoundFileProcessor, [{\\n key: \\\"process\\\",\\n value: function process(inputs) {\\n var input = inputs[0];\\n var inputChannel = input[0];\\n var position = inputChannel[inputChannel.length - 1] || 0;\\n this.port.postMessage({\\n name: 'position',\\n position: position\\n });\\n return true;\\n }\\n }]);\\n\\n return SoundFileProcessor;\\n}(_wrapNativeSuper(AudioWorkletProcessor));\\n\\nregisterProcessor(processorNames.soundFileProcessor, SoundFileProcessor);\"","'use strict';\r\n\r\ndefine(function (require) {\r\n\r\n var p5sound = require('master');\r\n var ac = p5sound.audiocontext;\r\n\r\n // Stereo panner\r\n // if there is a stereo panner node use it\r\n if(typeof ac.createStereoPanner !== 'undefined') {\r\n p5.Panner = function (input, output) {\r\n this.stereoPanner = this.input = ac.createStereoPanner();\r\n input.connect(this.stereoPanner);\r\n this.stereoPanner.connect(output);\r\n };\r\n\r\n p5.Panner.prototype.pan = function(val, tFromNow) {\r\n var time = tFromNow || 0;\r\n var t = ac.currentTime + time;\r\n\r\n this.stereoPanner.pan.linearRampToValueAtTime(val, t);\r\n };\r\n\r\n //not implemented because stereopanner\r\n //node does not require this and will automatically\r\n //convert single channel or multichannel to stereo.\r\n //tested with single and stereo, not with (>2) multichannel\r\n p5.Panner.prototype.inputChannels = function() {};\r\n\r\n p5.Panner.prototype.connect = function(obj) {\r\n this.stereoPanner.connect(obj);\r\n };\r\n\r\n p5.Panner.prototype.disconnect = function() {\r\n if (this.stereoPanner) {\r\n this.stereoPanner.disconnect();\r\n }\r\n };\r\n\r\n } else {\r\n // if there is no createStereoPanner object\r\n // such as in safari 7.1.7 at the time of writing this\r\n // use this method to create the effect\r\n p5.Panner = function(input, output, numInputChannels) {\r\n this.input = ac.createGain();\r\n input.connect(this.input);\r\n\r\n this.left = ac.createGain();\r\n this.right = ac.createGain();\r\n this.left.channelInterpretation = 'discrete';\r\n this.right.channelInterpretation = 'discrete';\r\n\r\n // if input is stereo\r\n if (numInputChannels > 1) {\r\n this.splitter = ac.createChannelSplitter(2);\r\n this.input.connect(this.splitter);\r\n\r\n this.splitter.connect(this.left, 1);\r\n this.splitter.connect(this.right, 0);\r\n }\r\n else {\r\n this.input.connect(this.left);\r\n this.input.connect(this.right);\r\n }\r\n\r\n this.output = ac.createChannelMerger(2);\r\n this.left.connect(this.output, 0, 1);\r\n this.right.connect(this.output, 0, 0);\r\n this.output.connect(output);\r\n };\r\n\r\n // -1 is left, +1 is right\r\n p5.Panner.prototype.pan = function(val, tFromNow) {\r\n var time = tFromNow || 0;\r\n var t = ac.currentTime + time;\r\n var v = (val + 1) / 2;\r\n var rightVal = Math.cos(v*Math.PI/2);\r\n var leftVal = Math.sin(v * Math.PI/2);\r\n this.left.gain.linearRampToValueAtTime(leftVal, t);\r\n this.right.gain.linearRampToValueAtTime(rightVal, t);\r\n };\r\n\r\n p5.Panner.prototype.inputChannels = function(numChannels) {\r\n if (numChannels === 1) {\r\n this.input.disconnect();\r\n this.input.connect(this.left);\r\n this.input.connect(this.right);\r\n } else if (numChannels === 2) {\r\n if (typeof(this.splitter === 'undefined')) {\r\n this.splitter = ac.createChannelSplitter(2);\r\n }\r\n this.input.disconnect();\r\n this.input.connect(this.splitter);\r\n this.splitter.connect(this.left, 1);\r\n this.splitter.connect(this.right, 0);\r\n }\r\n };\r\n\r\n p5.Panner.prototype.connect = function(obj) {\r\n this.output.connect(obj);\r\n };\r\n\r\n p5.Panner.prototype.disconnect = function() {\r\n if (this.output) {\r\n this.output.disconnect();\r\n }\r\n };\r\n }\r\n});\r\n","'use strict';\r\n\r\ndefine(function (require) {\r\n\r\n var CustomError = require('errorHandler');\r\n var p5sound = require('master');\r\n var ac = p5sound.audiocontext;\r\n var midiToFreq = require('helpers').midiToFreq;\r\n var convertToWav = require('helpers').convertToWav;\r\n var processorNames = require('./audioWorklet/processorNames');\r\n\r\n /**\r\n *
SoundFile object with a path to a file.
\r\n *\r\n *
The p5.SoundFile may not be available immediately because\r\n * it loads the file information asynchronously.
\r\n *\r\n *
To do something with the sound as soon as it loads\r\n * pass the name of a function as the second parameter.
\r\n *\r\n *
Only one file path is required. However, audio file formats\r\n * (i.e. mp3, ogg, wav and m4a/aac) are not supported by all\r\n * web browsers. If you want to ensure compatability, instead of a single\r\n * file path, you may include an Array of filepaths, and the browser will\r\n * choose a format that works.
\r\n *\r\n * @class p5.SoundFile\r\n * @constructor\r\n * @param {String|Array} path path to a sound file (String). Optionally,\r\n * you may include multiple file formats in\r\n * an array. Alternately, accepts an object\r\n * from the HTML5 File API, or a p5.File.\r\n * @param {Function} [successCallback] Name of a function to call once file loads\r\n * @param {Function} [errorCallback] Name of a function to call if file fails to\r\n * load. This function will receive an error or\r\n * XMLHttpRequest object with information\r\n * about what went wrong.\r\n * @param {Function} [whileLoadingCallback] Name of a function to call while file\r\n * is loading. That function will\r\n * receive progress of the request to\r\n * load the sound file\r\n * (between 0 and 1) as its first\r\n * parameter. This progress\r\n * does not account for the additional\r\n * time needed to decode the audio data.\r\n *\r\n * @example\r\n *
\r\n */\r\n p5.SoundFile = function(paths, onload, onerror, whileLoading) {\r\n if (typeof paths !== 'undefined') {\r\n if (typeof paths === 'string' || typeof paths[0] === 'string') {\r\n var path = p5.prototype._checkFileFormats(paths);\r\n this.url = path;\r\n }\r\n else if(typeof paths === 'object') {\r\n if (!(window.File && window.FileReader && window.FileList && window.Blob)) {\r\n // The File API isn't supported in this browser\r\n throw 'Unable to load file because the File API is not supported';\r\n }\r\n }\r\n\r\n // if type is a p5.File...get the actual file\r\n if (paths.file) {\r\n paths = paths.file;\r\n }\r\n\r\n this.file = paths;\r\n }\r\n\r\n // private _onended callback, set by the method: onended(callback)\r\n this._onended = function() {};\r\n\r\n this._looping = false;\r\n this._playing = false;\r\n this._paused = false;\r\n this._pauseTime = 0;\r\n\r\n // cues for scheduling events with addCue() removeCue()\r\n this._cues = [];\r\n this._cueIDCounter = 0;\r\n\r\n // position of the most recently played sample\r\n this._lastPos = 0;\r\n this._counterNode = null;\r\n this._workletNode = null;\r\n\r\n // array of sources so that they can all be stopped!\r\n this.bufferSourceNodes = [];\r\n\r\n // current source\r\n this.bufferSourceNode = null;\r\n\r\n this.buffer = null;\r\n this.playbackRate = 1;\r\n\r\n this.input = p5sound.audiocontext.createGain();\r\n this.output = p5sound.audiocontext.createGain();\r\n\r\n this.reversed = false;\r\n\r\n // start and end of playback / loop\r\n this.startTime = 0;\r\n this.endTime = null;\r\n this.pauseTime = 0;\r\n\r\n // \"restart\" would stop playback before retriggering\r\n this.mode = 'sustain';\r\n\r\n // time that playback was started, in millis\r\n this.startMillis = null;\r\n\r\n // stereo panning\r\n this.panPosition = 0.0;\r\n this.panner = new p5.Panner(this.output, p5sound.input, 2);\r\n\r\n // it is possible to instantiate a soundfile with no path\r\n if (this.url || this.file) {\r\n this.load(onload, onerror);\r\n }\r\n\r\n // add this p5.SoundFile to the soundArray\r\n p5sound.soundArray.push(this);\r\n\r\n if (typeof whileLoading === 'function') {\r\n this._whileLoading = whileLoading;\r\n } else {\r\n this._whileLoading = function() {};\r\n }\r\n\r\n this._onAudioProcess = _onAudioProcess.bind(this);\r\n this._clearOnEnd = _clearOnEnd.bind(this);\r\n };\r\n\r\n // register preload handling of loadSound\r\n p5.prototype.registerPreloadMethod('loadSound', p5.prototype);\r\n\r\n /**\r\n * loadSound() returns a new p5.SoundFile from a specified\r\n * path. If called during preload(), the p5.SoundFile will be ready\r\n * to play in time for setup() and draw(). If called outside of\r\n * preload, the p5.SoundFile will not be ready immediately, so\r\n * loadSound accepts a callback as the second parameter. Using a\r\n * \r\n * local server is recommended when loading external files.\r\n *\r\n * @method loadSound\r\n * @for p5\r\n * @param {String|Array} path Path to the sound file, or an array with\r\n * paths to soundfiles in multiple formats\r\n * i.e. ['sound.ogg', 'sound.mp3'].\r\n * Alternately, accepts an object: either\r\n * from the HTML5 File API, or a p5.File.\r\n * @param {Function} [successCallback] Name of a function to call once file loads\r\n * @param {Function} [errorCallback] Name of a function to call if there is\r\n * an error loading the file.\r\n * @param {Function} [whileLoading] Name of a function to call while file is loading.\r\n * This function will receive the percentage loaded\r\n * so far, from 0.0 to 1.0.\r\n * @return {SoundFile} Returns a p5.SoundFile\r\n * @example\r\n *
\r\n */\r\n p5.prototype.loadSound = function(path, callback, onerror, whileLoading) {\r\n // if loading locally without a server\r\n if (window.location.origin.indexOf('file://') > -1 && window.cordova === 'undefined' ) {\r\n window.alert('This sketch may require a server to load external files. Please see http://bit.ly/1qcInwS');\r\n }\r\n\r\n var self = this;\r\n var s = new p5.SoundFile(path, function() {\r\n if(typeof callback === 'function') {\r\n callback.apply(self, arguments);\r\n }\r\n\r\n if (typeof self._decrementPreload === 'function') {\r\n self._decrementPreload();\r\n }\r\n }, onerror, whileLoading);\r\n\r\n return s;\r\n };\r\n\r\n /**\r\n * This is a helper function that the p5.SoundFile calls to load\r\n * itself. Accepts a callback (the name of another function)\r\n * as an optional parameter.\r\n *\r\n * @private\r\n * @for p5.SoundFile\r\n * @param {Function} [successCallback] Name of a function to call once file loads\r\n * @param {Function} [errorCallback] Name of a function to call if there is an error\r\n */\r\n p5.SoundFile.prototype.load = function(callback, errorCallback) {\r\n var self = this;\r\n var errorTrace = new Error().stack;\r\n\r\n if (this.url !== undefined && this.url !== '') {\r\n var request = new XMLHttpRequest();\r\n request.addEventListener('progress', function(evt) {\r\n self._updateProgress(evt);\r\n }, false);\r\n request.open('GET', this.url, true);\r\n request.responseType = 'arraybuffer';\r\n\r\n request.onload = function() {\r\n if (request.status === 200) {\r\n // on sucess loading file:\r\n if (!self.panner) return;\r\n ac.decodeAudioData(request.response,\r\n // success decoding buffer:\r\n function(buff) {\r\n if (!self.panner) return;\r\n self.buffer = buff;\r\n self.panner.inputChannels(buff.numberOfChannels);\r\n if (callback) {\r\n callback(self);\r\n }\r\n },\r\n // error decoding buffer. \"e\" is undefined in Chrome 11/22/2015\r\n function() {\r\n if (!self.panner) return;\r\n var err = new CustomError('decodeAudioData', errorTrace, self.url);\r\n var msg = 'AudioContext error at decodeAudioData for ' + self.url;\r\n if (errorCallback) {\r\n err.msg = msg;\r\n errorCallback(err);\r\n } else {\r\n console.error(msg +'\\n The error stack trace includes: \\n' + err.stack);\r\n }\r\n }\r\n );\r\n }\r\n // if request status != 200, it failed\r\n else {\r\n if (!self.panner) return;\r\n var err = new CustomError('loadSound', errorTrace, self.url);\r\n var msg = 'Unable to load ' + self.url + '. The request status was: ' +\r\n request.status + ' (' + request.statusText + ')';\r\n\r\n if (errorCallback) {\r\n err.message = msg;\r\n errorCallback(err);\r\n } else {\r\n console.error(msg +'\\n The error stack trace includes: \\n' + err.stack);\r\n }\r\n }\r\n };\r\n\r\n // if there is another error, aside from 404...\r\n request.onerror = function() {\r\n var err = new CustomError('loadSound', errorTrace, self.url);\r\n var msg = 'There was no response from the server at ' + self.url + '. Check the url and internet connectivity.';\r\n\r\n if (errorCallback) {\r\n err.message = msg;\r\n errorCallback(err);\r\n } else {\r\n console.error(msg +'\\n The error stack trace includes: \\n' + err.stack);\r\n }\r\n };\r\n\r\n request.send();\r\n }\r\n else if (this.file !== undefined) {\r\n var reader = new FileReader();\r\n reader.onload = function() {\r\n if (!self.panner) return;\r\n ac.decodeAudioData(reader.result, function(buff) {\r\n if (!self.panner) return;\r\n self.buffer = buff;\r\n self.panner.inputChannels(buff.numberOfChannels);\r\n if (callback) {\r\n callback(self);\r\n }\r\n });\r\n };\r\n reader.onerror = function(e) {\r\n if (!self.panner) return;\r\n if (onerror) {\r\n onerror(e);\r\n }\r\n };\r\n reader.readAsArrayBuffer(this.file);\r\n }\r\n };\r\n\r\n // TO DO: use this method to create a loading bar that shows progress during file upload/decode.\r\n p5.SoundFile.prototype._updateProgress = function(evt) {\r\n if (evt.lengthComputable) {\r\n var percentComplete = evt.loaded / evt.total * 0.99;\r\n this._whileLoading(percentComplete, evt);\r\n // ...\r\n } else {\r\n // Unable to compute progress information since the total size is unknown\r\n this._whileLoading('size unknown');\r\n }\r\n };\r\n\r\n /**\r\n * Returns true if the sound file finished loading successfully.\r\n *\r\n * @method isLoaded\r\n * @for p5.SoundFile\r\n * @return {Boolean}\r\n */\r\n p5.SoundFile.prototype.isLoaded = function() {\r\n if (this.buffer) {\r\n return true;\r\n } else {\r\n return false;\r\n }\r\n };\r\n\r\n /**\r\n * Play the p5.SoundFile\r\n *\r\n * @method play\r\n * @for p5.SoundFile\r\n * @param {Number} [startTime] (optional) schedule playback to start (in seconds from now).\r\n * @param {Number} [rate] (optional) playback rate\r\n * @param {Number} [amp] (optional) amplitude (volume)\r\n * of playback\r\n * @param {Number} [cueStart] (optional) cue start time in seconds\r\n * @param {Number} [duration] (optional) duration of playback in seconds\r\n */\r\n p5.SoundFile.prototype.play = function(startTime, rate, amp, _cueStart, duration) {\r\n if (!this.output) {\r\n console.warn('SoundFile.play() called after dispose');\r\n return;\r\n }\r\n\r\n var self = this;\r\n var now = p5sound.audiocontext.currentTime;\r\n var cueStart, cueEnd;\r\n var time = startTime || 0;\r\n if (time < 0) {\r\n time = 0;\r\n }\r\n\r\n time = time + now;\r\n\r\n if (typeof rate !== 'undefined') {\r\n this.rate(rate);\r\n }\r\n\r\n if (typeof amp !== 'undefined') {\r\n this.setVolume(amp);\r\n }\r\n\r\n // TO DO: if already playing, create array of buffers for easy stop()\r\n if (this.buffer) {\r\n\r\n // reset the pause time (if it was paused)\r\n this._pauseTime = 0;\r\n\r\n // handle restart playmode\r\n if (this.mode === 'restart' && this.buffer && this.bufferSourceNode) {\r\n this.bufferSourceNode.stop(time);\r\n this._counterNode.stop(time);\r\n }\r\n\r\n //dont create another instance if already playing\r\n if (this.mode === 'untildone' && this.isPlaying()) {\r\n return;\r\n }\r\n // make a new source and counter. They are automatically assigned playbackRate and buffer\r\n this.bufferSourceNode = this._initSourceNode();\r\n\r\n // garbage collect counterNode and create a new one\r\n delete this._counterNode;\r\n this._counterNode = this._initCounterNode();\r\n\r\n if (_cueStart) {\r\n if (_cueStart >=0 && _cueStart < this.buffer.duration) {\r\n // this.startTime = cueStart;\r\n cueStart = _cueStart;\r\n } else { throw 'start time out of range'; }\r\n } else {\r\n cueStart = 0;\r\n }\r\n\r\n if (duration) {\r\n // if duration is greater than buffer.duration, just play entire file anyway rather than throw an error\r\n duration = duration <= this.buffer.duration - cueStart ? duration : this.buffer.duration;\r\n }\r\n\r\n // if it was paused, play at the pause position\r\n if (this._paused) {\r\n this.bufferSourceNode.start(time, this.pauseTime, duration);\r\n this._counterNode.start(time, this.pauseTime, duration);\r\n } else {\r\n this.bufferSourceNode.start(time, cueStart, duration);\r\n this._counterNode.start(time, cueStart, duration);\r\n }\r\n\r\n this._playing = true;\r\n this._paused = false;\r\n\r\n // add source to sources array, which is used in stopAll()\r\n this.bufferSourceNodes.push(this.bufferSourceNode);\r\n this.bufferSourceNode._arrayIndex = this.bufferSourceNodes.length - 1;\r\n\r\n this.bufferSourceNode.addEventListener('ended', this._clearOnEnd);\r\n }\r\n // If soundFile hasn't loaded the buffer yet, throw an error\r\n else {\r\n throw 'not ready to play file, buffer has yet to load. Try preload()';\r\n }\r\n\r\n // if looping, will restart at original time\r\n this.bufferSourceNode.loop = this._looping;\r\n this._counterNode.loop = this._looping;\r\n\r\n if (this._looping === true) {\r\n cueEnd = duration ? duration : cueStart - 0.000000000000001;\r\n this.bufferSourceNode.loopStart = cueStart;\r\n this.bufferSourceNode.loopEnd = cueEnd;\r\n this._counterNode.loopStart = cueStart;\r\n this._counterNode.loopEnd = cueEnd;\r\n }\r\n };\r\n\r\n\r\n /**\r\n * p5.SoundFile has two play modes: restart and\r\n * sustain. Play Mode determines what happens to a\r\n * p5.SoundFile if it is triggered while in the middle of playback.\r\n * In sustain mode, playback will continue simultaneous to the\r\n * new playback. In restart mode, play() will stop playback\r\n * and start over. With untilDone, a sound will play only if it's\r\n * not already playing. Sustain is the default mode.\r\n *\r\n * @method playMode\r\n * @for p5.SoundFile\r\n * @param {String} str 'restart' or 'sustain' or 'untilDone'\r\n * @example\r\n *
\r\n * var mySound;\r\n * function preload(){\r\n * mySound = loadSound('assets/Damscray_DancingTiger.mp3');\r\n * }\r\n * function mouseClicked() {\r\n * mySound.playMode('sustain');\r\n * mySound.play();\r\n * }\r\n * function keyPressed() {\r\n * mySound.playMode('restart');\r\n * mySound.play();\r\n * }\r\n *\r\n *
\r\n */\r\n p5.SoundFile.prototype.playMode = function(str) {\r\n var s = str.toLowerCase();\r\n\r\n // if restart, stop all other sounds from playing\r\n if (s === 'restart' && this.buffer && this.bufferSourceNode) {\r\n for (var i = 0; i < this.bufferSourceNodes.length - 1; i++) {\r\n var now = p5sound.audiocontext.currentTime;\r\n this.bufferSourceNodes[i].stop(now);\r\n }\r\n }\r\n\r\n // set play mode to effect future playback\r\n if (s === 'restart' || s === 'sustain' || s === 'untildone') {\r\n this.mode = s;\r\n } else {\r\n throw 'Invalid play mode. Must be either \"restart\" or \"sustain\"';\r\n }\r\n };\r\n\r\n /**\r\n * Pauses a file that is currently playing. If the file is not\r\n * playing, then nothing will happen.\r\n *\r\n * After pausing, .play() will resume from the paused\r\n * position.\r\n * If p5.SoundFile had been set to loop before it was paused,\r\n * it will continue to loop after it is unpaused with .play().\r\n *\r\n * @method pause\r\n * @for p5.SoundFile\r\n * @param {Number} [startTime] (optional) schedule event to occur\r\n * seconds from now\r\n * @example\r\n *
\r\n */\r\n p5.SoundFile.prototype.pause = function(startTime) {\r\n var now = p5sound.audiocontext.currentTime;\r\n var time = startTime || 0;\r\n var pTime = time + now;\r\n\r\n if (this.isPlaying() && this.buffer && this.bufferSourceNode) {\r\n this.pauseTime = this.currentTime();\r\n this.bufferSourceNode.stop(pTime);\r\n this._counterNode.stop(pTime);\r\n this._paused = true;\r\n this._playing = false;\r\n\r\n this._pauseTime = this.currentTime();\r\n // TO DO: make sure play() still starts from orig start position\r\n } else {\r\n this._pauseTime = 0;\r\n }\r\n };\r\n\r\n /**\r\n * Loop the p5.SoundFile. Accepts optional parameters to set the\r\n * playback rate, playback volume, loopStart, loopEnd.\r\n *\r\n * @method loop\r\n * @for p5.SoundFile\r\n * @param {Number} [startTime] (optional) schedule event to occur\r\n * seconds from now\r\n * @param {Number} [rate] (optional) playback rate\r\n * @param {Number} [amp] (optional) playback volume\r\n * @param {Number} [cueLoopStart] (optional) startTime in seconds\r\n * @param {Number} [duration] (optional) loop duration in seconds\r\n */\r\n p5.SoundFile.prototype.loop = function(startTime, rate, amp, loopStart, duration) {\r\n this._looping = true;\r\n this.play(startTime, rate, amp, loopStart, duration);\r\n };\r\n\r\n /**\r\n * Set a p5.SoundFile's looping flag to true or false. If the sound\r\n * is currently playing, this change will take effect when it\r\n * reaches the end of the current playback.\r\n *\r\n * @method setLoop\r\n * @for p5.SoundFile\r\n * @param {Boolean} Boolean set looping to true or false\r\n */\r\n p5.SoundFile.prototype.setLoop = function(bool) {\r\n if (bool === true) {\r\n this._looping = true;\r\n }\r\n else if (bool === false) {\r\n this._looping = false;\r\n }\r\n else {\r\n throw 'Error: setLoop accepts either true or false';\r\n }\r\n if (this.bufferSourceNode) {\r\n this.bufferSourceNode.loop = this._looping;\r\n this._counterNode.loop = this._looping;\r\n }\r\n };\r\n\r\n /**\r\n * Returns 'true' if a p5.SoundFile is currently looping and playing, 'false' if not.\r\n *\r\n * @method isLooping\r\n * @for p5.SoundFile\r\n * @return {Boolean}\r\n */\r\n p5.SoundFile.prototype.isLooping = function() {\r\n if (!this.bufferSourceNode) {\r\n return false;\r\n }\r\n if (this._looping === true && this.isPlaying() === true) {\r\n return true;\r\n }\r\n return false;\r\n };\r\n\r\n /**\r\n * Returns true if a p5.SoundFile is playing, false if not (i.e.\r\n * paused or stopped).\r\n *\r\n * @method isPlaying\r\n * @for p5.SoundFile\r\n * @return {Boolean}\r\n */\r\n p5.SoundFile.prototype.isPlaying = function() {\r\n return this._playing;\r\n };\r\n\r\n /**\r\n * Returns true if a p5.SoundFile is paused, false if not (i.e.\r\n * playing or stopped).\r\n *\r\n * @method isPaused\r\n * @for p5.SoundFile\r\n * @return {Boolean}\r\n */\r\n p5.SoundFile.prototype.isPaused = function() {\r\n return this._paused;\r\n };\r\n\r\n /**\r\n * Stop soundfile playback.\r\n *\r\n * @method stop\r\n * @for p5.SoundFile\r\n * @param {Number} [startTime] (optional) schedule event to occur\r\n * in seconds from now\r\n */\r\n p5.SoundFile.prototype.stop = function(timeFromNow) {\r\n var time = timeFromNow || 0;\r\n\r\n if (this.mode === 'sustain' || this.mode === 'untildone') {\r\n this.stopAll(time);\r\n this._playing = false;\r\n this.pauseTime = 0;\r\n this._paused = false;\r\n }\r\n else if (this.buffer && this.bufferSourceNode) {\r\n var now = p5sound.audiocontext.currentTime;\r\n var t = time || 0;\r\n this.pauseTime = 0;\r\n this.bufferSourceNode.stop(now + t);\r\n this._counterNode.stop(now + t);\r\n this._playing = false;\r\n this._paused = false;\r\n }\r\n };\r\n\r\n /**\r\n * Stop playback on all of this soundfile's sources.\r\n * @private\r\n */\r\n p5.SoundFile.prototype.stopAll = function(_time) {\r\n var now = p5sound.audiocontext.currentTime;\r\n var time = _time || 0;\r\n if (this.buffer && this.bufferSourceNode) {\r\n for (var i in this.bufferSourceNodes) {\r\n const bufferSourceNode = this.bufferSourceNodes[i];\r\n if (!!bufferSourceNode) {\r\n try {\r\n bufferSourceNode.stop(now + time);\r\n } catch(e) {\r\n // this was throwing errors only on Safari\r\n }\r\n }\r\n }\r\n this._counterNode.stop(now + time);\r\n this._onended(this);\r\n }\r\n };\r\n\r\n /**\r\n * Multiply the output volume (amplitude) of a sound file\r\n * between 0.0 (silence) and 1.0 (full volume).\r\n * 1.0 is the maximum amplitude of a digital sound, so multiplying\r\n * by greater than 1.0 may cause digital distortion. To\r\n * fade, provide a rampTime parameter. For more\r\n * complex fades, see the Envelope class.\r\n *\r\n * Alternately, you can pass in a signal source such as an\r\n * oscillator to modulate the amplitude with an audio signal.\r\n *\r\n * @method setVolume\r\n * @for p5.SoundFile\r\n * @param {Number|Object} volume Volume (amplitude) between 0.0\r\n * and 1.0 or modulating signal/oscillator\r\n * @param {Number} [rampTime] Fade for t seconds\r\n * @param {Number} [timeFromNow] Schedule this event to happen at\r\n * t seconds in the future\r\n */\r\n p5.SoundFile.prototype.setVolume = function(vol, _rampTime, _tFromNow) {\r\n if (typeof vol === 'number') {\r\n var rampTime = _rampTime || 0;\r\n var tFromNow = _tFromNow || 0;\r\n var now = p5sound.audiocontext.currentTime;\r\n var currentVol = this.output.gain.value;\r\n this.output.gain.cancelScheduledValues(now + tFromNow);\r\n this.output.gain.linearRampToValueAtTime(currentVol, now + tFromNow);\r\n this.output.gain.linearRampToValueAtTime(vol, now + tFromNow + rampTime);\r\n }\r\n else if (vol) {\r\n vol.connect(this.output.gain);\r\n } else {\r\n // return the Gain Node\r\n return this.output.gain;\r\n }\r\n };\r\n\r\n // same as setVolume, to match Processing Sound\r\n p5.SoundFile.prototype.amp = p5.SoundFile.prototype.setVolume;\r\n\r\n // these are the same thing\r\n p5.SoundFile.prototype.fade = p5.SoundFile.prototype.setVolume;\r\n\r\n p5.SoundFile.prototype.getVolume = function() {\r\n return this.output.gain.value;\r\n };\r\n\r\n /**\r\n * Set the stereo panning of a p5.sound object to\r\n * a floating point number between -1.0 (left) and 1.0 (right).\r\n * Default is 0.0 (center).\r\n *\r\n * @method pan\r\n * @for p5.SoundFile\r\n * @param {Number} [panValue] Set the stereo panner\r\n * @param {Number} [timeFromNow] schedule this event to happen\r\n * seconds from now\r\n * @example\r\n *
\r\n *\r\n * var ball = {};\r\n * var soundFile;\r\n *\r\n * function preload() {\r\n * soundFormats('ogg', 'mp3');\r\n * soundFile = loadSound('assets/beatbox.mp3');\r\n * }\r\n *\r\n * function draw() {\r\n * background(0);\r\n * ball.x = constrain(mouseX, 0, width);\r\n * ellipse(ball.x, height/2, 20, 20)\r\n * }\r\n *\r\n * function mousePressed(){\r\n * // map the ball's x location to a panning degree\r\n * // between -1.0 (left) and 1.0 (right)\r\n * var panning = map(ball.x, 0., width,-1.0, 1.0);\r\n * soundFile.pan(panning);\r\n * soundFile.play();\r\n * }\r\n *
\r\n */\r\n p5.SoundFile.prototype.pan = function(pval, tFromNow) {\r\n this.panPosition = pval;\r\n this.panner.pan(pval, tFromNow);\r\n };\r\n\r\n /**\r\n * Returns the current stereo pan position (-1.0 to 1.0)\r\n *\r\n * @method getPan\r\n * @for p5.SoundFile\r\n * @return {Number} Returns the stereo pan setting of the Oscillator\r\n * as a number between -1.0 (left) and 1.0 (right).\r\n * 0.0 is center and default.\r\n */\r\n p5.SoundFile.prototype.getPan = function() {\r\n return this.panPosition;\r\n };\r\n\r\n /**\r\n * Set the playback rate of a sound file. Will change the speed and the pitch.\r\n * Values less than zero will reverse the audio buffer.\r\n *\r\n * @method rate\r\n * @for p5.SoundFile\r\n * @param {Number} [playbackRate] Set the playback rate. 1.0 is normal,\r\n * .5 is half-speed, 2.0 is twice as fast.\r\n * Values less than zero play backwards.\r\n * @example\r\n *
\r\n * var song;\r\n *\r\n * function preload() {\r\n * song = loadSound('assets/Damscray_DancingTiger.mp3');\r\n * }\r\n *\r\n * function setup() {\r\n * song.loop();\r\n * }\r\n *\r\n * function draw() {\r\n * background(200);\r\n *\r\n * // Set the rate to a range between 0.1 and 4\r\n * // Changing the rate also alters the pitch\r\n * var speed = map(mouseY, 0.1, height, 0, 2);\r\n * speed = constrain(speed, 0.01, 4);\r\n * song.rate(speed);\r\n *\r\n * // Draw a circle to show what is going on\r\n * stroke(0);\r\n * fill(51, 100);\r\n * ellipse(mouseX, 100, 48, 48);\r\n * }\r\n *\r\n * \r\n *
\r\n *\r\n */\r\n p5.SoundFile.prototype.rate = function(playbackRate) {\r\n var reverse = false;\r\n if (typeof playbackRate === 'undefined') {\r\n return this.playbackRate;\r\n }\r\n\r\n this.playbackRate = playbackRate;\r\n\r\n if (playbackRate === 0) {\r\n playbackRate = 0.0000000000001;\r\n }\r\n\r\n else if (playbackRate < 0 && !this.reversed) {\r\n playbackRate = Math.abs(playbackRate);\r\n reverse = true;\r\n }\r\n\r\n else if (playbackRate > 0 && this.reversed) {\r\n reverse = true;\r\n }\r\n\r\n if (this.bufferSourceNode) {\r\n var now = p5sound.audiocontext.currentTime;\r\n this.bufferSourceNode.playbackRate.cancelScheduledValues(now);\r\n this.bufferSourceNode.playbackRate.linearRampToValueAtTime(Math.abs(playbackRate), now);\r\n this._counterNode.playbackRate.cancelScheduledValues(now);\r\n this._counterNode.playbackRate.linearRampToValueAtTime(Math.abs(playbackRate), now);\r\n }\r\n\r\n if (reverse) {\r\n this.reverseBuffer();\r\n }\r\n return this.playbackRate;\r\n };\r\n\r\n // TO DO: document this\r\n p5.SoundFile.prototype.setPitch = function(num) {\r\n var newPlaybackRate = midiToFreq(num) / midiToFreq(60);\r\n this.rate(newPlaybackRate);\r\n };\r\n\r\n p5.SoundFile.prototype.getPlaybackRate = function() {\r\n return this.playbackRate;\r\n };\r\n\r\n /**\r\n * Returns the duration of a sound file in seconds.\r\n *\r\n * @method duration\r\n * @for p5.SoundFile\r\n * @return {Number} The duration of the soundFile in seconds.\r\n */\r\n p5.SoundFile.prototype.duration = function() {\r\n // Return Duration\r\n if (this.buffer) {\r\n return this.buffer.duration;\r\n } else {\r\n return 0;\r\n }\r\n };\r\n\r\n /**\r\n * Return the current position of the p5.SoundFile playhead, in seconds.\r\n * Time is relative to the normal buffer direction, so if `reverseBuffer`\r\n * has been called, currentTime will count backwards.\r\n *\r\n * @method currentTime\r\n * @for p5.SoundFile\r\n * @return {Number} currentTime of the soundFile in seconds.\r\n */\r\n p5.SoundFile.prototype.currentTime = function() {\r\n return this.reversed\r\n ? Math.abs(this._lastPos - this.buffer.length) / ac.sampleRate\r\n : this._lastPos / ac.sampleRate;\r\n };\r\n\r\n /**\r\n * Move the playhead of the song to a position, in seconds. Start timing\r\n * and playback duration. If none are given, will reset the file to play\r\n * entire duration from start to finish.\r\n *\r\n * @method jump\r\n * @for p5.SoundFile\r\n * @param {Number} cueTime cueTime of the soundFile in seconds.\r\n * @param {Number} duration duration in seconds.\r\n */\r\n p5.SoundFile.prototype.jump = function(cueTime, duration) {\r\n if (cueTime < 0 || cueTime > this.buffer.duration) {\r\n throw 'jump time out of range';\r\n }\r\n if (duration > this.buffer.duration - cueTime) {\r\n throw 'end time out of range';\r\n }\r\n\r\n var cTime = cueTime || 0;\r\n var dur = duration || undefined;\r\n if (this.isPlaying()) {\r\n this.stop(0);\r\n }\r\n this.play(0, this.playbackRate, this.output.gain.value, cTime, dur);\r\n };\r\n\r\n /**\r\n * Return the number of channels in a sound file.\r\n * For example, Mono = 1, Stereo = 2.\r\n *\r\n * @method channels\r\n * @for p5.SoundFile\r\n * @return {Number} [channels]\r\n */\r\n p5.SoundFile.prototype.channels = function() {\r\n return this.buffer.numberOfChannels;\r\n };\r\n\r\n /**\r\n * Return the sample rate of the sound file.\r\n *\r\n * @method sampleRate\r\n * @for p5.SoundFile\r\n * @return {Number} [sampleRate]\r\n */\r\n p5.SoundFile.prototype.sampleRate = function() {\r\n return this.buffer.sampleRate;\r\n };\r\n\r\n /**\r\n * Return the number of samples in a sound file.\r\n * Equal to sampleRate * duration.\r\n *\r\n * @method frames\r\n * @for p5.SoundFile\r\n * @return {Number} [sampleCount]\r\n */\r\n p5.SoundFile.prototype.frames = function() {\r\n return this.buffer.length;\r\n };\r\n\r\n /**\r\n * Returns an array of amplitude peaks in a p5.SoundFile that can be\r\n * used to draw a static waveform. Scans through the p5.SoundFile's\r\n * audio buffer to find the greatest amplitudes. Accepts one\r\n * parameter, 'length', which determines size of the array.\r\n * Larger arrays result in more precise waveform visualizations.\r\n *\r\n * Inspired by Wavesurfer.js.\r\n *\r\n * @method getPeaks\r\n * @for p5.SoundFile\r\n * @params {Number} [length] length is the size of the returned array.\r\n * Larger length results in more precision.\r\n * Defaults to 5*width of the browser window.\r\n * @returns {Float32Array} Array of peaks.\r\n */\r\n p5.SoundFile.prototype.getPeaks = function(length) {\r\n\r\n if (this.buffer) {\r\n // set length to window's width if no length is provided\r\n if (!length) {\r\n length = window.width*5;\r\n }\r\n if (this.buffer) {\r\n var buffer = this.buffer;\r\n var sampleSize = buffer.length / length;\r\n var sampleStep = ~~(sampleSize / 10) || 1;\r\n var channels = buffer.numberOfChannels;\r\n var peaks = new Float32Array(Math.round(length));\r\n\r\n for (var c = 0; c < channels; c++) {\r\n var chan = buffer.getChannelData(c);\r\n for (var i = 0; i < length; i++) {\r\n var start = ~~(i*sampleSize);\r\n var end = ~~(start + sampleSize);\r\n var max = 0;\r\n for (var j = start; j < end; j+= sampleStep) {\r\n var value = chan[j];\r\n if (value > max) {\r\n max = value;\r\n // faster than Math.abs\r\n } else if (-value > max) {\r\n max = value;\r\n }\r\n }\r\n if (c === 0 || Math.abs(max) > peaks[i]) {\r\n peaks[i] = max;\r\n }\r\n }\r\n }\r\n\r\n return peaks;\r\n }\r\n }\r\n\r\n else {\r\n throw 'Cannot load peaks yet, buffer is not loaded';\r\n }\r\n };\r\n\r\n /**\r\n * Reverses the p5.SoundFile's buffer source.\r\n * Playback must be handled separately (see example).\r\n *\r\n * @method reverseBuffer\r\n * @for p5.SoundFile\r\n * @example\r\n *
\r\n * var drum;\r\n *\r\n * function preload() {\r\n * drum = loadSound('assets/drum.mp3');\r\n * }\r\n *\r\n * function setup() {\r\n * drum.reverseBuffer();\r\n * drum.play();\r\n * }\r\n *\r\n * \r\n *
\r\n */\r\n p5.SoundFile.prototype.reverseBuffer = function() {\r\n if (this.buffer) {\r\n var currentPos = this._lastPos / ac.sampleRate;\r\n var curVol = this.getVolume();\r\n this.setVolume(0, 0.001);\r\n\r\n const numChannels = this.buffer.numberOfChannels;\r\n for (var i = 0; i < numChannels; i++) {\r\n this.buffer.getChannelData(i).reverse();\r\n }\r\n // set reversed flag\r\n this.reversed = !this.reversed;\r\n\r\n if (currentPos) {\r\n this.jump(this.duration() - currentPos);\r\n }\r\n this.setVolume(curVol, 0.001);\r\n } else {\r\n throw 'SoundFile is not done loading';\r\n }\r\n };\r\n\r\n /**\r\n * Schedule an event to be called when the soundfile\r\n * reaches the end of a buffer. If the soundfile is\r\n * playing through once, this will be called when it\r\n * ends. If it is looping, it will be called when\r\n * stop is called.\r\n *\r\n * @method onended\r\n * @for p5.SoundFile\r\n * @param {Function} callback function to call when the\r\n * soundfile has ended.\r\n */\r\n p5.SoundFile.prototype.onended = function(callback) {\r\n this._onended = callback;\r\n return this;\r\n };\r\n\r\n p5.SoundFile.prototype.add = function() {\r\n // TO DO\r\n };\r\n\r\n p5.SoundFile.prototype.dispose = function() {\r\n var now = p5sound.audiocontext.currentTime;\r\n\r\n // remove reference to soundfile\r\n var index = p5sound.soundArray.indexOf(this);\r\n p5sound.soundArray.splice(index, 1);\r\n\r\n this.stop(now);\r\n if (this.buffer && this.bufferSourceNode) {\r\n for (var i = 0; i < this.bufferSourceNodes.length - 1; i++) {\r\n if (this.bufferSourceNodes[i] !== null) {\r\n this.bufferSourceNodes[i].disconnect();\r\n try {\r\n this.bufferSourceNodes[i].stop(now);\r\n } catch(e) {\r\n console.warning('no buffer source node to dispose');\r\n }\r\n this.bufferSourceNodes[i] = null;\r\n }\r\n }\r\n if ( this.isPlaying() ) {\r\n try {\r\n this._counterNode.stop(now);\r\n } catch(e) {\r\n console.log(e);\r\n }\r\n this._counterNode = null;\r\n }\r\n }\r\n if (this.output) {\r\n this.output.disconnect();\r\n this.output = null;\r\n }\r\n if (this.panner) {\r\n this.panner.disconnect();\r\n this.panner = null;\r\n }\r\n };\r\n\r\n /**\r\n * Connects the output of a p5sound object to input of another\r\n * p5.sound object. For example, you may connect a p5.SoundFile to an\r\n * FFT or an Effect. If no parameter is given, it will connect to\r\n * the master output. Most p5sound objects connect to the master\r\n * output when they are created.\r\n *\r\n * @method connect\r\n * @for p5.SoundFile\r\n * @param {Object} [object] Audio object that accepts an input\r\n */\r\n p5.SoundFile.prototype.connect = function(unit) {\r\n if (!unit) {\r\n this.panner.connect(p5sound.input);\r\n }\r\n else {\r\n if (unit.hasOwnProperty('input')) {\r\n this.panner.connect(unit.input);\r\n } else {\r\n this.panner.connect(unit);\r\n }\r\n }\r\n };\r\n\r\n /**\r\n * Disconnects the output of this p5sound object.\r\n *\r\n * @method disconnect\r\n * @for p5.SoundFile\r\n */\r\n p5.SoundFile.prototype.disconnect = function() {\r\n if (this.panner) {\r\n this.panner.disconnect();\r\n }\r\n };\r\n\r\n /**\r\n */\r\n p5.SoundFile.prototype.getLevel = function() {\r\n console.warn('p5.SoundFile.getLevel has been removed from the library. Use p5.Amplitude instead');\r\n };\r\n\r\n /**\r\n * Reset the source for this SoundFile to a\r\n * new path (URL).\r\n *\r\n * @method setPath\r\n * @for p5.SoundFile\r\n * @param {String} path path to audio file\r\n * @param {Function} callback Callback\r\n */\r\n p5.SoundFile.prototype.setPath = function(p, callback) {\r\n var path = p5.prototype._checkFileFormats(p);\r\n this.url = path;\r\n this.load(callback);\r\n };\r\n\r\n /**\r\n * Replace the current Audio Buffer with a new Buffer.\r\n *\r\n * @method setBuffer\r\n * @for p5.SoundFile\r\n * @param {Array} buf Array of Float32 Array(s). 2 Float32 Arrays\r\n * will create a stereo source. 1 will create\r\n * a mono source.\r\n */\r\n p5.SoundFile.prototype.setBuffer = function(buf) {\r\n var numChannels = buf.length;\r\n var size = buf[0].length;\r\n var newBuffer = ac.createBuffer(numChannels, size, ac.sampleRate);\r\n\r\n if (!(buf[0] instanceof Float32Array)) {\r\n buf[0] = new Float32Array(buf[0]);\r\n }\r\n\r\n for (var channelNum = 0; channelNum < numChannels; channelNum++) {\r\n var channel = newBuffer.getChannelData( channelNum );\r\n channel.set(buf[channelNum]);\r\n }\r\n\r\n this.buffer = newBuffer;\r\n\r\n // set numbers of channels on input to the panner\r\n this.panner.inputChannels(numChannels);\r\n };\r\n\r\n //////////////////////////////////////////////////\r\n // script processor node with an empty buffer to help\r\n // keep a sample-accurate position in playback buffer.\r\n // Inspired by Chinmay Pendharkar's technique for Sonoport --> http://bit.ly/1HwdCsV\r\n // Copyright [2015] [Sonoport (Asia) Pte. Ltd.],\r\n // Licensed under the Apache License http://apache.org/licenses/LICENSE-2.0\r\n ////////////////////////////////////////////////////////////////////////////////////\r\n\r\n var _createCounterBuffer = function(buffer) {\r\n const len = buffer.length;\r\n const audioBuf = ac.createBuffer( 1, buffer.length, ac.sampleRate );\r\n const arrayBuffer = audioBuf.getChannelData(0);\r\n for (var index = 0; index < len; index++) {\r\n arrayBuffer[index] = index;\r\n }\r\n return audioBuf;\r\n };\r\n\r\n // initialize counterNode, set its initial buffer and playbackRate\r\n p5.SoundFile.prototype._initCounterNode = function() {\r\n var self = this;\r\n var now = ac.currentTime;\r\n var cNode = ac.createBufferSource();\r\n\r\n // dispose of worklet node if it already exists\r\n if (self._workletNode) {\r\n self._workletNode.disconnect();\r\n delete self._workletNode;\r\n }\r\n self._workletNode = new AudioWorkletNode(ac, processorNames.soundFileProcessor);\r\n self._workletNode.port.onmessage = function(event) {\r\n if (event.data.name === 'position') {\r\n this._lastPos = event.data.position;\r\n\r\n // do any callbacks that have been scheduled\r\n this._onTimeUpdate(self._lastPos);\r\n }\r\n }.bind(self);\r\n\r\n // create counter buffer of the same length as self.buffer\r\n cNode.buffer = _createCounterBuffer( self.buffer );\r\n\r\n cNode.playbackRate.setValueAtTime(self.playbackRate, now);\r\n\r\n cNode.connect(self._workletNode);\r\n self._workletNode.connect(p5.soundOut._silentNode);\r\n\r\n return cNode;\r\n };\r\n\r\n // initialize sourceNode, set its initial buffer and playbackRate\r\n p5.SoundFile.prototype._initSourceNode = function() {\r\n var bufferSourceNode = ac.createBufferSource();\r\n bufferSourceNode.buffer = this.buffer;\r\n bufferSourceNode.playbackRate.value = this.playbackRate;\r\n bufferSourceNode.connect(this.output);\r\n return bufferSourceNode;\r\n };\r\n\r\n /**\r\n * processPeaks returns an array of timestamps where it thinks there is a beat.\r\n *\r\n * This is an asynchronous function that processes the soundfile in an offline audio context,\r\n * and sends the results to your callback function.\r\n *\r\n * The process involves running the soundfile through a lowpass filter, and finding all of the\r\n * peaks above the initial threshold. If the total number of peaks are below the minimum number of peaks,\r\n * it decreases the threshold and re-runs the analysis until either minPeaks or minThreshold are reached.\r\n *\r\n * @method processPeaks\r\n * @for p5.SoundFile\r\n * @param {Function} callback a function to call once this data is returned\r\n * @param {Number} [initThreshold] initial threshold defaults to 0.9\r\n * @param {Number} [minThreshold] minimum threshold defaults to 0.22\r\n * @param {Number} [minPeaks] minimum number of peaks defaults to 200\r\n * @return {Array} Array of timestamped peaks\r\n */\r\n p5.SoundFile.prototype.processPeaks = function(callback, _initThreshold, _minThreshold, _minPeaks) {\r\n var bufLen = this.buffer.length;\r\n var sampleRate = this.buffer.sampleRate;\r\n var buffer = this.buffer;\r\n var allPeaks = [];\r\n\r\n var initialThreshold = _initThreshold || 0.9,\r\n threshold = initialThreshold,\r\n minThreshold = _minThreshold || 0.22,\r\n minPeaks = _minPeaks || 200;\r\n\r\n // Create offline context\r\n var offlineContext = new window.OfflineAudioContext(1, bufLen, sampleRate);\r\n\r\n // create buffer source\r\n var source = offlineContext.createBufferSource();\r\n source.buffer = buffer;\r\n\r\n // Create filter. TO DO: allow custom setting of filter\r\n var filter = offlineContext.createBiquadFilter();\r\n filter.type = 'lowpass';\r\n source.connect(filter);\r\n filter.connect(offlineContext.destination);\r\n\r\n // start playing at time:0\r\n source.start(0);\r\n offlineContext.startRendering(); // Render the song\r\n\r\n // act on the result\r\n offlineContext.oncomplete = function(e) {\r\n if (!self.panner) return;\r\n var filteredBuffer = e.renderedBuffer;\r\n var bufferData = filteredBuffer.getChannelData(0);\r\n\r\n\r\n // step 1:\r\n // create Peak instances, add them to array, with strength and sampleIndex\r\n do {\r\n allPeaks = getPeaksAtThreshold(bufferData, threshold);\r\n threshold -= 0.005;\r\n } while (Object.keys(allPeaks).length < minPeaks && threshold >= minThreshold);\r\n\r\n\r\n // step 2:\r\n // find intervals for each peak in the sampleIndex, add tempos array\r\n var intervalCounts = countIntervalsBetweenNearbyPeaks(allPeaks);\r\n\r\n // step 3: find top tempos\r\n var groups = groupNeighborsByTempo(intervalCounts, filteredBuffer.sampleRate);\r\n\r\n // sort top intervals\r\n var topTempos = groups.sort(function(intA, intB) {\r\n return intB.count - intA.count;\r\n\r\n }).splice(0,5);\r\n\r\n // set this SoundFile's tempo to the top tempo ??\r\n this.tempo = topTempos[0].tempo;\r\n\r\n // step 4:\r\n // new array of peaks at top tempo within a bpmVariance\r\n var bpmVariance = 5;\r\n var tempoPeaks = getPeaksAtTopTempo(allPeaks, topTempos[0].tempo, filteredBuffer.sampleRate, bpmVariance);\r\n\r\n callback(tempoPeaks);\r\n };\r\n };\r\n\r\n // process peaks\r\n var Peak = function(amp, i) {\r\n this.sampleIndex = i;\r\n this.amplitude = amp;\r\n this.tempos = [];\r\n this.intervals = [];\r\n };\r\n\r\n // 1. for processPeaks() Function to identify peaks above a threshold\r\n // returns an array of peak indexes as frames (samples) of the original soundfile\r\n function getPeaksAtThreshold(data, threshold) {\r\n var peaksObj = {};\r\n var length = data.length;\r\n\r\n for (var i = 0; i < length; i++) {\r\n if (data[i] > threshold) {\r\n var amp = data[i];\r\n var peak = new Peak(amp, i);\r\n peaksObj[i] = peak;\r\n // Skip forward ~ 1/8s to get past this peak.\r\n i += 6000;\r\n }\r\n i++;\r\n }\r\n return peaksObj;\r\n }\r\n\r\n // 2. for processPeaks()\r\n function countIntervalsBetweenNearbyPeaks(peaksObj) {\r\n var intervalCounts = [];\r\n var peaksArray = Object.keys(peaksObj).sort();\r\n\r\n for (var index = 0; index < peaksArray.length; index++) {\r\n\r\n // find intervals in comparison to nearby peaks\r\n for (var i = 0; i < 10; i++) {\r\n var startPeak = peaksObj[peaksArray[index]];\r\n var endPeak = peaksObj[peaksArray[index + i]];\r\n\r\n if (startPeak && endPeak) {\r\n var startPos = startPeak.sampleIndex;\r\n var endPos = endPeak.sampleIndex;\r\n var interval = endPos - startPos;\r\n\r\n // add a sample interval to the startPeak in the allPeaks array\r\n if (interval > 0) {\r\n startPeak.intervals.push(interval);\r\n }\r\n\r\n // tally the intervals and return interval counts\r\n var foundInterval = intervalCounts.some(function(intervalCount) {\r\n if (intervalCount.interval === interval) {\r\n intervalCount.count++;\r\n return intervalCount;\r\n }\r\n });\r\n\r\n // store with JSON like formatting\r\n if (!foundInterval) {\r\n intervalCounts.push({\r\n interval: interval,\r\n count: 1,\r\n });\r\n }\r\n }\r\n }\r\n }\r\n\r\n return intervalCounts;\r\n }\r\n\r\n\r\n // 3. for processPeaks --> find tempo\r\n function groupNeighborsByTempo(intervalCounts, sampleRate) {\r\n var tempoCounts = [];\r\n\r\n intervalCounts.forEach(function(intervalCount) {\r\n\r\n try {\r\n // Convert an interval to tempo\r\n var theoreticalTempo = Math.abs( 60 / (intervalCount.interval / sampleRate ) );\r\n\r\n theoreticalTempo = mapTempo(theoreticalTempo);\r\n\r\n var foundTempo = tempoCounts.some(function(tempoCount) {\r\n if (tempoCount.tempo === theoreticalTempo)\r\n return tempoCount.count += intervalCount.count;\r\n });\r\n if (!foundTempo) {\r\n if (isNaN(theoreticalTempo)) {\r\n return;\r\n }\r\n tempoCounts.push({\r\n tempo: Math.round(theoreticalTempo),\r\n count: intervalCount.count\r\n });\r\n }\r\n } catch(e) {\r\n throw e;\r\n }\r\n\r\n });\r\n\r\n return tempoCounts;\r\n }\r\n\r\n // 4. for processPeaks - get peaks at top tempo\r\n function getPeaksAtTopTempo(peaksObj, tempo, sampleRate, bpmVariance) {\r\n var peaksAtTopTempo = [];\r\n var peaksArray = Object.keys(peaksObj).sort();\r\n\r\n // TO DO: filter out peaks that have the tempo and return\r\n for (var i = 0; i < peaksArray.length; i++) {\r\n var key = peaksArray[i];\r\n var peak = peaksObj[key];\r\n\r\n for (var j = 0; j < peak.intervals.length; j++) {\r\n var intervalBPM = Math.round(Math.abs( 60 / (peak.intervals[j] / sampleRate) ) );\r\n\r\n intervalBPM = mapTempo(intervalBPM);\r\n\r\n if ( Math.abs(intervalBPM - tempo) < bpmVariance ) {\r\n // convert sampleIndex to seconds\r\n peaksAtTopTempo.push(peak.sampleIndex/sampleRate);\r\n }\r\n }\r\n }\r\n\r\n // filter out peaks that are very close to each other\r\n peaksAtTopTempo = peaksAtTopTempo.filter(function(peakTime, index, arr) {\r\n var dif = arr[index + 1] - peakTime;\r\n if (dif > 0.01) {\r\n return true;\r\n }\r\n });\r\n\r\n return peaksAtTopTempo;\r\n }\r\n\r\n // helper function for processPeaks\r\n function mapTempo(theoreticalTempo) {\r\n // these scenarios create infinite while loop\r\n if (!isFinite(theoreticalTempo) || theoreticalTempo === 0 ) {\r\n return;\r\n }\r\n\r\n // Adjust the tempo to fit within the 90-180 BPM range\r\n while (theoreticalTempo < 90) theoreticalTempo *= 2;\r\n while (theoreticalTempo > 180 && theoreticalTempo > 90) theoreticalTempo /= 2;\r\n\r\n return theoreticalTempo;\r\n }\r\n\r\n\r\n /*** SCHEDULE EVENTS ***/\r\n\r\n // Cue inspired by JavaScript setTimeout, and the\r\n // Tone.js Transport Timeline Event, MIT License Yotam Mann 2015 tonejs.org\r\n var Cue = function(callback, time, id, val) {\r\n this.callback = callback;\r\n this.time = time;\r\n this.id = id;\r\n this.val = val;\r\n };\r\n\r\n /**\r\n * Schedule events to trigger every time a MediaElement\r\n * (audio/video) reaches a playback cue point.\r\n *\r\n * Accepts a callback function, a time (in seconds) at which to trigger\r\n * the callback, and an optional parameter for the callback.\r\n *\r\n * Time will be passed as the first parameter to the callback function,\r\n * and param will be the second parameter.\r\n *\r\n *\r\n * @method addCue\r\n * @for p5.SoundFile\r\n * @param {Number} time Time in seconds, relative to this media\r\n * element's playback. For example, to trigger\r\n * an event every time playback reaches two\r\n * seconds, pass in the number 2. This will be\r\n * passed as the first parameter to\r\n * the callback function.\r\n * @param {Function} callback Name of a function that will be\r\n * called at the given time. The callback will\r\n * receive time and (optionally) param as its\r\n * two parameters.\r\n * @param {Object} [value] An object to be passed as the\r\n * second parameter to the\r\n * callback function.\r\n * @return {Number} id ID of this cue,\r\n * useful for removeCue(id)\r\n * @example\r\n *
\r\n */\r\n p5.SoundFile.prototype.addCue = function(time, callback, val) {\r\n var id = this._cueIDCounter++;\r\n\r\n var cue = new Cue(callback, time, id, val);\r\n this._cues.push(cue);\r\n\r\n // if (!this.elt.ontimeupdate) {\r\n // this.elt.ontimeupdate = this._onTimeUpdate.bind(this);\r\n // }\r\n\r\n return id;\r\n };\r\n\r\n /**\r\n * Remove a callback based on its ID. The ID is returned by the\r\n * addCue method.\r\n *\r\n * @method removeCue\r\n * @for p5.SoundFile\r\n * @param {Number} id ID of the cue, as returned by addCue\r\n */\r\n p5.SoundFile.prototype.removeCue = function(id) {\r\n var cueLength = this._cues.length;\r\n for (var i = 0; i < cueLength; i++) {\r\n var cue = this._cues[i];\r\n if (cue.id === id) {\r\n this._cues.splice(i, 1);\r\n break;\r\n }\r\n }\r\n\r\n if (this._cues.length === 0) {\r\n // TO DO: remove callback\r\n // this.elt.ontimeupdate = null\r\n }\r\n };\r\n\r\n /**\r\n * Remove all of the callbacks that had originally been scheduled\r\n * via the addCue method.\r\n *\r\n * @method clearCues\r\n */\r\n p5.SoundFile.prototype.clearCues = function() {\r\n this._cues = [];\r\n // this.elt.ontimeupdate = null;\r\n };\r\n\r\n // private method that checks for cues to be fired if events\r\n // have been scheduled using addCue(callback, time).\r\n p5.SoundFile.prototype._onTimeUpdate = function(position) {\r\n var playbackTime = position/this.buffer.sampleRate;\r\n var cueLength = this._cues.length;\r\n\r\n for (var i = 0 ; i < cueLength; i++) {\r\n var cue = this._cues[i];\r\n var callbackTime = cue.time;\r\n var val = cue.val;\r\n\r\n if (this._prevTime < callbackTime && callbackTime <= playbackTime) {\r\n\r\n // pass the scheduled callbackTime as parameter to the callback\r\n cue.callback(val);\r\n }\r\n\r\n }\r\n\r\n this._prevTime = playbackTime;\r\n };\r\n\r\n /**\r\n * Save a p5.SoundFile as a .wav file. The browser will prompt the user\r\n * to download the file to their device. To upload a file to a server, see\r\n * getBlob\r\n *\r\n * @method save\r\n * @for p5.SoundFile\r\n * @param {String} [fileName] name of the resulting .wav file.\r\n * @example\r\n *
\r\n * var inp, button, mySound;\r\n * var fileName = 'cool';\r\n * function preload() {\r\n * mySound = loadSound('assets/doorbell.mp3');\r\n * }\r\n * function setup() {\r\n * btn = createButton('click to save file');\r\n * btn.position(0, 0);\r\n * btn.mouseClicked(handleMouseClick);\r\n * }\r\n *\r\n * function handleMouseClick() {\r\n * mySound.save(fileName);\r\n * }\r\n *
\r\n */\r\n p5.SoundFile.prototype.save = function(fileName) {\r\n const dataView = convertToWav(this.buffer);\r\n p5.prototype.saveSound([dataView], fileName, 'wav');\r\n };\r\n\r\n /**\r\n * This method is useful for sending a SoundFile to a server. It returns the\r\n * .wav-encoded audio data as a \"Blob\".\r\n * A Blob is a file-like data object that can be uploaded to a server\r\n * with an http request. We'll\r\n * use the `httpDo` options object to send a POST request with some\r\n * specific options: we encode the request as `multipart/form-data`,\r\n * and attach the blob as one of the form values using `FormData`.\r\n *\r\n *\r\n * @method getBlob\r\n * @for p5.SoundFile\r\n * @returns {Blob} A file-like data object\r\n * @example\r\n *
\r\n *\r\n * function preload() {\r\n * mySound = loadSound('assets/doorbell.mp3');\r\n * }\r\n *\r\n * function setup() {\r\n * noCanvas();\r\n * var soundBlob = mySound.getBlob();\r\n *\r\n * // Now we can send the blob to a server...\r\n * var serverUrl = 'https://jsonplaceholder.typicode.com/posts';\r\n * var httpRequestOptions = {\r\n * method: 'POST',\r\n * body: new FormData().append('soundBlob', soundBlob),\r\n * headers: new Headers({\r\n * 'Content-Type': 'multipart/form-data'\r\n * })\r\n * };\r\n * httpDo(serverUrl, httpRequestOptions);\r\n *\r\n * // We can also create an `ObjectURL` pointing to the Blob\r\n * var blobUrl = URL.createObjectURL(soundBlob);\r\n *\r\n * // The `
\r\n */\r\n p5.SoundFile.prototype.getBlob = function() {\r\n const dataView = convertToWav(this.buffer);\r\n return new Blob([dataView], { type: 'audio/wav' });\r\n };\r\n\r\n // event handler to keep track of current position\r\n function _onAudioProcess(processEvent) {\r\n var inputBuffer = processEvent.inputBuffer.getChannelData(0);\r\n\r\n this._lastPos = inputBuffer[inputBuffer.length - 1] || 0;\r\n\r\n // do any callbacks that have been scheduled\r\n this._onTimeUpdate(self._lastPos);\r\n }\r\n\r\n // event handler to remove references to the bufferSourceNode when it is done playing\r\n function _clearOnEnd(e) {\r\n const thisBufferSourceNode = e.target;\r\n const soundFile = this;\r\n\r\n // delete this.bufferSourceNode from the sources array when it is done playing:\r\n thisBufferSourceNode._playing = false;\r\n thisBufferSourceNode.removeEventListener('ended', soundFile._clearOnEnd);\r\n\r\n // call the onended callback\r\n soundFile._onended(soundFile);\r\n\r\n soundFile.bufferSourceNodes.forEach(function (n, i) {\r\n if (n._playing === false) {\r\n soundFile.bufferSourceNodes.splice(i);\r\n }\r\n });\r\n\r\n if (soundFile.bufferSourceNodes.length === 0) {\r\n soundFile._playing = false;\r\n }\r\n }\r\n});\r\n","'use strict';\r\n\r\ndefine(function (require) {\r\n var p5sound = require('master');\r\n var processorNames = require('./audioWorklet/processorNames');\r\n\r\n /**\r\n * Amplitude measures volume between 0.0 and 1.0.\r\n * Listens to all p5sound by default, or use setInput()\r\n * to listen to a specific sound source. Accepts an optional\r\n * smoothing value, which defaults to 0.\r\n *\r\n * @class p5.Amplitude\r\n * @constructor\r\n * @param {Number} [smoothing] between 0.0 and .999 to smooth\r\n * amplitude readings (defaults to 0)\r\n * @example\r\n *
\r\n * var sound, amplitude, cnv;\r\n *\r\n * function preload(){\r\n * sound = loadSound('assets/beat.mp3');\r\n * }\r\n * function setup() {\r\n * cnv = createCanvas(100,100);\r\n * amplitude = new p5.Amplitude();\r\n *\r\n * // start / stop the sound when canvas is clicked\r\n * cnv.mouseClicked(function() {\r\n * if (sound.isPlaying() ){\r\n * sound.stop();\r\n * } else {\r\n * sound.play();\r\n * }\r\n * });\r\n * }\r\n * function draw() {\r\n * background(0);\r\n * fill(255);\r\n * var level = amplitude.getLevel();\r\n * var size = map(level, 0, 1, 0, 200);\r\n * ellipse(width/2, height/2, size, size);\r\n * }\r\n *\r\n *
\r\n */\r\n p5.Amplitude = function(smoothing) {\r\n\r\n // Set to 2048 for now. In future iterations, this should be inherited or parsed from p5sound's default\r\n this.bufferSize = 2048;\r\n\r\n // set audio context\r\n this.audiocontext = p5sound.audiocontext;\r\n this._workletNode = new AudioWorkletNode(this.audiocontext, processorNames.amplitudeProcessor, {\r\n outputChannelCount: [1],\r\n parameterData: { smoothing: smoothing || 0 },\r\n processorOptions: { normalize: false }\r\n });\r\n\r\n this._workletNode.port.onmessage = function(event) {\r\n if (event.data.name === 'amplitude') {\r\n this.volume = event.data.volume;\r\n this.volNorm = event.data.volNorm;\r\n this.stereoVol = event.data.stereoVol;\r\n this.stereoVolNorm = event.data.stereoVolNorm;\r\n }\r\n }.bind(this);\r\n\r\n // for connections\r\n this.input = this._workletNode;\r\n\r\n this.output = this.audiocontext.createGain();\r\n\r\n // the variables to return\r\n this.volume = 0;\r\n this.volNorm = 0;\r\n this.stereoVol = [0, 0];\r\n this.stereoVolNorm = [0, 0];\r\n\r\n this.normalize = false;\r\n\r\n this._workletNode.connect(this.output);\r\n this.output.gain.value = 0;\r\n\r\n // this may only be necessary because of a Chrome bug\r\n this.output.connect(this.audiocontext.destination);\r\n\r\n // connect to p5sound master output by default, unless set by input()\r\n p5sound.meter.connect(this._workletNode);\r\n\r\n // add this p5.SoundFile to the soundArray\r\n p5sound.soundArray.push(this);\r\n };\r\n\r\n /**\r\n * Connects to the p5sound instance (master output) by default.\r\n * Optionally, you can pass in a specific source (i.e. a soundfile).\r\n *\r\n * @method setInput\r\n * @for p5.Amplitude\r\n * @param {soundObject|undefined} [snd] set the sound source\r\n * (optional, defaults to\r\n * master output)\r\n * @param {Number|undefined} [smoothing] a range between 0.0 and 1.0\r\n * to smooth amplitude readings\r\n * @example\r\n *
\r\n * function preload(){\r\n * sound1 = loadSound('assets/beat.mp3');\r\n * sound2 = loadSound('assets/drum.mp3');\r\n * }\r\n * function setup(){\r\n * amplitude = new p5.Amplitude();\r\n * sound1.play();\r\n * sound2.play();\r\n * amplitude.setInput(sound2);\r\n * }\r\n * function draw() {\r\n * background(0);\r\n * fill(255);\r\n * var level = amplitude.getLevel();\r\n * var size = map(level, 0, 1, 0, 200);\r\n * ellipse(width/2, height/2, size, size);\r\n * }\r\n * function mouseClicked(){\r\n * sound1.stop();\r\n * sound2.stop();\r\n * }\r\n *
\r\n */\r\n p5.Amplitude.prototype.setInput = function(source, smoothing) {\r\n\r\n p5sound.meter.disconnect();\r\n\r\n if (smoothing) {\r\n this._workletNode.parameters.get('smoothing').value = smoothing;\r\n }\r\n\r\n // connect to the master out of p5s instance if no snd is provided\r\n if (source == null) {\r\n console.log('Amplitude input source is not ready! Connecting to master output instead');\r\n p5sound.meter.connect(this._workletNode);\r\n }\r\n\r\n // if it is a p5.Signal\r\n else if (source instanceof p5.Signal) {\r\n source.output.connect(this._workletNode);\r\n }\r\n // connect to the sound if it is available\r\n else if (source) {\r\n source.connect(this._workletNode);\r\n this._workletNode.disconnect();\r\n this._workletNode.connect(this.output);\r\n }\r\n\r\n // otherwise, connect to the master out of p5s instance (default)\r\n else {\r\n p5sound.meter.connect(this._workletNode);\r\n }\r\n };\r\n\r\n p5.Amplitude.prototype.connect = function(unit) {\r\n if (unit) {\r\n if (unit.hasOwnProperty('input')) {\r\n this.output.connect(unit.input);\r\n } else {\r\n this.output.connect(unit);\r\n }\r\n } else {\r\n this.output.connect(this.panner.connect(p5sound.input));\r\n }\r\n };\r\n\r\n p5.Amplitude.prototype.disconnect = function() {\r\n if (this.output) {\r\n this.output.disconnect();\r\n }\r\n };\r\n\r\n /**\r\n * Returns a single Amplitude reading at the moment it is called.\r\n * For continuous readings, run in the draw loop.\r\n *\r\n * @method getLevel\r\n * @for p5.Amplitude\r\n * @param {Number} [channel] Optionally return only channel 0 (left) or 1 (right)\r\n * @return {Number} Amplitude as a number between 0.0 and 1.0\r\n * @example\r\n *
\r\n * function preload(){\r\n * sound = loadSound('assets/beat.mp3');\r\n * }\r\n * function setup() {\r\n * amplitude = new p5.Amplitude();\r\n * sound.play();\r\n * }\r\n * function draw() {\r\n * background(0);\r\n * fill(255);\r\n * var level = amplitude.getLevel();\r\n * var size = map(level, 0, 1, 0, 200);\r\n * ellipse(width/2, height/2, size, size);\r\n * }\r\n * function mouseClicked(){\r\n * sound.stop();\r\n * }\r\n *
\r\n */\r\n p5.Amplitude.prototype.getLevel = function(channel) {\r\n if (typeof channel !== 'undefined') {\r\n if (this.normalize) {\r\n return this.stereoVolNorm[channel];\r\n } else {\r\n return this.stereoVol[channel];\r\n }\r\n }\r\n else if (this.normalize) {\r\n return this.volNorm;\r\n }\r\n else {\r\n return this.volume;\r\n }\r\n };\r\n\r\n /**\r\n * Determines whether the results of Amplitude.process() will be\r\n * Normalized. To normalize, Amplitude finds the difference the\r\n * loudest reading it has processed and the maximum amplitude of\r\n * 1.0. Amplitude adds this difference to all values to produce\r\n * results that will reliably map between 0.0 and 1.0. However,\r\n * if a louder moment occurs, the amount that Normalize adds to\r\n * all the values will change. Accepts an optional boolean parameter\r\n * (true or false). Normalizing is off by default.\r\n *\r\n * @method toggleNormalize\r\n * @for p5.Amplitude\r\n * @param {boolean} [boolean] set normalize to true (1) or false (0)\r\n */\r\n p5.Amplitude.prototype.toggleNormalize = function(bool) {\r\n if (typeof bool === 'boolean') {\r\n this.normalize = bool;\r\n }\r\n else {\r\n this.normalize = !this.normalize;\r\n }\r\n this._workletNode.port.postMessage({ name: 'toggleNormalize', normalize: this.normalize });\r\n };\r\n\r\n /**\r\n * Smooth Amplitude analysis by averaging with the last analysis\r\n * frame. Off by default.\r\n *\r\n * @method smooth\r\n * @for p5.Amplitude\r\n * @param {Number} set smoothing from 0.0 <= 1\r\n */\r\n p5.Amplitude.prototype.smooth = function(s) {\r\n if (s >= 0 && s < 1) {\r\n this._workletNode.parameters.get('smoothing').value = s;\r\n } else {\r\n console.log('Error: smoothing must be between 0 and 1');\r\n }\r\n };\r\n\r\n p5.Amplitude.prototype.dispose = function() {\r\n // remove reference from soundArray\r\n var index = p5sound.soundArray.indexOf(this);\r\n p5sound.soundArray.splice(index, 1);\r\n\r\n if (this.input) {\r\n this.input.disconnect();\r\n delete this.input;\r\n }\r\n if (this.output) {\r\n this.output.disconnect();\r\n delete this.output;\r\n }\r\n\r\n this._workletNode.disconnect();\r\n delete this._workletNode;\r\n };\r\n\r\n});\r\n","'use strict';\r\n\r\ndefine(function(require) {\r\n var p5sound = require('master');\r\n\r\n /**\r\n *
FFT (Fast Fourier Transform) is an analysis algorithm that\r\n * isolates individual\r\n * \r\n * audio frequencies within a waveform.
\r\n *\r\n *
Once instantiated, a p5.FFT object can return an array based on\r\n * two types of analyses: • FFT.waveform() computes\r\n * amplitude values along the time domain. The array indices correspond\r\n * to samples across a brief moment in time. Each value represents\r\n * amplitude of the waveform at that sample of time. \r\n * • FFT.analyze() computes amplitude values along the\r\n * frequency domain. The array indices correspond to frequencies (i.e.\r\n * pitches), from the lowest to the highest that humans can hear. Each\r\n * value represents amplitude at that slice of the frequency spectrum.\r\n * Use with getEnergy() to measure amplitude at specific\r\n * frequencies, or within a range of frequencies.
\r\n *\r\n *
FFT analyzes a very short snapshot of sound called a sample\r\n * buffer. It returns an array of amplitude measurements, referred\r\n * to as bins. The array is 1024 bins long by default.\r\n * You can change the bin array length, but it must be a power of 2\r\n * between 16 and 1024 in order for the FFT algorithm to function\r\n * correctly. The actual size of the FFT buffer is twice the\r\n * number of bins, so given a standard sample rate, the buffer is\r\n * 2048/44100 seconds long.
\r\n *\r\n *\r\n * @class p5.FFT\r\n * @constructor\r\n * @param {Number} [smoothing] Smooth results of Freq Spectrum.\r\n * 0.0 < smoothing < 1.0.\r\n * Defaults to 0.8.\r\n * @param {Number} [bins] Length of resulting array.\r\n * Must be a power of two between\r\n * 16 and 1024. Defaults to 1024.\r\n * @example\r\n *
\r\n * function preload(){\r\n * sound = loadSound('assets/Damscray_DancingTiger.mp3');\r\n * }\r\n *\r\n * function setup(){\r\n * var cnv = createCanvas(100,100);\r\n * cnv.mouseClicked(togglePlay);\r\n * fft = new p5.FFT();\r\n * sound.amp(0.2);\r\n * }\r\n *\r\n * function draw(){\r\n * background(0);\r\n *\r\n * var spectrum = fft.analyze();\r\n * noStroke();\r\n * fill(0,255,0); // spectrum is green\r\n * for (var i = 0; i< spectrum.length; i++){\r\n * var x = map(i, 0, spectrum.length, 0, width);\r\n * var h = -height + map(spectrum[i], 0, 255, height, 0);\r\n * rect(x, height, width / spectrum.length, h )\r\n * }\r\n *\r\n * var waveform = fft.waveform();\r\n * noFill();\r\n * beginShape();\r\n * stroke(255,0,0); // waveform is red\r\n * strokeWeight(1);\r\n * for (var i = 0; i< waveform.length; i++){\r\n * var x = map(i, 0, waveform.length, 0, width);\r\n * var y = map( waveform[i], -1, 1, 0, height);\r\n * vertex(x,y);\r\n * }\r\n * endShape();\r\n *\r\n * text('click to play/pause', 4, 10);\r\n * }\r\n *\r\n * // fade sound if mouse is over canvas\r\n * function togglePlay() {\r\n * if (sound.isPlaying()) {\r\n * sound.pause();\r\n * } else {\r\n * sound.loop();\r\n * }\r\n * }\r\n *
\r\n */\r\n p5.FFT = function(smoothing, bins) {\r\n this.input = this.analyser = p5sound.audiocontext.createAnalyser();\r\n\r\n Object.defineProperties(this, {\r\n bins: {\r\n get: function() {\r\n return this.analyser.fftSize / 2;\r\n },\r\n set: function(b) {\r\n this.analyser.fftSize = b * 2;\r\n },\r\n configurable: true,\r\n enumerable: true\r\n },\r\n smoothing: {\r\n get: function() {\r\n return this.analyser.smoothingTimeConstant;\r\n },\r\n set: function(s) {\r\n this.analyser.smoothingTimeConstant = s;\r\n },\r\n configurable: true,\r\n enumerable: true\r\n }\r\n });\r\n\r\n // set default smoothing and bins\r\n this.smooth(smoothing);\r\n this.bins = bins || 1024;\r\n\r\n // default connections to p5sound fftMeter\r\n p5sound.fftMeter.connect(this.analyser);\r\n\r\n this.freqDomain = new Uint8Array(this.analyser.frequencyBinCount);\r\n this.timeDomain = new Uint8Array(this.analyser.frequencyBinCount);\r\n\r\n // predefined frequency ranges, these will be tweakable\r\n this.bass = [20, 140];\r\n this.lowMid = [140, 400];\r\n this.mid = [400, 2600];\r\n this.highMid = [2600, 5200];\r\n this.treble = [5200, 14000];\r\n\r\n // add this p5.SoundFile to the soundArray\r\n p5sound.soundArray.push(this);\r\n };\r\n\r\n /**\r\n * Set the input source for the FFT analysis. If no source is\r\n * provided, FFT will analyze all sound in the sketch.\r\n *\r\n * @method setInput\r\n * @for p5.FFT\r\n * @param {Object} [source] p5.sound object (or web audio API source node)\r\n */\r\n p5.FFT.prototype.setInput = function(source) {\r\n if (!source) {\r\n p5sound.fftMeter.connect(this.analyser);\r\n } else {\r\n if (source.output) {\r\n source.output.connect(this.analyser);\r\n } else if (source.connect) {\r\n source.connect(this.analyser);\r\n }\r\n p5sound.fftMeter.disconnect();\r\n }\r\n };\r\n\r\n /**\r\n * Returns an array of amplitude values (between -1.0 and +1.0) that represent\r\n * a snapshot of amplitude readings in a single buffer. Length will be\r\n * equal to bins (defaults to 1024). Can be used to draw the waveform\r\n * of a sound.\r\n *\r\n * @method waveform\r\n * @for p5.FFT\r\n * @param {Number} [bins] Must be a power of two between\r\n * 16 and 1024. Defaults to 1024.\r\n * @param {String} [precision] If any value is provided, will return results\r\n * in a Float32 Array which is more precise\r\n * than a regular array.\r\n * @return {Array} Array Array of amplitude values (-1 to 1)\r\n * over time. Array length = bins.\r\n *\r\n */\r\n p5.FFT.prototype.waveform = function() {\r\n var bins, mode, normalArray;\r\n\r\n for (var i = 0; i < arguments.length; i++) {\r\n if (typeof arguments[i] === 'number') {\r\n bins = arguments[i];\r\n this.analyser.fftSize = bins * 2;\r\n }\r\n if (typeof arguments[i] === 'string') {\r\n mode = arguments[i];\r\n }\r\n }\r\n\r\n // getFloatFrequencyData doesnt work in Safari as of 5/2015\r\n if (mode && !p5.prototype._isSafari()) {\r\n timeToFloat(this, this.timeDomain);\r\n this.analyser.getFloatTimeDomainData(this.timeDomain);\r\n return this.timeDomain;\r\n } else {\r\n timeToInt(this, this.timeDomain);\r\n this.analyser.getByteTimeDomainData(this.timeDomain);\r\n var normalArray = new Array();\r\n for (var j = 0; j < this.timeDomain.length; j++) {\r\n var scaled = p5.prototype.map(this.timeDomain[j], 0, 255, -1, 1);\r\n normalArray.push(scaled);\r\n }\r\n return normalArray;\r\n }\r\n };\r\n\r\n /**\r\n * Returns an array of amplitude values (between 0 and 255)\r\n * across the frequency spectrum. Length is equal to FFT bins\r\n * (1024 by default). The array indices correspond to frequencies\r\n * (i.e. pitches), from the lowest to the highest that humans can\r\n * hear. Each value represents amplitude at that slice of the\r\n * frequency spectrum. Must be called prior to using\r\n * getEnergy().\r\n *\r\n * @method analyze\r\n * @for p5.FFT\r\n * @param {Number} [bins] Must be a power of two between\r\n * 16 and 1024. Defaults to 1024.\r\n * @param {Number} [scale] If \"dB,\" returns decibel\r\n * float measurements between\r\n * -140 and 0 (max).\r\n * Otherwise returns integers from 0-255.\r\n * @return {Array} spectrum Array of energy (amplitude/volume)\r\n * values across the frequency spectrum.\r\n * Lowest energy (silence) = 0, highest\r\n * possible is 255.\r\n * @example\r\n *
\r\n * var osc;\r\n * var fft;\r\n *\r\n * function setup(){\r\n * createCanvas(100,100);\r\n * osc = new p5.Oscillator();\r\n * osc.amp(0);\r\n * osc.start();\r\n * fft = new p5.FFT();\r\n * }\r\n *\r\n * function draw(){\r\n * background(0);\r\n *\r\n * var freq = map(mouseX, 0, 800, 20, 15000);\r\n * freq = constrain(freq, 1, 20000);\r\n * osc.freq(freq);\r\n *\r\n * var spectrum = fft.analyze();\r\n * noStroke();\r\n * fill(0,255,0); // spectrum is green\r\n * for (var i = 0; i< spectrum.length; i++){\r\n * var x = map(i, 0, spectrum.length, 0, width);\r\n * var h = -height + map(spectrum[i], 0, 255, height, 0);\r\n * rect(x, height, width / spectrum.length, h );\r\n * }\r\n *\r\n * stroke(255);\r\n * text('Freq: ' + round(freq)+'Hz', 10, 10);\r\n *\r\n * isMouseOverCanvas();\r\n * }\r\n *\r\n * // only play sound when mouse is over canvas\r\n * function isMouseOverCanvas() {\r\n * var mX = mouseX, mY = mouseY;\r\n * if (mX > 0 && mX < width && mY < height && mY > 0) {\r\n * osc.amp(0.5, 0.2);\r\n * } else {\r\n * osc.amp(0, 0.2);\r\n * }\r\n * }\r\n *
\r\n *\r\n *\r\n */\r\n p5.FFT.prototype.analyze = function() {\r\n var mode;\r\n\r\n for (var i = 0; i < arguments.length; i++) {\r\n if (typeof arguments[i] === 'number') {\r\n this.bins = arguments[i];\r\n this.analyser.fftSize = this.bins * 2;\r\n }\r\n if (typeof arguments[i] === 'string') {\r\n mode = arguments[i];\r\n }\r\n }\r\n\r\n if (mode && mode.toLowerCase() === 'db') {\r\n freqToFloat(this);\r\n this.analyser.getFloatFrequencyData(this.freqDomain);\r\n return this.freqDomain;\r\n } else {\r\n freqToInt(this, this.freqDomain);\r\n this.analyser.getByteFrequencyData(this.freqDomain);\r\n var normalArray = Array.apply([], this.freqDomain);\r\n \r\n return normalArray;\r\n }\r\n };\r\n\r\n /**\r\n * Returns the amount of energy (volume) at a specific\r\n * \r\n * frequency, or the average amount of energy between two\r\n * frequencies. Accepts Number(s) corresponding\r\n * to frequency (in Hz), or a String corresponding to predefined\r\n * frequency ranges (\"bass\", \"lowMid\", \"mid\", \"highMid\", \"treble\").\r\n * Returns a range between 0 (no energy/volume at that frequency) and\r\n * 255 (maximum energy).\r\n * NOTE: analyze() must be called prior to getEnergy(). Analyze()\r\n * tells the FFT to analyze frequency data, and getEnergy() uses\r\n * the results determine the value at a specific frequency or\r\n * range of frequencies.\r\n *\r\n * @method getEnergy\r\n * @for p5.FFT\r\n * @param {Number|String} frequency1 Will return a value representing\r\n * energy at this frequency. Alternately,\r\n * the strings \"bass\", \"lowMid\" \"mid\",\r\n * \"highMid\", and \"treble\" will return\r\n * predefined frequency ranges.\r\n * @param {Number} [frequency2] If a second frequency is given,\r\n * will return average amount of\r\n * energy that exists between the\r\n * two frequencies.\r\n * @return {Number} Energy Energy (volume/amplitude) from\r\n * 0 and 255.\r\n *\r\n */\r\n p5.FFT.prototype.getEnergy = function(frequency1, frequency2) {\r\n var nyquist = p5sound.audiocontext.sampleRate / 2;\r\n\r\n if (frequency1 === 'bass') {\r\n frequency1 = this.bass[0];\r\n frequency2 = this.bass[1];\r\n } else if (frequency1 === 'lowMid') {\r\n frequency1 = this.lowMid[0];\r\n frequency2 = this.lowMid[1];\r\n } else if (frequency1 === 'mid') {\r\n frequency1 = this.mid[0];\r\n frequency2 = this.mid[1];\r\n } else if (frequency1 === 'highMid') {\r\n frequency1 = this.highMid[0];\r\n frequency2 = this.highMid[1];\r\n } else if (frequency1 === 'treble') {\r\n frequency1 = this.treble[0];\r\n frequency2 = this.treble[1];\r\n }\r\n\r\n if (typeof frequency1 !== 'number') {\r\n throw 'invalid input for getEnergy()';\r\n } else if (!frequency2) {\r\n // if only one parameter:\r\n var index = Math.round(frequency1 / nyquist * this.freqDomain.length);\r\n return this.freqDomain[index];\r\n } else if (frequency1 && frequency2) {\r\n // if two parameters:\r\n // if second is higher than first\r\n if (frequency1 > frequency2) {\r\n var swap = frequency2;\r\n frequency2 = frequency1;\r\n frequency1 = swap;\r\n }\r\n var lowIndex = Math.round(frequency1 / nyquist * this.freqDomain.length);\r\n var highIndex = Math.round(frequency2 / nyquist * this.freqDomain.length);\r\n\r\n var total = 0;\r\n var numFrequencies = 0;\r\n // add up all of the values for the frequencies\r\n for (var i = lowIndex; i <= highIndex; i++) {\r\n total += this.freqDomain[i];\r\n numFrequencies += 1;\r\n }\r\n // divide by total number of frequencies\r\n var toReturn = total / numFrequencies;\r\n return toReturn;\r\n } else {\r\n throw 'invalid input for getEnergy()';\r\n }\r\n };\r\n\r\n // compatability with v.012, changed to getEnergy in v.0121. Will be deprecated...\r\n p5.FFT.prototype.getFreq = function(freq1, freq2) {\r\n console.log('getFreq() is deprecated. Please use getEnergy() instead.');\r\n var x = this.getEnergy(freq1, freq2);\r\n return x;\r\n };\r\n\r\n /**\r\n * Returns the\r\n * \r\n * spectral centroid of the input signal.\r\n * NOTE: analyze() must be called prior to getCentroid(). Analyze()\r\n * tells the FFT to analyze frequency data, and getCentroid() uses\r\n * the results determine the spectral centroid.\r\n *\r\n * @method getCentroid\r\n * @for p5.FFT\r\n * @return {Number} Spectral Centroid Frequency Frequency of the spectral centroid in Hz.\r\n *\r\n *\r\n * @example\r\n *
\r\n *\r\n *\r\n *function setup(){\r\n * cnv = createCanvas(100,100);\r\n * sound = new p5.AudioIn();\r\n * sound.start();\r\n * fft = new p5.FFT();\r\n * sound.connect(fft);\r\n *}\r\n *\r\n *\r\n *function draw(){\r\n *\r\n * var centroidplot = 0.0;\r\n * var spectralCentroid = 0;\r\n *\r\n *\r\n * background(0);\r\n * stroke(0,255,0);\r\n * var spectrum = fft.analyze();\r\n * fill(0,255,0); // spectrum is green\r\n *\r\n * //draw the spectrum\r\n * for (var i = 0; i< spectrum.length; i++){\r\n * var x = map(log(i), 0, log(spectrum.length), 0, width);\r\n * var h = map(spectrum[i], 0, 255, 0, height);\r\n * var rectangle_width = (log(i+1)-log(i))*(width/log(spectrum.length));\r\n * rect(x, height, rectangle_width, -h )\r\n * }\r\n\r\n * var nyquist = 22050;\r\n *\r\n * // get the centroid\r\n * spectralCentroid = fft.getCentroid();\r\n *\r\n * // the mean_freq_index calculation is for the display.\r\n * var mean_freq_index = spectralCentroid/(nyquist/spectrum.length);\r\n *\r\n * centroidplot = map(log(mean_freq_index), 0, log(spectrum.length), 0, width);\r\n *\r\n *\r\n * stroke(255,0,0); // the line showing where the centroid is will be red\r\n *\r\n * rect(centroidplot, 0, width / spectrum.length, height)\r\n * noStroke();\r\n * fill(255,255,255); // text is white\r\n * text(\"centroid: \", 10, 20);\r\n * text(round(spectralCentroid)+\" Hz\", 10, 40);\r\n *}\r\n *
\r\n */\r\n p5.FFT.prototype.getCentroid = function() {\r\n var nyquist = p5sound.audiocontext.sampleRate / 2;\r\n var cumulative_sum = 0;\r\n var centroid_normalization = 0;\r\n\r\n for (var i = 0; i < this.freqDomain.length; i++) {\r\n cumulative_sum += i * this.freqDomain[i];\r\n centroid_normalization += this.freqDomain[i];\r\n }\r\n\r\n var mean_freq_index = 0;\r\n\r\n if (centroid_normalization !== 0) {\r\n mean_freq_index = cumulative_sum / centroid_normalization;\r\n }\r\n\r\n var spec_centroid_freq =\r\n mean_freq_index * (nyquist / this.freqDomain.length);\r\n return spec_centroid_freq;\r\n };\r\n\r\n /**\r\n * Smooth FFT analysis by averaging with the last analysis frame.\r\n *\r\n * @method smooth\r\n * @param {Number} smoothing 0.0 < smoothing < 1.0.\r\n * Defaults to 0.8.\r\n */\r\n p5.FFT.prototype.smooth = function(s) {\r\n if (typeof s !== 'undefined') {\r\n this.smoothing = s;\r\n }\r\n return this.smoothing;\r\n };\r\n\r\n p5.FFT.prototype.dispose = function() {\r\n // remove reference from soundArray\r\n var index = p5sound.soundArray.indexOf(this);\r\n p5sound.soundArray.splice(index, 1);\r\n\r\n if (this.analyser) {\r\n this.analyser.disconnect();\r\n delete this.analyser;\r\n }\r\n };\r\n\r\n /**\r\n * Returns an array of average amplitude values for a given number\r\n * of frequency bands split equally. N defaults to 16.\r\n * NOTE: analyze() must be called prior to linAverages(). Analyze()\r\n * tells the FFT to analyze frequency data, and linAverages() uses\r\n * the results to group them into a smaller set of averages.\r\n *\r\n * @method linAverages\r\n * @for p5.FFT\r\n * @param {Number} N Number of returned frequency groups\r\n * @return {Array} linearAverages Array of average amplitude values for each group\r\n */\r\n p5.FFT.prototype.linAverages = function(N) {\r\n var N = N || 16; // This prevents undefined, null or 0 values of N\r\n\r\n var spectrum = this.freqDomain;\r\n var spectrumLength = spectrum.length;\r\n var spectrumStep = Math.floor(spectrumLength / N);\r\n\r\n var linearAverages = new Array(N);\r\n // Keep a second index for the current average group and place the values accordingly\r\n // with only one loop in the spectrum data\r\n var groupIndex = 0;\r\n\r\n for (var specIndex = 0; specIndex < spectrumLength; specIndex++) {\r\n linearAverages[groupIndex] =\r\n linearAverages[groupIndex] !== undefined\r\n ? (linearAverages[groupIndex] + spectrum[specIndex]) / 2\r\n : spectrum[specIndex];\r\n\r\n // Increase the group index when the last element of the group is processed\r\n if (specIndex % spectrumStep === spectrumStep - 1) {\r\n groupIndex++;\r\n }\r\n }\r\n\r\n return linearAverages;\r\n };\r\n\r\n /**\r\n * Returns an array of average amplitude values of the spectrum, for a given\r\n * set of \r\n * Octave Bands\r\n * NOTE: analyze() must be called prior to logAverages(). Analyze()\r\n * tells the FFT to analyze frequency data, and logAverages() uses\r\n * the results to group them into a smaller set of averages.\r\n *\r\n * @method logAverages\r\n * @for p5.FFT\r\n * @param {Array} octaveBands Array of Octave Bands objects for grouping\r\n * @return {Array} logAverages Array of average amplitude values for each group\r\n */\r\n p5.FFT.prototype.logAverages = function(octaveBands) {\r\n var nyquist = p5sound.audiocontext.sampleRate / 2;\r\n var spectrum = this.freqDomain;\r\n var spectrumLength = spectrum.length;\r\n\r\n var logAverages = new Array(octaveBands.length);\r\n // Keep a second index for the current average group and place the values accordingly\r\n // With only one loop in the spectrum data\r\n var octaveIndex = 0;\r\n\r\n for (var specIndex = 0; specIndex < spectrumLength; specIndex++) {\r\n var specIndexFrequency = Math.round(\r\n specIndex * nyquist / this.freqDomain.length\r\n );\r\n\r\n // Increase the group index if the current frequency exceeds the limits of the band\r\n if (specIndexFrequency > octaveBands[octaveIndex].hi) {\r\n octaveIndex++;\r\n }\r\n\r\n logAverages[octaveIndex] =\r\n logAverages[octaveIndex] !== undefined\r\n ? (logAverages[octaveIndex] + spectrum[specIndex]) / 2\r\n : spectrum[specIndex];\r\n }\r\n\r\n return logAverages;\r\n };\r\n\r\n /**\r\n * Calculates and Returns the 1/N\r\n * Octave Bands\r\n * N defaults to 3 and minimum central frequency to 15.625Hz.\r\n * (1/3 Octave Bands ~= 31 Frequency Bands)\r\n * Setting fCtr0 to a central value of a higher octave will ignore the lower bands\r\n * and produce less frequency groups.\r\n *\r\n * @method getOctaveBands\r\n * @for p5.FFT\r\n * @param {Number} N Specifies the 1/N type of generated octave bands\r\n * @param {Number} fCtr0 Minimum central frequency for the lowest band\r\n * @return {Array} octaveBands Array of octave band objects with their bounds\r\n */\r\n p5.FFT.prototype.getOctaveBands = function(N, fCtr0) {\r\n var N = N || 3; // Default to 1/3 Octave Bands\r\n var fCtr0 = fCtr0 || 15.625; // Minimum central frequency, defaults to 15.625Hz\r\n\r\n var octaveBands = [];\r\n var lastFrequencyBand = {\r\n lo: fCtr0 / Math.pow(2, 1 / (2 * N)),\r\n ctr: fCtr0,\r\n hi: fCtr0 * Math.pow(2, 1 / (2 * N))\r\n };\r\n octaveBands.push(lastFrequencyBand);\r\n\r\n var nyquist = p5sound.audiocontext.sampleRate / 2;\r\n while (lastFrequencyBand.hi < nyquist) {\r\n var newFrequencyBand = {};\r\n newFrequencyBand.lo = lastFrequencyBand.hi;\r\n newFrequencyBand.ctr = lastFrequencyBand.ctr * Math.pow(2, 1 / N);\r\n newFrequencyBand.hi = newFrequencyBand.ctr * Math.pow(2, 1 / (2 * N));\r\n\r\n octaveBands.push(newFrequencyBand);\r\n lastFrequencyBand = newFrequencyBand;\r\n }\r\n\r\n return octaveBands;\r\n };\r\n\r\n // helper methods to convert type from float (dB) to int (0-255)\r\n var freqToFloat = function(fft) {\r\n if (fft.freqDomain instanceof Float32Array === false) {\r\n fft.freqDomain = new Float32Array(fft.analyser.frequencyBinCount);\r\n }\r\n };\r\n var freqToInt = function(fft) {\r\n if (fft.freqDomain instanceof Uint8Array === false) {\r\n fft.freqDomain = new Uint8Array(fft.analyser.frequencyBinCount);\r\n }\r\n };\r\n var timeToFloat = function(fft) {\r\n if (fft.timeDomain instanceof Float32Array === false) {\r\n fft.timeDomain = new Float32Array(fft.analyser.frequencyBinCount);\r\n }\r\n };\r\n var timeToInt = function(fft) {\r\n if (fft.timeDomain instanceof Uint8Array === false) {\r\n fft.timeDomain = new Uint8Array(fft.analyser.frequencyBinCount);\r\n }\r\n };\r\n});\r\n","'use strict';\r\n\r\ndefine(function (require) {\r\n\r\n // Signal is built with the Tone.js signal by Yotam Mann\r\n // https://github.com/TONEnoTONE/Tone.js/\r\n var Signal = require('Tone/signal/Signal');\r\n var Add = require('Tone/signal/Add');\r\n var Mult = require('Tone/signal/Multiply');\r\n var Scale = require('Tone/signal/Scale');\r\n\r\n /**\r\n *
p5.Signal is a constant audio-rate signal used by p5.Oscillator\r\n * and p5.Envelope for modulation math.
\r\n *\r\n *
This is necessary because Web Audio is processed on a seprate clock.\r\n * For example, the p5 draw loop runs about 60 times per second. But\r\n * the audio clock must process samples 44100 times per second. If we\r\n * want to add a value to each of those samples, we can't do it in the\r\n * draw loop, but we can do it by adding a constant-rate audio signal.This class mostly functions behind the scenes in p5.sound, and returns\r\n * a Tone.Signal from the Tone.js library by Yotam Mann.\r\n * If you want to work directly with audio signals for modular\r\n * synthesis, check out\r\n * tone.js.
\r\n *\r\n * @class p5.Signal\r\n * @constructor\r\n * @return {Tone.Signal} A Signal object from the Tone.js library\r\n * @example\r\n *
\r\n * function setup() {\r\n * carrier = new p5.Oscillator('sine');\r\n * carrier.amp(1); // set amplitude\r\n * carrier.freq(220); // set frequency\r\n * carrier.start(); // start oscillating\r\n *\r\n * modulator = new p5.Oscillator('sawtooth');\r\n * modulator.disconnect();\r\n * modulator.amp(1);\r\n * modulator.freq(4);\r\n * modulator.start();\r\n *\r\n * // Modulator's default amplitude range is -1 to 1.\r\n * // Multiply it by -200, so the range is -200 to 200\r\n * // then add 220 so the range is 20 to 420\r\n * carrier.freq( modulator.mult(-200).add(220) );\r\n * }\r\n *
\r\n */\r\n p5.Signal = function(value) {\r\n var s = new Signal(value);\r\n // p5sound.soundArray.push(s);\r\n return s; // TODO: is this really a constructor?\r\n };\r\n\r\n /**\r\n * Fade to value, for smooth transitions\r\n *\r\n * @method fade\r\n * @for p5.Signal\r\n * @param {Number} value Value to set this signal\r\n * @param {Number} [secondsFromNow] Length of fade, in seconds from now\r\n */\r\n Signal.prototype.fade = Signal.prototype.linearRampToValueAtTime;\r\n Mult.prototype.fade = Signal.prototype.fade;\r\n Add.prototype.fade = Signal.prototype.fade;\r\n Scale.prototype.fade = Signal.prototype.fade;\r\n\r\n\r\n /**\r\n * Connect a p5.sound object or Web Audio node to this\r\n * p5.Signal so that its amplitude values can be scaled.\r\n *\r\n * @method setInput\r\n * @for p5.Signal\r\n * @param {Object} input\r\n */\r\n Signal.prototype.setInput = function(_input) {\r\n _input.connect(this);\r\n };\r\n Mult.prototype.setInput = Signal.prototype.setInput;\r\n Add.prototype.setInput = Signal.prototype.setInput;\r\n Scale.prototype.setInput = Signal.prototype.setInput;\r\n\r\n\r\n // signals can add / mult / scale themselves\r\n\r\n /**\r\n * Add a constant value to this audio signal,\r\n * and return the resulting audio signal. Does\r\n * not change the value of the original signal,\r\n * instead it returns a new p5.SignalAdd.\r\n *\r\n * @method add\r\n * @for p5.Signal\r\n * @param {Number} number\r\n * @return {p5.Signal} object\r\n */\r\n Signal.prototype.add = function(num) {\r\n var add = new Add(num);\r\n // add.setInput(this);\r\n this.connect(add);\r\n return add;\r\n };\r\n Mult.prototype.add = Signal.prototype.add;\r\n Add.prototype.add = Signal.prototype.add;\r\n Scale.prototype.add = Signal.prototype.add;\r\n\r\n /**\r\n * Multiply this signal by a constant value,\r\n * and return the resulting audio signal. Does\r\n * not change the value of the original signal,\r\n * instead it returns a new p5.SignalMult.\r\n *\r\n * @method mult\r\n * @for p5.Signal\r\n * @param {Number} number to multiply\r\n * @return {p5.Signal} object\r\n */\r\n Signal.prototype.mult = function(num) {\r\n var mult = new Mult(num);\r\n // mult.setInput(this);\r\n this.connect(mult);\r\n return mult;\r\n };\r\n Mult.prototype.mult = Signal.prototype.mult;\r\n Add.prototype.mult = Signal.prototype.mult;\r\n Scale.prototype.mult = Signal.prototype.mult;\r\n\r\n /**\r\n * Scale this signal value to a given range,\r\n * and return the result as an audio signal. Does\r\n * not change the value of the original signal,\r\n * instead it returns a new p5.SignalScale.\r\n *\r\n * @method scale\r\n * @for p5.Signal\r\n * @param {Number} number to multiply\r\n * @param {Number} inMin input range minumum\r\n * @param {Number} inMax input range maximum\r\n * @param {Number} outMin input range minumum\r\n * @param {Number} outMax input range maximum\r\n * @return {p5.Signal} object\r\n */\r\n Signal.prototype.scale = function(inMin, inMax, outMin, outMax) {\r\n var mapOutMin, mapOutMax;\r\n if (arguments.length === 4) {\r\n mapOutMin = p5.prototype.map(outMin, inMin, inMax, 0, 1) - 0.5;\r\n mapOutMax = p5.prototype.map(outMax, inMin, inMax, 0, 1) - 0.5;\r\n }\r\n else {\r\n mapOutMin = arguments[0];\r\n mapOutMax = arguments[1];\r\n }\r\n var scale = new Scale(mapOutMin, mapOutMax);\r\n this.connect(scale);\r\n return scale;\r\n };\r\n Mult.prototype.scale = Signal.prototype.scale;\r\n Add.prototype.scale = Signal.prototype.scale;\r\n Scale.prototype.scale = Signal.prototype.scale;\r\n\r\n});\r\n\r\n\r\n","define([\"Tone/core/Tone\", \"Tone/type/TimeBase\"], function (Tone) {\n\n\t/**\n\t * @class Tone.Frequency is a primitive type for encoding Frequency values. \n\t * Eventually all time values are evaluated to hertz\n\t * using the `eval` method. \n\t * @constructor\n\t * @extends {Tone.TimeBase}\n\t * @param {String|Number} val The time value.\n\t * @param {String=} units The units of the value.\n\t * @example\n\t * Tone.Frequency(\"C3\") // 261\n\t * Tone.Frequency(38, \"midi\") //\n\t * Tone.Frequency(\"C3\").transpose(4);\n\t */\n\tTone.Frequency = function(val, units){\n\t\tif (this instanceof Tone.Frequency){\n\t\t\t\n\t\t\tTone.TimeBase.call(this, val, units);\n\n\t\t} else {\n\t\t\treturn new Tone.Frequency(val, units);\n\t\t}\n\t};\n\n\tTone.extend(Tone.Frequency, Tone.TimeBase);\n\n\t///////////////////////////////////////////////////////////////////////////\n\t//\tAUGMENT BASE EXPRESSIONS\n\t///////////////////////////////////////////////////////////////////////////\n\n\t//clone the expressions so that \n\t//we can add more without modifying the original\n\tTone.Frequency.prototype._primaryExpressions = Object.create(Tone.TimeBase.prototype._primaryExpressions);\n\n\t/*\n\t * midi type primary expression\n\t * @type {Object}\n\t * @private\n\t */\n\tTone.Frequency.prototype._primaryExpressions.midi = {\n\t\tregexp : /^(\\d+(?:\\.\\d+)?midi)/,\n\t\tmethod : function(value){\n\t\t\treturn this.midiToFrequency(value);\n\t\t}\t\n\t};\n\n\t/*\n\t * note type primary expression\n\t * @type {Object}\n\t * @private\n\t */\n\tTone.Frequency.prototype._primaryExpressions.note = {\n\t\tregexp : /^([a-g]{1}(?:b|#|x|bb)?)(-?[0-9]+)/i,\n\t\tmethod : function(pitch, octave){\n\t\t\tvar index = noteToScaleIndex[pitch.toLowerCase()];\n\t\t\tvar noteNumber = index + (parseInt(octave) + 1) * 12;\n\t\t\treturn this.midiToFrequency(noteNumber);\n\t\t}\t\n\t};\n\n\t/*\n\t * BeatsBarsSixteenths type primary expression\n\t * @type {Object}\n\t * @private\n\t */\n\tTone.Frequency.prototype._primaryExpressions.tr = {\n\t\t\tregexp : /^(\\d+(?:\\.\\d+)?):(\\d+(?:\\.\\d+)?):?(\\d+(?:\\.\\d+)?)?/,\n\t\t\tmethod : function(m, q, s){\n\t\t\tvar total = 1;\n\t\t\tif (m && m !== \"0\"){\n\t\t\t\ttotal *= this._beatsToUnits(this._timeSignature() * parseFloat(m));\n\t\t\t}\n\t\t\tif (q && q !== \"0\"){\n\t\t\t\ttotal *= this._beatsToUnits(parseFloat(q));\n\t\t\t}\n\t\t\tif (s && s !== \"0\"){\n\t\t\t\ttotal *= this._beatsToUnits(parseFloat(s) / 4);\n\t\t\t}\n\t\t\treturn total;\n\t\t}\n\t};\n\n\t///////////////////////////////////////////////////////////////////////////\n\t//\tEXPRESSIONS\n\t///////////////////////////////////////////////////////////////////////////\n\n\t/**\n\t * Transposes the frequency by the given number of semitones.\n\t * @param {Interval} interval\n\t * @return {Tone.Frequency} this\n\t * @example\n\t * Tone.Frequency(\"A4\").transpose(3); //\"C5\"\n\t */\n\tTone.Frequency.prototype.transpose = function(interval){\n\t\tthis._expr = function(expr, interval){\n\t\t\tvar val = expr();\n\t\t\treturn val * this.intervalToFrequencyRatio(interval);\n\t\t}.bind(this, this._expr, interval);\n\t\treturn this;\n\t};\n\n\t/**\n\t * Takes an array of semitone intervals and returns\n\t * an array of frequencies transposed by those intervals.\n\t * @param {Array} intervals\n\t * @return {Tone.Frequency} this\n\t * @example\n\t * Tone.Frequency(\"A4\").harmonize([0, 3, 7]); //[\"A4\", \"C5\", \"E5\"]\n\t */\n\tTone.Frequency.prototype.harmonize = function(intervals){\n\t\tthis._expr = function(expr, intervals){\n\t\t\tvar val = expr();\n\t\t\tvar ret = [];\n\t\t\tfor (var i = 0; i < intervals.length; i++){\n\t\t\t\tret[i] = val * this.intervalToFrequencyRatio(intervals[i]);\n\t\t\t}\n\t\t\treturn ret;\n\t\t}.bind(this, this._expr, intervals);\n\t\treturn this;\n\t};\n\n\t///////////////////////////////////////////////////////////////////////////\n\t//\tUNIT CONVERSIONS\n\t///////////////////////////////////////////////////////////////////////////\n\n\t/**\n\t * Return the value of the frequency as a MIDI note\n\t * @return {MIDI}\n\t * @example\n\t * Tone.Frequency(\"C4\").toMidi(); //60\n\t */\n\tTone.Frequency.prototype.toMidi = function(){\n\t\treturn this.frequencyToMidi(this.valueOf());\n\t};\n\n\t/**\n\t * Return the value of the frequency in Scientific Pitch Notation\n\t * @return {Note}\n\t * @example\n\t * Tone.Frequency(69, \"midi\").toNote(); //\"A4\"\n\t */\n\tTone.Frequency.prototype.toNote = function(){\n\t\tvar freq = this.valueOf();\n\t\tvar log = Math.log(freq / Tone.Frequency.A4) / Math.LN2;\n\t\tvar noteNumber = Math.round(12 * log) + 57;\n\t\tvar octave = Math.floor(noteNumber/12);\n\t\tif(octave < 0){\n\t\t\tnoteNumber += -12 * octave;\n\t\t}\n\t\tvar noteName = scaleIndexToNote[noteNumber % 12];\n\t\treturn noteName + octave.toString();\n\t};\n\n\t/**\n\t * Return the duration of one cycle in seconds.\n\t * @return {Seconds}\n\t */\n\tTone.Frequency.prototype.toSeconds = function(){\n\t\treturn 1 / this.valueOf();\n\t};\n\n\t/**\n\t * Return the value in Hertz\n\t * @return {Frequency}\n\t */\n\tTone.Frequency.prototype.toFrequency = function(){\n\t\treturn this.valueOf();\n\t};\n\n\t/**\n\t * Return the duration of one cycle in ticks\n\t * @return {Ticks}\n\t */\n\tTone.Frequency.prototype.toTicks = function(){\n\t\tvar quarterTime = this._beatsToUnits(1);\n\t\tvar quarters = this.valueOf() / quarterTime;\n\t\treturn Math.floor(quarters * Tone.Transport.PPQ);\n\t};\n\n\t///////////////////////////////////////////////////////////////////////////\n\t//\tUNIT CONVERSIONS HELPERS\n\t///////////////////////////////////////////////////////////////////////////\n\n\t/**\n\t * Returns the value of a frequency in the current units\n\t * @param {Frequency} freq\n\t * @return {Number}\n\t * @private\n\t */\n\tTone.Frequency.prototype._frequencyToUnits = function(freq){\n\t\treturn freq;\n\t};\n\n\t/**\n\t * Returns the value of a tick in the current time units\n\t * @param {Ticks} ticks\n\t * @return {Number}\n\t * @private\n\t */\n\tTone.Frequency.prototype._ticksToUnits = function(ticks){\n\t\treturn 1 / ((ticks * 60) / (Tone.Transport.bpm.value * Tone.Transport.PPQ));\n\t};\n\n\t/**\n\t * Return the value of the beats in the current units\n\t * @param {Number} beats\n\t * @return {Number}\n\t * @private\n\t */\n\tTone.Frequency.prototype._beatsToUnits = function(beats){\n\t\treturn 1 / Tone.TimeBase.prototype._beatsToUnits.call(this, beats);\n\t};\n\n\t/**\n\t * Returns the value of a second in the current units\n\t * @param {Seconds} seconds\n\t * @return {Number}\n\t * @private\n\t */\n\tTone.Frequency.prototype._secondsToUnits = function(seconds){\n\t\treturn 1 / seconds;\n\t};\n\n\t/**\n\t * The default units if none are given.\n\t * @private\n\t */\n\tTone.Frequency.prototype._defaultUnits = \"hz\";\n\n\t///////////////////////////////////////////////////////////////////////////\n\t//\tFREQUENCY CONVERSIONS\n\t///////////////////////////////////////////////////////////////////////////\n\n\t/**\n\t * Note to scale index\n\t * @type {Object}\n\t */\n\tvar noteToScaleIndex = {\n\t\t\"cbb\" : -2, \"cb\" : -1, \"c\" : 0, \"c#\" : 1, \"cx\" : 2, \n\t\t\"dbb\" : 0, \"db\" : 1, \"d\" : 2, \"d#\" : 3, \"dx\" : 4,\n\t\t\"ebb\" : 2, \"eb\" : 3, \"e\" : 4, \"e#\" : 5, \"ex\" : 6, \n\t\t\"fbb\" : 3, \"fb\" : 4, \"f\" : 5, \"f#\" : 6, \"fx\" : 7,\n\t\t\"gbb\" : 5, \"gb\" : 6, \"g\" : 7, \"g#\" : 8, \"gx\" : 9,\n\t\t\"abb\" : 7, \"ab\" : 8, \"a\" : 9, \"a#\" : 10, \"ax\" : 11,\n\t\t\"bbb\" : 9, \"bb\" : 10, \"b\" : 11, \"b#\" : 12, \"bx\" : 13,\n\t};\n\n\t/**\n\t * scale index to note (sharps)\n\t * @type {Array}\n\t */\n\tvar scaleIndexToNote = [\"C\", \"C#\", \"D\", \"D#\", \"E\", \"F\", \"F#\", \"G\", \"G#\", \"A\", \"A#\", \"B\"];\n\n\t/**\n\t * The [concert pitch](https://en.wikipedia.org/wiki/Concert_pitch)\n\t * A4's values in Hertz. \n\t * @type {Frequency}\n\t * @static\n\t */\n\tTone.Frequency.A4 = 440;\n\n\t/**\n\t * Convert a MIDI note to frequency value. \n\t * @param {MIDI} midi The midi number to convert.\n\t * @return {Frequency} the corresponding frequency value\n\t * @example\n\t * tone.midiToFrequency(69); // returns 440\n\t */\n\tTone.Frequency.prototype.midiToFrequency = function(midi){\n\t\treturn Tone.Frequency.A4 * Math.pow(2, (midi - 69) / 12);\n\t};\n\n\t/**\n\t * Convert a frequency value to a MIDI note.\n\t * @param {Frequency} frequency The value to frequency value to convert.\n\t * @returns {MIDI}\n\t * @example\n\t * tone.midiToFrequency(440); // returns 69\n\t */\n\tTone.Frequency.prototype.frequencyToMidi = function(frequency){\n\t\treturn 69 + 12 * Math.log(frequency / Tone.Frequency.A4) / Math.LN2;\n\t};\n\n\treturn Tone.Frequency;\n});","define([\"Tone/core/Tone\", \"Tone/type/Time\"], function (Tone) {\n\n\t/**\n\t * @class Tone.TransportTime is a the time along the Transport's\n\t * timeline. It is similar to Tone.Time, but instead of evaluating\n\t * against the AudioContext's clock, it is evaluated against\n\t * the Transport's position. See [TransportTime wiki](https://github.com/Tonejs/Tone.js/wiki/TransportTime).\n\t * @constructor\n\t * @param {Time} val The time value as a number or string\n\t * @param {String=} units Unit values\n\t * @extends {Tone.Time}\n\t */\n\tTone.TransportTime = function(val, units){\n\t\tif (this instanceof Tone.TransportTime){\n\t\t\t\n\t\t\tTone.Time.call(this, val, units);\n\n\t\t} else {\n\t\t\treturn new Tone.TransportTime(val, units);\n\t\t}\n\t};\n\n\tTone.extend(Tone.TransportTime, Tone.Time);\n\n\t//clone the expressions so that \n\t//we can add more without modifying the original\n\tTone.TransportTime.prototype._unaryExpressions = Object.create(Tone.Time.prototype._unaryExpressions);\n\n\t/**\n\t * Adds an additional unary expression\n\t * which quantizes values to the next subdivision\n\t * @type {Object}\n\t * @private\n\t */\n\tTone.TransportTime.prototype._unaryExpressions.quantize = {\n\t\tregexp : /^@/,\n\t\tmethod : function(rh){\n\t\t\tvar subdivision = this._secondsToTicks(rh());\n\t\t\tvar multiple = Math.ceil(Tone.Transport.ticks / subdivision);\n\t\t\treturn this._ticksToUnits(multiple * subdivision);\n\t\t}\n\t};\n\n\t/**\n\t * Convert seconds into ticks\n\t * @param {Seconds} seconds\n\t * @return {Ticks}\n\t * @private\n\t */\n\tTone.TransportTime.prototype._secondsToTicks = function(seconds){\n\t\tvar quarterTime = this._beatsToUnits(1);\n\t\tvar quarters = seconds / quarterTime;\n\t\treturn Math.round(quarters * Tone.Transport.PPQ);\n\t};\n\n\t/**\n\t * Evaluate the time expression. Returns values in ticks\n\t * @return {Ticks}\n\t */\n\tTone.TransportTime.prototype.valueOf = function(){\n\t\tvar val = this._secondsToTicks(this._expr());\n\t\treturn val + (this._plusNow ? Tone.Transport.ticks : 0);\n\t};\n\n\t/**\n\t * Return the time in ticks.\n\t * @return {Ticks}\n\t */\n\tTone.TransportTime.prototype.toTicks = function(){\n\t\treturn this.valueOf();\n\t};\n\n\t/**\n\t * Return the time in seconds.\n\t * @return {Seconds}\n\t */\n\tTone.TransportTime.prototype.toSeconds = function(){\n\t\tvar val = this._expr();\n\t\treturn val + (this._plusNow ? Tone.Transport.seconds : 0);\n\t};\n\n\t/**\n\t * Return the time as a frequency value\n\t * @return {Frequency} \n\t */\n\tTone.TransportTime.prototype.toFrequency = function(){\n\t\treturn 1/this.toSeconds();\n\t};\n\n\treturn Tone.TransportTime;\n});","'use strict';\r\n\r\ndefine(function (require) {\r\n\r\n var p5sound = require('master');\r\n var Add = require('Tone/signal/Add');\r\n var Mult = require('Tone/signal/Multiply');\r\n var Scale = require('Tone/signal/Scale');\r\n var TimelineSignal = require('Tone/signal/TimelineSignal');\r\n\r\n /**\r\n *
Envelopes are pre-defined amplitude distribution over time.\r\n * Typically, envelopes are used to control the output volume\r\n * of an object, a series of fades referred to as Attack, Decay,\r\n * Sustain and Release (\r\n * ADSR\r\n * ). Envelopes can also control other Web Audio Parameters—for example, a p5.Envelope can\r\n * control an Oscillator's frequency like this: osc.freq(env).
\r\n *
Use setRange to change the attack/release level.\r\n * Use setADSR to change attackTime, decayTime, sustainPercent and releaseTime.
\r\n *
Use the play method to play the entire envelope,\r\n * the ramp method for a pingable trigger,\r\n * or triggerAttack/\r\n * triggerRelease to trigger noteOn/noteOff.
\r\n * var attackLevel = 1.0;\r\n * var releaseLevel = 0;\r\n *\r\n * var attackTime = 0.001;\r\n * var decayTime = 0.2;\r\n * var susPercent = 0.2;\r\n * var releaseTime = 0.5;\r\n *\r\n * var env, triOsc;\r\n *\r\n * function setup() {\r\n * var cnv = createCanvas(100, 100);\r\n *\r\n * textAlign(CENTER);\r\n * text('click to play', width/2, height/2);\r\n *\r\n * env = new p5.Envelope();\r\n * env.setADSR(attackTime, decayTime, susPercent, releaseTime);\r\n * env.setRange(attackLevel, releaseLevel);\r\n *\r\n * triOsc = new p5.Oscillator('triangle');\r\n * triOsc.amp(env);\r\n * triOsc.start();\r\n * triOsc.freq(220);\r\n *\r\n * cnv.mousePressed(playEnv);\r\n * }\r\n *\r\n * function playEnv() {\r\n * env.play();\r\n * }\r\n *
\r\n */\r\n p5.Envelope = function(t1, l1, t2, l2, t3, l3) {\r\n /**\r\n * Time until envelope reaches attackLevel\r\n * @property attackTime\r\n */\r\n this.aTime = t1 || 0.1;\r\n /**\r\n * Level once attack is complete.\r\n * @property attackLevel\r\n */\r\n this.aLevel = l1 || 1;\r\n /**\r\n * Time until envelope reaches decayLevel.\r\n * @property decayTime\r\n */\r\n this.dTime = t2 || 0.5;\r\n /**\r\n * Level after decay. The envelope will sustain here until it is released.\r\n * @property decayLevel\r\n */\r\n this.dLevel = l2 || 0;\r\n /**\r\n * Duration of the release portion of the envelope.\r\n * @property releaseTime\r\n */\r\n this.rTime = t3 || 0;\r\n /**\r\n * Level at the end of the release.\r\n * @property releaseLevel\r\n */\r\n this.rLevel = l3 || 0;\r\n\r\n this._rampHighPercentage = 0.98;\r\n\r\n this._rampLowPercentage = 0.02;\r\n\r\n\r\n this.output = p5sound.audiocontext.createGain();\r\n\r\n this.control = new TimelineSignal();\r\n\r\n this._init(); // this makes sure the envelope starts at zero\r\n\r\n this.control.connect(this.output); // connect to the output\r\n\r\n this.connection = null; // store connection\r\n\r\n //array of math operation signal chaining\r\n this.mathOps = [this.control];\r\n\r\n //whether envelope should be linear or exponential curve\r\n this.isExponential = false;\r\n\r\n // oscillator or buffer source to clear on env complete\r\n // to save resources if/when it is retriggered\r\n this.sourceToClear = null;\r\n\r\n // set to true if attack is set, then false on release\r\n this.wasTriggered = false;\r\n\r\n\r\n // add to the soundArray so we can dispose of the env later\r\n p5sound.soundArray.push(this);\r\n };\r\n\r\n // this init function just smooths the starting value to zero and gives a start point for the timeline\r\n // - it was necessary to remove glitches at the beginning.\r\n p5.Envelope.prototype._init = function () {\r\n var now = p5sound.audiocontext.currentTime;\r\n var t = now;\r\n this.control.setTargetAtTime(0.00001, t, .001);\r\n //also, compute the correct time constants\r\n this._setRampAD(this.aTime, this.dTime);\r\n };\r\n\r\n /**\r\n * Reset the envelope with a series of time/value pairs.\r\n *\r\n * @method set\r\n * @for p5.Envelope\r\n * @param {Number} attackTime Time (in seconds) before level\r\n * reaches attackLevel\r\n * @param {Number} attackLevel Typically an amplitude between\r\n * 0.0 and 1.0\r\n * @param {Number} decayTime Time\r\n * @param {Number} decayLevel Amplitude (In a standard ADSR envelope,\r\n * decayLevel = sustainLevel)\r\n * @param {Number} releaseTime Release Time (in seconds)\r\n * @param {Number} releaseLevel Amplitude\r\n * @example\r\n *
\r\n * var t1 = 0.1; // attack time in seconds\r\n * var l1 = 0.7; // attack level 0.0 to 1.0\r\n * var t2 = 0.3; // decay time in seconds\r\n * var l2 = 0.1; // decay level 0.0 to 1.0\r\n * var t3 = 0.2; // sustain time in seconds\r\n * var l3 = 0.5; // sustain level 0.0 to 1.0\r\n * // release level defaults to zero\r\n *\r\n * var env;\r\n * var triOsc;\r\n *\r\n * function setup() {\r\n * background(0);\r\n * noStroke();\r\n * fill(255);\r\n * textAlign(CENTER);\r\n * text('click to play', width/2, height/2);\r\n *\r\n * env = new p5.Envelope(t1, l1, t2, l2, t3, l3);\r\n * triOsc = new p5.Oscillator('triangle');\r\n * triOsc.amp(env); // give the env control of the triOsc's amp\r\n * triOsc.start();\r\n * }\r\n *\r\n * // mouseClick triggers envelope if over canvas\r\n * function mouseClicked() {\r\n * // is mouse over canvas?\r\n * if (mouseX > 0 && mouseX < width && mouseY > 0 && mouseY < height) {\r\n * env.play(triOsc);\r\n * }\r\n * }\r\n *
\r\n *\r\n */\r\n p5.Envelope.prototype.set = function(t1, l1, t2, l2, t3, l3) {\r\n this.aTime = t1;\r\n this.aLevel = l1;\r\n this.dTime = t2 || 0;\r\n this.dLevel = l2 || 0;\r\n this.rTime = t3 || 0;\r\n this.rLevel = l3 || 0;\r\n\r\n // set time constants for ramp\r\n this._setRampAD(t1, t2);\r\n };\r\n\r\n /**\r\n * Set values like a traditional\r\n * \r\n * ADSR envelope\r\n * .\r\n *\r\n * @method setADSR\r\n * @for p5.Envelope\r\n * @param {Number} attackTime Time (in seconds before envelope\r\n * reaches Attack Level\r\n * @param {Number} [decayTime] Time (in seconds) before envelope\r\n * reaches Decay/Sustain Level\r\n * @param {Number} [susRatio] Ratio between attackLevel and releaseLevel, on a scale from 0 to 1,\r\n * where 1.0 = attackLevel, 0.0 = releaseLevel.\r\n * The susRatio determines the decayLevel and the level at which the\r\n * sustain portion of the envelope will sustain.\r\n * For example, if attackLevel is 0.4, releaseLevel is 0,\r\n * and susAmt is 0.5, the decayLevel would be 0.2. If attackLevel is\r\n * increased to 1.0 (using setRange),\r\n * then decayLevel would increase proportionally, to become 0.5.\r\n * @param {Number} [releaseTime] Time in seconds from now (defaults to 0)\r\n * @example\r\n *
\r\n * var attackLevel = 1.0;\r\n * var releaseLevel = 0;\r\n *\r\n * var attackTime = 0.001;\r\n * var decayTime = 0.2;\r\n * var susPercent = 0.2;\r\n * var releaseTime = 0.5;\r\n *\r\n * var env, triOsc;\r\n *\r\n * function setup() {\r\n * var cnv = createCanvas(100, 100);\r\n *\r\n * textAlign(CENTER);\r\n * text('click to play', width/2, height/2);\r\n *\r\n * env = new p5.Envelope();\r\n * env.setADSR(attackTime, decayTime, susPercent, releaseTime);\r\n * env.setRange(attackLevel, releaseLevel);\r\n *\r\n * triOsc = new p5.Oscillator('triangle');\r\n * triOsc.amp(env);\r\n * triOsc.start();\r\n * triOsc.freq(220);\r\n *\r\n * cnv.mousePressed(playEnv);\r\n * }\r\n *\r\n * function playEnv() {\r\n * env.play();\r\n * }\r\n *
\r\n */\r\n p5.Envelope.prototype.setADSR = function(aTime, dTime, sPercent, rTime) {\r\n this.aTime = aTime;\r\n this.dTime = dTime || 0;\r\n\r\n // lerp\r\n this.sPercent = sPercent || 0;\r\n this.dLevel = typeof sPercent !== 'undefined' ? sPercent * (this.aLevel - this.rLevel) + this.rLevel : 0;\r\n\r\n this.rTime = rTime || 0;\r\n\r\n // also set time constants for ramp\r\n this._setRampAD(aTime, dTime);\r\n };\r\n\r\n /**\r\n * Set max (attackLevel) and min (releaseLevel) of envelope.\r\n *\r\n * @method setRange\r\n * @for p5.Envelope\r\n * @param {Number} aLevel attack level (defaults to 1)\r\n * @param {Number} rLevel release level (defaults to 0)\r\n * @example\r\n *
\r\n * var attackLevel = 1.0;\r\n * var releaseLevel = 0;\r\n *\r\n * var attackTime = 0.001;\r\n * var decayTime = 0.2;\r\n * var susPercent = 0.2;\r\n * var releaseTime = 0.5;\r\n *\r\n * var env, triOsc;\r\n *\r\n * function setup() {\r\n * var cnv = createCanvas(100, 100);\r\n *\r\n * textAlign(CENTER);\r\n * text('click to play', width/2, height/2);\r\n *\r\n * env = new p5.Envelope();\r\n * env.setADSR(attackTime, decayTime, susPercent, releaseTime);\r\n * env.setRange(attackLevel, releaseLevel);\r\n *\r\n * triOsc = new p5.Oscillator('triangle');\r\n * triOsc.amp(env);\r\n * triOsc.start();\r\n * triOsc.freq(220);\r\n *\r\n * cnv.mousePressed(playEnv);\r\n * }\r\n *\r\n * function playEnv() {\r\n * env.play();\r\n * }\r\n *
\r\n */\r\n p5.Envelope.prototype.setRange = function(aLevel, rLevel) {\r\n this.aLevel = aLevel || 1;\r\n this.rLevel = rLevel || 0;\r\n\r\n // not sure if this belongs here:\r\n\r\n // {Number} [dLevel] decay/sustain level (optional)\r\n // if (typeof(dLevel) !== 'undefined') {\r\n // this.dLevel = dLevel\r\n // } else if (this.sPercent) {\r\n // this.dLevel = this.sPercent ? this.sPercent * (this.aLevel - this.rLevel) + this.rLevel : 0;\r\n // }\r\n };\r\n\r\n // private (undocumented) method called when ADSR is set to set time constants for ramp\r\n //\r\n // Set the \r\n // time constants for simple exponential ramps.\r\n // The larger the time constant value, the slower the\r\n // transition will be.\r\n //\r\n // method _setRampAD\r\n // param {Number} attackTimeConstant attack time constant\r\n // param {Number} decayTimeConstant decay time constant\r\n //\r\n p5.Envelope.prototype._setRampAD = function(t1, t2) {\r\n this._rampAttackTime = this.checkExpInput(t1);\r\n this._rampDecayTime = this.checkExpInput(t2);\r\n\r\n var TCDenominator = 1.0;\r\n /// Aatish Bhatia's calculation for time constant for rise(to adjust 1/1-e calculation to any percentage)\r\n TCDenominator = Math.log(1.0 / this.checkExpInput(1.0 - this._rampHighPercentage));\r\n this._rampAttackTC = t1 / this.checkExpInput(TCDenominator);\r\n TCDenominator = Math.log(1.0 / this._rampLowPercentage);\r\n this._rampDecayTC = t2 / this.checkExpInput(TCDenominator);\r\n };\r\n\r\n // private method\r\n p5.Envelope.prototype.setRampPercentages = function(p1, p2) {\r\n //set the percentages that the simple exponential ramps go to\r\n this._rampHighPercentage = this.checkExpInput(p1);\r\n this._rampLowPercentage = this.checkExpInput(p2);\r\n var TCDenominator = 1.0;\r\n //now re-compute the time constants based on those percentages\r\n /// Aatish Bhatia's calculation for time constant for rise(to adjust 1/1-e calculation to any percentage)\r\n TCDenominator = Math.log(1.0 / this.checkExpInput(1.0 - this._rampHighPercentage));\r\n this._rampAttackTC = this._rampAttackTime / this.checkExpInput(TCDenominator);\r\n TCDenominator = Math.log(1.0 / this._rampLowPercentage);\r\n this._rampDecayTC = this._rampDecayTime / this.checkExpInput(TCDenominator);\r\n };\r\n\r\n\r\n /**\r\n * Assign a parameter to be controlled by this envelope.\r\n * If a p5.Sound object is given, then the p5.Envelope will control its\r\n * output gain. If multiple inputs are provided, the env will\r\n * control all of them.\r\n *\r\n * @method setInput\r\n * @for p5.Envelope\r\n * @param {Object} [...inputs] A p5.sound object or\r\n * Web Audio Param.\r\n */\r\n p5.Envelope.prototype.setInput = function() {\r\n for (var i = 0; i\r\n * Web Audio Audio Param.\r\n *\r\n * @method play\r\n * @for p5.Envelope\r\n * @param {Object} unit A p5.sound object or\r\n * Web Audio Param.\r\n * @param {Number} [startTime] time from now (in seconds) at which to play\r\n * @param {Number} [sustainTime] time to sustain before releasing the envelope\r\n * @example\r\n *
\r\n * var attackLevel = 1.0;\r\n * var releaseLevel = 0;\r\n *\r\n * var attackTime = 0.001;\r\n * var decayTime = 0.2;\r\n * var susPercent = 0.2;\r\n * var releaseTime = 0.5;\r\n *\r\n * var env, triOsc;\r\n *\r\n * function setup() {\r\n * var cnv = createCanvas(100, 100);\r\n *\r\n * textAlign(CENTER);\r\n * text('click to play', width/2, height/2);\r\n *\r\n * env = new p5.Envelope();\r\n * env.setADSR(attackTime, decayTime, susPercent, releaseTime);\r\n * env.setRange(attackLevel, releaseLevel);\r\n *\r\n * triOsc = new p5.Oscillator('triangle');\r\n * triOsc.amp(env);\r\n * triOsc.start();\r\n * triOsc.freq(220);\r\n *\r\n * cnv.mousePressed(playEnv);\r\n * }\r\n *\r\n * function playEnv() {\r\n * // trigger env on triOsc, 0 seconds from now\r\n * // After decay, sustain for 0.2 seconds before release\r\n * env.play(triOsc, 0, 0.2);\r\n * }\r\n *
\r\n */\r\n p5.Envelope.prototype.play = function(unit, secondsFromNow, susTime) {\r\n var tFromNow = secondsFromNow || 0;\r\n var susTime = susTime || 0;\r\n\r\n if (unit) {\r\n if (this.connection !== unit) {\r\n this.connect(unit);\r\n }\r\n }\r\n\r\n this.triggerAttack(unit, tFromNow);\r\n\r\n this.triggerRelease(unit, tFromNow + this.aTime + this.dTime + susTime);\r\n\r\n };\r\n\r\n /**\r\n * Trigger the Attack, and Decay portion of the Envelope.\r\n * Similar to holding down a key on a piano, but it will\r\n * hold the sustain level until you let go. Input can be\r\n * any p5.sound object, or a \r\n * Web Audio Param.\r\n *\r\n * @method triggerAttack\r\n * @for p5.Envelope\r\n * @param {Object} unit p5.sound Object or Web Audio Param\r\n * @param {Number} secondsFromNow time from now (in seconds)\r\n * @example\r\n *
\r\n *\r\n * var attackLevel = 1.0;\r\n * var releaseLevel = 0;\r\n *\r\n * var attackTime = 0.001;\r\n * var decayTime = 0.3;\r\n * var susPercent = 0.4;\r\n * var releaseTime = 0.5;\r\n *\r\n * var env, triOsc;\r\n *\r\n * function setup() {\r\n * var cnv = createCanvas(100, 100);\r\n * background(200);\r\n * textAlign(CENTER);\r\n * text('click to play', width/2, height/2);\r\n *\r\n * env = new p5.Envelope();\r\n * env.setADSR(attackTime, decayTime, susPercent, releaseTime);\r\n * env.setRange(attackLevel, releaseLevel);\r\n *\r\n * triOsc = new p5.Oscillator('triangle');\r\n * triOsc.amp(env);\r\n * triOsc.start();\r\n * triOsc.freq(220);\r\n *\r\n * cnv.mousePressed(envAttack);\r\n * }\r\n *\r\n * function envAttack() {\r\n * console.log('trigger attack');\r\n * env.triggerAttack();\r\n *\r\n * background(0,255,0);\r\n * text('attack!', width/2, height/2);\r\n * }\r\n *\r\n * function mouseReleased() {\r\n * env.triggerRelease();\r\n *\r\n * background(200);\r\n * text('click to play', width/2, height/2);\r\n * }\r\n *
\r\n */\r\n p5.Envelope.prototype.triggerAttack = function(unit, secondsFromNow) {\r\n var now = p5sound.audiocontext.currentTime;\r\n var tFromNow = secondsFromNow || 0;\r\n var t = now + tFromNow;\r\n this.lastAttack = t;\r\n this.wasTriggered = true;\r\n\r\n if (unit) {\r\n if (this.connection !== unit) {\r\n this.connect(unit);\r\n }\r\n }\r\n\r\n // get and set value (with linear ramp) to anchor automation\r\n var valToSet = this.control.getValueAtTime(t);\r\n\r\n if (this.isExponential === true)\r\n {\r\n this.control.exponentialRampToValueAtTime(this.checkExpInput(valToSet), t);\r\n }\r\n else\r\n {\r\n this.control.linearRampToValueAtTime(valToSet, t);\r\n }\r\n\r\n // after each ramp completes, cancel scheduled values\r\n // (so they can be overridden in case env has been re-triggered)\r\n // then, set current value (with linearRamp to avoid click)\r\n // then, schedule the next automation...\r\n\r\n // attack\r\n t += this.aTime;\r\n if (this.isExponential === true)\r\n {\r\n this.control.exponentialRampToValueAtTime(this.checkExpInput(this.aLevel), t);\r\n valToSet = this.checkExpInput(this.control.getValueAtTime(t));\r\n this.control.cancelScheduledValues(t);\r\n this.control.exponentialRampToValueAtTime(valToSet, t);\r\n }\r\n else\r\n {\r\n this.control.linearRampToValueAtTime(this.aLevel, t);\r\n valToSet = this.control.getValueAtTime(t);\r\n this.control.cancelScheduledValues(t);\r\n this.control.linearRampToValueAtTime(valToSet, t);\r\n\r\n }\r\n\r\n // decay to decay level (if using ADSR, then decay level == sustain level)\r\n t += this.dTime;\r\n if (this.isExponential === true)\r\n {\r\n this.control.exponentialRampToValueAtTime(this.checkExpInput(this.dLevel), t);\r\n valToSet = this.checkExpInput(this.control.getValueAtTime(t));\r\n this.control.cancelScheduledValues(t);\r\n this.control.exponentialRampToValueAtTime(valToSet, t);\r\n }\r\n else\r\n {\r\n this.control.linearRampToValueAtTime(this.dLevel, t);\r\n valToSet = this.control.getValueAtTime(t);\r\n this.control.cancelScheduledValues(t);\r\n this.control.linearRampToValueAtTime(valToSet, t);\r\n }\r\n };\r\n\r\n /**\r\n * Trigger the Release of the Envelope. This is similar to releasing\r\n * the key on a piano and letting the sound fade according to the\r\n * release level and release time.\r\n *\r\n * @method triggerRelease\r\n * @for p5.Envelope\r\n * @param {Object} unit p5.sound Object or Web Audio Param\r\n * @param {Number} secondsFromNow time to trigger the release\r\n * @example\r\n *
\r\n *\r\n * var attackLevel = 1.0;\r\n * var releaseLevel = 0;\r\n *\r\n * var attackTime = 0.001;\r\n * var decayTime = 0.3;\r\n * var susPercent = 0.4;\r\n * var releaseTime = 0.5;\r\n *\r\n * var env, triOsc;\r\n *\r\n * function setup() {\r\n * var cnv = createCanvas(100, 100);\r\n * background(200);\r\n * textAlign(CENTER);\r\n * text('click to play', width/2, height/2);\r\n *\r\n * env = new p5.Envelope();\r\n * env.setADSR(attackTime, decayTime, susPercent, releaseTime);\r\n * env.setRange(attackLevel, releaseLevel);\r\n *\r\n * triOsc = new p5.Oscillator('triangle');\r\n * triOsc.amp(env);\r\n * triOsc.start();\r\n * triOsc.freq(220);\r\n *\r\n * cnv.mousePressed(envAttack);\r\n * }\r\n *\r\n * function envAttack() {\r\n * console.log('trigger attack');\r\n * env.triggerAttack();\r\n *\r\n * background(0,255,0);\r\n * text('attack!', width/2, height/2);\r\n * }\r\n *\r\n * function mouseReleased() {\r\n * env.triggerRelease();\r\n *\r\n * background(200);\r\n * text('click to play', width/2, height/2);\r\n * }\r\n *
\r\n */\r\n p5.Envelope.prototype.triggerRelease = function(unit, secondsFromNow) {\r\n\r\n // only trigger a release if an attack was triggered\r\n if (!this.wasTriggered) {\r\n // this currently causes a bit of trouble:\r\n // if a later release has been scheduled (via the play function)\r\n // a new earlier release won't interrupt it, because\r\n // this.wasTriggered has already been set to false.\r\n // If we want new earlier releases to override, then we need to\r\n // keep track of the last release time, and if the new release time is\r\n // earlier, then use it.\r\n return;\r\n }\r\n\r\n var now = p5sound.audiocontext.currentTime;\r\n var tFromNow = secondsFromNow || 0;\r\n var t = now + tFromNow;\r\n\r\n if (unit) {\r\n if (this.connection !== unit) {\r\n this.connect(unit);\r\n }\r\n }\r\n\r\n // get and set value (with linear or exponential ramp) to anchor automation\r\n var valToSet = this.control.getValueAtTime(t);\r\n if (this.isExponential === true)\r\n {\r\n this.control.exponentialRampToValueAtTime(this.checkExpInput(valToSet), t);\r\n }\r\n else\r\n {\r\n this.control.linearRampToValueAtTime(valToSet, t);\r\n }\r\n\r\n // release\r\n t += this.rTime;\r\n\r\n if (this.isExponential === true)\r\n {\r\n this.control.exponentialRampToValueAtTime(this.checkExpInput(this.rLevel), t);\r\n valToSet = this.checkExpInput(this.control.getValueAtTime(t));\r\n this.control.cancelScheduledValues(t);\r\n this.control.exponentialRampToValueAtTime(valToSet, t);\r\n }\r\n else\r\n {\r\n this.control.linearRampToValueAtTime(this.rLevel, t);\r\n valToSet = this.control.getValueAtTime(t);\r\n this.control.cancelScheduledValues(t);\r\n this.control.linearRampToValueAtTime(valToSet, t);\r\n }\r\n\r\n this.wasTriggered = false;\r\n };\r\n\r\n /**\r\n * Exponentially ramp to a value using the first two\r\n * values from setADSR(attackTime, decayTime)\r\n * as \r\n * time constants for simple exponential ramps.\r\n * If the value is higher than current value, it uses attackTime,\r\n * while a decrease uses decayTime.\r\n *\r\n * @method ramp\r\n * @for p5.Envelope\r\n * @param {Object} unit p5.sound Object or Web Audio Param\r\n * @param {Number} secondsFromNow When to trigger the ramp\r\n * @param {Number} v Target value\r\n * @param {Number} [v2] Second target value (optional)\r\n * @example\r\n *
\r\n * var env, osc, amp, cnv;\r\n *\r\n * var attackTime = 0.001;\r\n * var decayTime = 0.2;\r\n * var attackLevel = 1;\r\n * var decayLevel = 0;\r\n *\r\n * function setup() {\r\n * cnv = createCanvas(100, 100);\r\n * fill(0,255,0);\r\n * noStroke();\r\n *\r\n * env = new p5.Envelope();\r\n * env.setADSR(attackTime, decayTime);\r\n *\r\n * osc = new p5.Oscillator();\r\n * osc.amp(env);\r\n * osc.start();\r\n *\r\n * amp = new p5.Amplitude();\r\n *\r\n * cnv.mousePressed(triggerRamp);\r\n * }\r\n *\r\n * function triggerRamp() {\r\n * env.ramp(osc, 0, attackLevel, decayLevel);\r\n * }\r\n *\r\n * function draw() {\r\n * background(20,20,20);\r\n * text('click me', 10, 20);\r\n * var h = map(amp.getLevel(), 0, 0.4, 0, height);;\r\n *\r\n * rect(0, height, width, -h);\r\n * }\r\n *
\r\n */\r\n p5.Envelope.prototype.ramp = function(unit, secondsFromNow, v1, v2) {\r\n\r\n var now = p5sound.audiocontext.currentTime;\r\n var tFromNow = secondsFromNow || 0;\r\n var t = now + tFromNow;\r\n var destination1 = this.checkExpInput(v1);\r\n var destination2 = typeof v2 !== 'undefined' ? this.checkExpInput(v2) : undefined;\r\n\r\n // connect env to unit if not already connected\r\n if (unit) {\r\n if (this.connection !== unit) {\r\n this.connect(unit);\r\n }\r\n }\r\n\r\n //get current value\r\n var currentVal = this.checkExpInput(this.control.getValueAtTime(t));\r\n // this.control.cancelScheduledValues(t);\r\n\r\n //if it's going up\r\n if (destination1 > currentVal) {\r\n this.control.setTargetAtTime(destination1, t, this._rampAttackTC);\r\n t += this._rampAttackTime;\r\n }\r\n\r\n //if it's going down\r\n else if (destination1 < currentVal) {\r\n this.control.setTargetAtTime(destination1, t, this._rampDecayTC);\r\n t += this._rampDecayTime;\r\n }\r\n\r\n // Now the second part of envelope begins\r\n if (destination2 === undefined) return;\r\n\r\n //if it's going up\r\n if (destination2 > destination1) {\r\n this.control.setTargetAtTime(destination2, t, this._rampAttackTC);\r\n }\r\n\r\n //if it's going down\r\n else if (destination2 < destination1) {\r\n this.control.setTargetAtTime(destination2, t, this._rampDecayTC);\r\n }\r\n };\r\n\r\n\r\n p5.Envelope.prototype.connect = function(unit) {\r\n this.connection = unit;\r\n\r\n // assume we're talking about output gain\r\n // unless given a different audio param\r\n if (unit instanceof p5.Oscillator ||\r\n unit instanceof p5.SoundFile ||\r\n unit instanceof p5.AudioIn ||\r\n unit instanceof p5.Reverb ||\r\n unit instanceof p5.Noise ||\r\n unit instanceof p5.Filter ||\r\n unit instanceof p5.Delay\r\n ) {\r\n unit = unit.output.gain;\r\n }\r\n if (unit instanceof AudioParam) {\r\n //set the initial value\r\n unit.setValueAtTime(0, p5sound.audiocontext.currentTime);\r\n }\r\n if (unit instanceof p5.Signal) {\r\n unit.setValue(0);\r\n }\r\n this.output.connect(unit);\r\n };\r\n\r\n p5.Envelope.prototype.disconnect = function() {\r\n if (this.output) {\r\n this.output.disconnect();\r\n }\r\n };\r\n\r\n\r\n // Signal Math\r\n\r\n /**\r\n * Add a value to the p5.Oscillator's output amplitude,\r\n * and return the oscillator. Calling this method\r\n * again will override the initial add() with new values.\r\n *\r\n * @method add\r\n * @for p5.Envelope\r\n * @param {Number} number Constant number to add\r\n * @return {p5.Envelope} Envelope Returns this envelope\r\n * with scaled output\r\n */\r\n p5.Envelope.prototype.add = function(num) {\r\n var add = new Add(num);\r\n var thisChain = this.mathOps.length;\r\n var nextChain = this.output;\r\n return p5.prototype._mathChain(this, add, thisChain, nextChain, Add);\r\n };\r\n\r\n /**\r\n * Multiply the p5.Envelope's output amplitude\r\n * by a fixed value. Calling this method\r\n * again will override the initial mult() with new values.\r\n *\r\n * @method mult\r\n * @for p5.Envelope\r\n * @param {Number} number Constant number to multiply\r\n * @return {p5.Envelope} Envelope Returns this envelope\r\n * with scaled output\r\n */\r\n p5.Envelope.prototype.mult = function(num) {\r\n var mult = new Mult(num);\r\n var thisChain = this.mathOps.length;\r\n var nextChain = this.output;\r\n return p5.prototype._mathChain(this, mult, thisChain, nextChain, Mult);\r\n };\r\n\r\n /**\r\n * Scale this envelope's amplitude values to a given\r\n * range, and return the envelope. Calling this method\r\n * again will override the initial scale() with new values.\r\n *\r\n * @method scale\r\n * @for p5.Envelope\r\n * @param {Number} inMin input range minumum\r\n * @param {Number} inMax input range maximum\r\n * @param {Number} outMin input range minumum\r\n * @param {Number} outMax input range maximum\r\n * @return {p5.Envelope} Envelope Returns this envelope\r\n * with scaled output\r\n */\r\n p5.Envelope.prototype.scale = function(inMin, inMax, outMin, outMax) {\r\n var scale = new Scale(inMin, inMax, outMin, outMax);\r\n var thisChain = this.mathOps.length;\r\n var nextChain = this.output;\r\n return p5.prototype._mathChain(this, scale, thisChain, nextChain, Scale);\r\n };\r\n\r\n\r\n // get rid of the oscillator\r\n p5.Envelope.prototype.dispose = function() {\r\n // remove reference from soundArray\r\n var index = p5sound.soundArray.indexOf(this);\r\n p5sound.soundArray.splice(index, 1);\r\n\r\n this.disconnect();\r\n if (this.control) {\r\n this.control.dispose();\r\n this.control = null;\r\n }\r\n for (var i = 1; i < this.mathOps.length; i++) {\r\n this.mathOps[i].dispose();\r\n }\r\n };\r\n\r\n // Different name for backwards compatibility, replicates p5.Envelope class\r\n p5.Env = function(t1, l1, t2, l2, t3, l3) {\r\n console.warn('WARNING: p5.Env is now deprecated and may be removed in future versions. ' +\r\n 'Please use the new p5.Envelope instead.');\r\n p5.Envelope.call(this, t1, l1, t2, l2, t3, l3);\r\n };\r\n p5.Env.prototype = Object.create(p5.Envelope.prototype);\r\n\r\n});\r\n","'use strict';\r\n\r\ndefine(function (require) {\r\n\r\n var p5sound = require('master');\r\n require('oscillator');\r\n\r\n /**\r\n * Creates a Pulse object, an oscillator that implements\r\n * Pulse Width Modulation.\r\n * The pulse is created with two oscillators.\r\n * Accepts a parameter for frequency, and to set the\r\n * width between the pulses. See \r\n * p5.Oscillator for a full list of methods.\r\n *\r\n * @class p5.Pulse\r\n * @extends p5.Oscillator\r\n * @constructor\r\n * @param {Number} [freq] Frequency in oscillations per second (Hz)\r\n * @param {Number} [w] Width between the pulses (0 to 1.0,\r\n * defaults to 0)\r\n * @example\r\n *
Note: This uses the getUserMedia/\r\n * Stream API, which is not supported by certain browsers. Access in Chrome browser\r\n * is limited to localhost and https, but access over http may be limited.
\r\n *\r\n * @class p5.AudioIn\r\n * @constructor\r\n * @param {Function} [errorCallback] A function to call if there is an error\r\n * accessing the AudioIn. For example,\r\n * Safari and iOS devices do not\r\n * currently allow microphone access.\r\n * @example\r\n *
\r\n * var mic;\r\n * function setup(){\r\n * mic = new p5.AudioIn()\r\n * mic.start();\r\n * }\r\n * function draw(){\r\n * background(0);\r\n * micLevel = mic.getLevel();\r\n * ellipse(width/2, constrain(height-micLevel*height*5, 0, height), 10, 10);\r\n * }\r\n *
\r\n */\r\n p5.AudioIn = function(errorCallback) {\r\n // set up audio input\r\n /**\r\n * @property {GainNode} input\r\n */\r\n this.input = p5sound.audiocontext.createGain();\r\n /**\r\n * @property {GainNode} output\r\n */\r\n this.output = p5sound.audiocontext.createGain();\r\n\r\n /**\r\n * @property {MediaStream|null} stream\r\n */\r\n this.stream = null;\r\n /**\r\n * @property {MediaStreamAudioSourceNode|null} mediaStream\r\n */\r\n this.mediaStream = null;\r\n /**\r\n * @property {Number|null} currentSource\r\n */\r\n this.currentSource = null;\r\n\r\n /**\r\n * Client must allow browser to access their microphone / audioin source.\r\n * Default: false. Will become true when the client enables acces.\r\n *\r\n * @property {Boolean} enabled\r\n */\r\n this.enabled = false;\r\n\r\n /**\r\n * Input amplitude, connect to it by default but not to master out\r\n *\r\n * @property {p5.Amplitude} amplitude\r\n */\r\n this.amplitude = new p5.Amplitude();\r\n this.output.connect(this.amplitude.input);\r\n\r\n if (!window.MediaStreamTrack || !window.navigator.mediaDevices || !window.navigator.mediaDevices.getUserMedia) {\r\n errorCallback ? errorCallback() : window.alert('This browser does not support MediaStreamTrack and mediaDevices');\r\n }\r\n\r\n // add to soundArray so we can dispose on close\r\n p5sound.soundArray.push(this);\r\n };\r\n\r\n /**\r\n * Start processing audio input. This enables the use of other\r\n * AudioIn methods like getLevel(). Note that by default, AudioIn\r\n * is not connected to p5.sound's output. So you won't hear\r\n * anything unless you use the connect() method. \r\n *\r\n * Certain browsers limit access to the user's microphone. For example,\r\n * Chrome only allows access from localhost and over https. For this reason,\r\n * you may want to include an errorCallback—a function that is called in case\r\n * the browser won't provide mic access.\r\n *\r\n * @method start\r\n * @for p5.AudioIn\r\n * @param {Function} [successCallback] Name of a function to call on\r\n * success.\r\n * @param {Function} [errorCallback] Name of a function to call if\r\n * there was an error. For example,\r\n * some browsers do not support\r\n * getUserMedia.\r\n */\r\n p5.AudioIn.prototype.start = function(successCallback, errorCallback) {\r\n var self = this;\r\n\r\n if (this.stream) {\r\n this.stop();\r\n }\r\n\r\n // set the audio source\r\n var audioSource = p5sound.inputSources[self.currentSource];\r\n var constraints = {\r\n audio: {\r\n sampleRate: p5sound.audiocontext.sampleRate,\r\n echoCancellation: false\r\n }\r\n };\r\n\r\n // if developers determine which source to use\r\n if (p5sound.inputSources[this.currentSource]) {\r\n constraints.audio.deviceId = audioSource.deviceId;\r\n }\r\n\r\n window.navigator.mediaDevices.getUserMedia( constraints )\r\n .then( function(stream) {\r\n self.stream = stream;\r\n self.enabled = true;\r\n // Wrap a MediaStreamSourceNode around the live input\r\n self.mediaStream = p5sound.audiocontext.createMediaStreamSource(stream);\r\n self.mediaStream.connect(self.output);\r\n // only send to the Amplitude reader, so we can see it but not hear it.\r\n self.amplitude.setInput(self.output);\r\n if (successCallback) successCallback();\r\n })\r\n .catch( function(err) {\r\n if (errorCallback) errorCallback(err);\r\n else console.error(err);\r\n });\r\n };\r\n\r\n /**\r\n * Turn the AudioIn off. If the AudioIn is stopped, it cannot getLevel().\r\n * If re-starting, the user may be prompted for permission access.\r\n *\r\n * @method stop\r\n * @for p5.AudioIn\r\n */\r\n p5.AudioIn.prototype.stop = function() {\r\n if (this.stream) {\r\n this.stream.getTracks().forEach(function(track) {\r\n track.stop();\r\n });\r\n\r\n this.mediaStream.disconnect();\r\n\r\n delete this.mediaStream;\r\n delete this.stream;\r\n }\r\n };\r\n\r\n /**\r\n * Connect to an audio unit. If no parameter is provided, will\r\n * connect to the master output (i.e. your speakers). \r\n *\r\n * @method connect\r\n * @for p5.AudioIn\r\n * @param {Object} [unit] An object that accepts audio input,\r\n * such as an FFT\r\n */\r\n p5.AudioIn.prototype.connect = function(unit) {\r\n if (unit) {\r\n if (unit.hasOwnProperty('input')) {\r\n this.output.connect(unit.input);\r\n }\r\n else if (unit.hasOwnProperty('analyser')) {\r\n this.output.connect(unit.analyser);\r\n }\r\n else {\r\n this.output.connect(unit);\r\n }\r\n }\r\n else {\r\n this.output.connect(p5sound.input);\r\n }\r\n };\r\n\r\n /**\r\n * Disconnect the AudioIn from all audio units. For example, if\r\n * connect() had been called, disconnect() will stop sending\r\n * signal to your speakers. \r\n *\r\n * @method disconnect\r\n * @for p5.AudioIn\r\n */\r\n p5.AudioIn.prototype.disconnect = function() {\r\n if (this.output) {\r\n this.output.disconnect();\r\n // stay connected to amplitude even if not outputting to p5\r\n this.output.connect(this.amplitude.input);\r\n }\r\n };\r\n\r\n /**\r\n * Read the Amplitude (volume level) of an AudioIn. The AudioIn\r\n * class contains its own instance of the Amplitude class to help\r\n * make it easy to get a microphone's volume level. Accepts an\r\n * optional smoothing value (0.0 < 1.0). NOTE: AudioIn must\r\n * .start() before using .getLevel(). \r\n *\r\n * @method getLevel\r\n * @for p5.AudioIn\r\n * @param {Number} [smoothing] Smoothing is 0.0 by default.\r\n * Smooths values based on previous values.\r\n * @return {Number} Volume level (between 0.0 and 1.0)\r\n */\r\n p5.AudioIn.prototype.getLevel = function(smoothing) {\r\n if (smoothing) {\r\n this.amplitude.smoothing = smoothing;\r\n }\r\n return this.amplitude.getLevel();\r\n };\r\n\r\n /**\r\n * Set amplitude (volume) of a mic input between 0 and 1.0. \r\n *\r\n * @method amp\r\n * @for p5.AudioIn\r\n * @param {Number} vol between 0 and 1.0\r\n * @param {Number} [time] ramp time (optional)\r\n */\r\n p5.AudioIn.prototype.amp = function(vol, t) {\r\n if (t) {\r\n var rampTime = t || 0;\r\n var currentVol = this.output.gain.value;\r\n this.output.gain.cancelScheduledValues(p5sound.audiocontext.currentTime);\r\n this.output.gain.setValueAtTime(currentVol, p5sound.audiocontext.currentTime);\r\n this.output.gain.linearRampToValueAtTime(vol, rampTime + p5sound.audiocontext.currentTime);\r\n } else {\r\n this.output.gain.cancelScheduledValues(p5sound.audiocontext.currentTime);\r\n this.output.gain.setValueAtTime(vol, p5sound.audiocontext.currentTime);\r\n }\r\n };\r\n\r\n /**\r\n * Returns a list of available input sources. This is a wrapper\r\n * for and it returns a Promise.\r\n *\r\n * @method getSources\r\n * @for p5.AudioIn\r\n * @param {Function} [successCallback] This callback function handles the sources when they\r\n * have been enumerated. The callback function\r\n * receives the deviceList array as its only argument\r\n * @param {Function} [errorCallback] This optional callback receives the error\r\n * message as its argument.\r\n * @returns {Promise} Returns a Promise that can be used in place of the callbacks, similar\r\n * to the enumerateDevices() method\r\n * @example\r\n *
\r\n */\r\n p5.AudioIn.prototype.getSources = function (onSuccess, onError) {\r\n return new Promise( function(resolve, reject) {\r\n window.navigator.mediaDevices.enumerateDevices()\r\n .then( function(devices) {\r\n p5sound.inputSources = devices.filter(function(device) {\r\n return device.kind === 'audioinput';\r\n });\r\n resolve(p5sound.inputSources);\r\n if (onSuccess) {\r\n onSuccess(p5sound.inputSources);\r\n }\r\n })\r\n .catch( function(error) {\r\n reject(error);\r\n if (onError) {\r\n onError(error);\r\n } else {\r\n console.error('This browser does not support MediaStreamTrack.getSources()');\r\n }\r\n });\r\n });\r\n };\r\n\r\n /**\r\n * Set the input source. Accepts a number representing a\r\n * position in the array returned by getSources().\r\n * This is only available in browsers that support\r\n * navigator.mediaDevices.enumerateDevices(). \r\n *\r\n * @method setSource\r\n * @for p5.AudioIn\r\n * @param {number} num position of input source in the array\r\n */\r\n p5.AudioIn.prototype.setSource = function(num) {\r\n if (p5sound.inputSources.length > 0 && num < p5sound.inputSources.length) {\r\n // set the current source\r\n this.currentSource = num;\r\n console.log('set source to ', p5sound.inputSources[this.currentSource]);\r\n } else {\r\n console.log('unable to set input source');\r\n }\r\n\r\n // restart stream if currently active\r\n if (this.stream && this.stream.active) {\r\n this.start();\r\n }\r\n };\r\n\r\n // private method\r\n p5.AudioIn.prototype.dispose = function() {\r\n // remove reference from soundArray\r\n var index = p5sound.soundArray.indexOf(this);\r\n p5sound.soundArray.splice(index, 1);\r\n\r\n this.stop();\r\n\r\n if (this.output) {\r\n this.output.disconnect();\r\n }\r\n if (this.amplitude) {\r\n this.amplitude.disconnect();\r\n }\r\n delete this.amplitude;\r\n delete this.output;\r\n };\r\n\r\n});\r\n","define([\"Tone/core/Tone\", \"Tone/signal/Signal\", \"Tone/signal/Expr\", \n\t\"Tone/signal/EqualPowerGain\", \"Tone/core/Gain\"], function(Tone){\n\n\t\"use strict\";\n\n\t/**\n\t * @class Tone.Crossfade provides equal power fading between two inputs. \n\t * More on crossfading technique [here](https://en.wikipedia.org/wiki/Fade_(audio_engineering)#Crossfading).\n\t *\n\t * @constructor\n\t * @extends {Tone}\n\t * @param {NormalRange} [initialFade=0.5]\n\t * @example\n\t * var crossFade = new Tone.CrossFade(0.5);\n\t * //connect effect A to crossfade from\n\t * //effect output 0 to crossfade input 0\n\t * effectA.connect(crossFade, 0, 0);\n\t * //connect effect B to crossfade from\n\t * //effect output 0 to crossfade input 1\n\t * effectB.connect(crossFade, 0, 1);\n\t * crossFade.fade.value = 0;\n\t * // ^ only effectA is output\n\t * crossFade.fade.value = 1;\n\t * // ^ only effectB is output\n\t * crossFade.fade.value = 0.5;\n\t * // ^ the two signals are mixed equally. \n\t */\t\t\n\tTone.CrossFade = function(initialFade){\n\n\t\tthis.createInsOuts(2, 1);\n\n\t\t/**\n\t\t * Alias for input[0]. \n\t\t * @type {Tone.Gain}\n\t\t */\n\t\tthis.a = this.input[0] = new Tone.Gain();\n\n\t\t/**\n\t\t * Alias for input[1]. \n\t\t * @type {Tone.Gain}\n\t\t */\n\t\tthis.b = this.input[1] = new Tone.Gain();\n\n\t\t/**\n\t\t * \tThe mix between the two inputs. A fade value of 0\n\t\t * \twill output 100% input[0] and \n\t\t * \ta value of 1 will output 100% input[1]. \n\t\t * @type {NormalRange}\n\t\t * @signal\n\t\t */\n\t\tthis.fade = new Tone.Signal(this.defaultArg(initialFade, 0.5), Tone.Type.NormalRange);\n\n\t\t/**\n\t\t * equal power gain cross fade\n\t\t * @private\n\t\t * @type {Tone.EqualPowerGain}\n\t\t */\n\t\tthis._equalPowerA = new Tone.EqualPowerGain();\n\n\t\t/**\n\t\t * equal power gain cross fade\n\t\t * @private\n\t\t * @type {Tone.EqualPowerGain}\n\t\t */\n\t\tthis._equalPowerB = new Tone.EqualPowerGain();\n\t\t\n\t\t/**\n\t\t * invert the incoming signal\n\t\t * @private\n\t\t * @type {Tone}\n\t\t */\n\t\tthis._invert = new Tone.Expr(\"1 - $0\");\n\n\t\t//connections\n\t\tthis.a.connect(this.output);\n\t\tthis.b.connect(this.output);\n\t\tthis.fade.chain(this._equalPowerB, this.b.gain);\n\t\tthis.fade.chain(this._invert, this._equalPowerA, this.a.gain);\n\t\tthis._readOnly(\"fade\");\n\t};\n\n\tTone.extend(Tone.CrossFade);\n\n\t/**\n\t * clean up\n\t * @returns {Tone.CrossFade} this\n\t */\n\tTone.CrossFade.prototype.dispose = function(){\n\t\tTone.prototype.dispose.call(this);\n\t\tthis._writable(\"fade\");\n\t\tthis._equalPowerA.dispose();\n\t\tthis._equalPowerA = null;\n\t\tthis._equalPowerB.dispose();\n\t\tthis._equalPowerB = null;\n\t\tthis.fade.dispose();\n\t\tthis.fade = null;\n\t\tthis._invert.dispose();\n\t\tthis._invert = null;\n\t\tthis.a.dispose();\n\t\tthis.a = null;\n\t\tthis.b.dispose();\n\t\tthis.b = null;\n\t\treturn this;\n\t};\n\n\treturn Tone.CrossFade;\n});\n","define([\"Tone/core/Tone\", \"Tone/signal/Add\", \"Tone/signal/Subtract\", \"Tone/signal/Multiply\", \n\t\"Tone/signal/GreaterThan\", \"Tone/signal/GreaterThanZero\", \"Tone/signal/Abs\", \"Tone/signal/Negate\", \n\t\"Tone/signal/Modulo\", \"Tone/signal/Pow\", \"Tone/signal/AudioToGain\"], \n\tfunction(Tone){\n\n\t\"use strict\";\n\n\t/**\n\t * @class Evaluate an expression at audio rate.
\n\t * Parsing code modified from https://code.google.com/p/tapdigit/\n\t * Copyright 2011 2012 Ariya Hidayat, New BSD License\n\t *\n\t * @extends {Tone.SignalBase}\n\t * @constructor\n\t * @param {string} expr the expression to generate\n\t * @example\n\t * //adds the signals from input[0] and input[1].\n\t * var expr = new Tone.Expr(\"$0 + $1\");\n\t */\n\tTone.Expr = function(){\n\n\t\tvar expr = this._replacements(Array.prototype.slice.call(arguments));\n\t\tvar inputCount = this._parseInputs(expr);\n\n\t\t/**\n\t\t * hold onto all of the nodes for disposal\n\t\t * @type {Array}\n\t\t * @private\n\t\t */\n\t\tthis._nodes = [];\n\n\t\t/**\n\t\t * The inputs. The length is determined by the expression. \n\t\t * @type {Array}\n\t\t */\n\t\tthis.input = new Array(inputCount);\n\n\t\t//create a gain for each input\n\t\tfor (var i = 0; i < inputCount; i++){\n\t\t\tthis.input[i] = this.context.createGain();\n\t\t}\n\n\t\t//parse the syntax tree\n\t\tvar tree = this._parseTree(expr);\n\t\t//evaluate the results\n\t\tvar result;\n\t\ttry {\n\t\t\tresult = this._eval(tree);\n\t\t} catch (e){\n\t\t\tthis._disposeNodes();\n\t\t\tthrow new Error(\"Tone.Expr: Could evaluate expression: \"+expr);\n\t\t}\n\n\t\t/**\n\t\t * The output node is the result of the expression\n\t\t * @type {Tone}\n\t\t */\n\t\tthis.output = result;\n\t};\n\n\tTone.extend(Tone.Expr, Tone.SignalBase);\n\n\t//some helpers to cut down the amount of code\n\tfunction applyBinary(Constructor, args, self){\n\t\tvar op = new Constructor();\n\t\tself._eval(args[0]).connect(op, 0, 0);\n\t\tself._eval(args[1]).connect(op, 0, 1);\n\t\treturn op;\n\t}\n\tfunction applyUnary(Constructor, args, self){\n\t\tvar op = new Constructor();\n\t\tself._eval(args[0]).connect(op, 0, 0);\n\t\treturn op;\n\t}\n\tfunction getNumber(arg){\n\t\treturn arg ? parseFloat(arg) : undefined;\n\t}\n\tfunction literalNumber(arg){\n\t\treturn arg && arg.args ? parseFloat(arg.args) : undefined;\n\t}\n\n\t/*\n\t * the Expressions that Tone.Expr can parse.\n\t *\n\t * each expression belongs to a group and contains a regexp \n\t * for selecting the operator as well as that operators method\n\t * \n\t * @type {Object}\n\t * @private\n\t */\n\tTone.Expr._Expressions = {\n\t\t//values\n\t\t\"value\" : {\n\t\t\t\"signal\" : {\n\t\t\t\tregexp : /^\\d+\\.\\d+|^\\d+/,\n\t\t\t\tmethod : function(arg){\n\t\t\t\t\tvar sig = new Tone.Signal(getNumber(arg));\n\t\t\t\t\treturn sig;\n\t\t\t\t}\n\t\t\t},\n\t\t\t\"input\" : {\n\t\t\t\tregexp : /^\\$\\d/,\n\t\t\t\tmethod : function(arg, self){\n\t\t\t\t\treturn self.input[getNumber(arg.substr(1))];\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\t\t//syntactic glue\n\t\t\"glue\" : {\n\t\t\t\"(\" : {\n\t\t\t\tregexp : /^\\(/,\n\t\t\t},\n\t\t\t\")\" : {\n\t\t\t\tregexp : /^\\)/,\n\t\t\t},\n\t\t\t\",\" : {\n\t\t\t\tregexp : /^,/,\n\t\t\t}\n\t\t},\n\t\t//functions\n\t\t\"func\" : {\n\t\t\t\"abs\" : {\n\t\t\t\tregexp : /^abs/,\n\t\t\t\tmethod : applyUnary.bind(this, Tone.Abs)\n\t\t\t},\n\t\t\t\"mod\" : {\n\t\t\t\tregexp : /^mod/,\n\t\t\t\tmethod : function(args, self){\n\t\t\t\t\tvar modulus = literalNumber(args[1]);\n\t\t\t\t\tvar op = new Tone.Modulo(modulus);\n\t\t\t\t\tself._eval(args[0]).connect(op);\n\t\t\t\t\treturn op;\n\t\t\t\t}\n\t\t\t},\n\t\t\t\"pow\" : {\n\t\t\t\tregexp : /^pow/,\n\t\t\t\tmethod : function(args, self){\n\t\t\t\t\tvar exp = literalNumber(args[1]);\n\t\t\t\t\tvar op = new Tone.Pow(exp);\n\t\t\t\t\tself._eval(args[0]).connect(op);\n\t\t\t\t\treturn op;\n\t\t\t\t}\n\t\t\t},\n\t\t\t\"a2g\" : {\n\t\t\t\tregexp : /^a2g/,\n\t\t\t\tmethod : function(args, self){\n\t\t\t\t\tvar op = new Tone.AudioToGain();\n\t\t\t\t\tself._eval(args[0]).connect(op);\n\t\t\t\t\treturn op;\n\t\t\t\t}\n\t\t\t},\n\t\t},\n\t\t//binary expressions\n\t\t\"binary\" : {\n\t\t\t\"+\" : {\n\t\t\t\tregexp : /^\\+/,\n\t\t\t\tprecedence : 1,\n\t\t\t\tmethod : applyBinary.bind(this, Tone.Add)\n\t\t\t},\n\t\t\t\"-\" : {\n\t\t\t\tregexp : /^\\-/,\n\t\t\t\tprecedence : 1,\n\t\t\t\tmethod : function(args, self){\n\t\t\t\t\t//both unary and binary op\n\t\t\t\t\tif (args.length === 1){\n\t\t\t\t\t\treturn applyUnary(Tone.Negate, args, self);\n\t\t\t\t\t} else {\n\t\t\t\t\t\treturn applyBinary(Tone.Subtract, args, self);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t},\n\t\t\t\"*\" : {\n\t\t\t\tregexp : /^\\*/,\n\t\t\t\tprecedence : 0,\n\t\t\t\tmethod : applyBinary.bind(this, Tone.Multiply)\n\t\t\t}\n\t\t},\n\t\t//unary expressions\n\t\t\"unary\" : {\n\t\t\t\"-\" : {\n\t\t\t\tregexp : /^\\-/,\n\t\t\t\tmethod : applyUnary.bind(this, Tone.Negate)\n\t\t\t},\n\t\t\t\"!\" : {\n\t\t\t\tregexp : /^\\!/,\n\t\t\t\tmethod : applyUnary.bind(this, Tone.NOT)\n\t\t\t},\n\t\t},\n\t};\n\t\t\n\t/**\n\t * @param {string} expr the expression string\n\t * @return {number} the input count\n\t * @private\n\t */\n\tTone.Expr.prototype._parseInputs = function(expr){\n\t\tvar inputArray = expr.match(/\\$\\d/g);\n\t\tvar inputMax = 0;\n\t\tif (inputArray !== null){\n\t\t\tfor (var i = 0; i < inputArray.length; i++){\n\t\t\t\tvar inputNum = parseInt(inputArray[i].substr(1)) + 1;\n\t\t\t\tinputMax = Math.max(inputMax, inputNum);\n\t\t\t}\n\t\t}\n\t\treturn inputMax;\n\t};\n\n\t/**\n\t * @param {Array} args \tan array of arguments\n\t * @return {string} the results of the replacements being replaced\n\t * @private\n\t */\n\tTone.Expr.prototype._replacements = function(args){\n\t\tvar expr = args.shift();\n\t\tfor (var i = 0; i < args.length; i++){\n\t\t\texpr = expr.replace(/\\%/i, args[i]);\n\t\t}\n\t\treturn expr;\n\t};\n\n\t/**\n\t * tokenize the expression based on the Expressions object\n\t * @param {string} expr \n\t * @return {Object} returns two methods on the tokenized list, next and peek\n\t * @private\n\t */\n\tTone.Expr.prototype._tokenize = function(expr){\n\t\tvar position = -1;\n\t\tvar tokens = [];\n\n\t\twhile(expr.length > 0){\n\t\t\texpr = expr.trim();\n\t\t\tvar token = getNextToken(expr);\n\t\t\ttokens.push(token);\n\t\t\texpr = expr.substr(token.value.length);\n\t\t}\n\n\t\tfunction getNextToken(expr){\n\t\t\tfor (var type in Tone.Expr._Expressions){\n\t\t\t\tvar group = Tone.Expr._Expressions[type];\n\t\t\t\tfor (var opName in group){\n\t\t\t\t\tvar op = group[opName];\n\t\t\t\t\tvar reg = op.regexp;\n\t\t\t\t\tvar match = expr.match(reg);\n\t\t\t\t\tif (match !== null){\n\t\t\t\t\t\treturn {\n\t\t\t\t\t\t\ttype : type,\n\t\t\t\t\t\t\tvalue : match[0],\n\t\t\t\t\t\t\tmethod : op.method\n\t\t\t\t\t\t};\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\tthrow new SyntaxError(\"Tone.Expr: Unexpected token \"+expr);\n\t\t}\n\n\t\treturn {\n\t\t\tnext : function(){\n\t\t\t\treturn tokens[++position];\n\t\t\t},\n\t\t\tpeek : function(){\n\t\t\t\treturn tokens[position + 1];\n\t\t\t}\n\t\t};\n\t};\n\n\t/**\n\t * recursively parse the string expression into a syntax tree\n\t * \n\t * @param {string} expr \n\t * @return {Object}\n\t * @private\n\t */\n\tTone.Expr.prototype._parseTree = function(expr){\n\t\tvar lexer = this._tokenize(expr);\n\t\tvar isUndef = this.isUndef.bind(this);\n\n\t\tfunction matchSyntax(token, syn) {\n\t\t\treturn !isUndef(token) && \n\t\t\t\ttoken.type === \"glue\" &&\n\t\t\t\ttoken.value === syn;\n\t\t}\n\n\t\tfunction matchGroup(token, groupName, prec) {\n\t\t\tvar ret = false;\n\t\t\tvar group = Tone.Expr._Expressions[groupName];\n\t\t\tif (!isUndef(token)){\n\t\t\t\tfor (var opName in group){\n\t\t\t\t\tvar op = group[opName];\n\t\t\t\t\tif (op.regexp.test(token.value)){\n\t\t\t\t\t\tif (!isUndef(prec)){\n\t\t\t\t\t\t\tif(op.precedence === prec){\t\n\t\t\t\t\t\t\t\treturn true;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\treturn true;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn ret;\n\t\t}\n\n\t\tfunction parseExpression(precedence) {\n\t\t\tif (isUndef(precedence)){\n\t\t\t\tprecedence = 5;\n\t\t\t}\n\t\t\tvar expr;\n\t\t\tif (precedence < 0){\n\t\t\t\texpr = parseUnary();\n\t\t\t} else {\n\t\t\t\texpr = parseExpression(precedence-1);\n\t\t\t}\n\t\t\tvar token = lexer.peek();\n\t\t\twhile (matchGroup(token, \"binary\", precedence)) {\n\t\t\t\ttoken = lexer.next();\n\t\t\t\texpr = {\n\t\t\t\t\toperator: token.value,\n\t\t\t\t\tmethod : token.method,\n\t\t\t\t\targs : [\n\t\t\t\t\t\texpr,\n\t\t\t\t\t\tparseExpression(precedence-1)\n\t\t\t\t\t]\n\t\t\t\t};\n\t\t\t\ttoken = lexer.peek();\n\t\t\t}\n\t\t\treturn expr;\n\t\t}\n\n\t\tfunction parseUnary() {\n\t\t\tvar token, expr;\n\t\t\ttoken = lexer.peek();\n\t\t\tif (matchGroup(token, \"unary\")) {\n\t\t\t\ttoken = lexer.next();\n\t\t\t\texpr = parseUnary();\n\t\t\t\treturn {\n\t\t\t\t\toperator: token.value,\n\t\t\t\t\tmethod : token.method,\n\t\t\t\t\targs : [expr]\n\t\t\t\t};\n\t\t\t}\n\t\t\treturn parsePrimary();\n\t\t}\n\n\t\tfunction parsePrimary() {\n\t\t\tvar token, expr;\n\t\t\ttoken = lexer.peek();\n\t\t\tif (isUndef(token)) {\n\t\t\t\tthrow new SyntaxError(\"Tone.Expr: Unexpected termination of expression\");\n\t\t\t}\n\t\t\tif (token.type === \"func\") {\n\t\t\t\ttoken = lexer.next();\n\t\t\t\treturn parseFunctionCall(token);\n\t\t\t}\n\t\t\tif (token.type === \"value\") {\n\t\t\t\ttoken = lexer.next();\n\t\t\t\treturn {\n\t\t\t\t\tmethod : token.method,\n\t\t\t\t\targs : token.value\n\t\t\t\t};\n\t\t\t}\n\t\t\tif (matchSyntax(token, \"(\")) {\n\t\t\t\tlexer.next();\n\t\t\t\texpr = parseExpression();\n\t\t\t\ttoken = lexer.next();\n\t\t\t\tif (!matchSyntax(token, \")\")) {\n\t\t\t\t\tthrow new SyntaxError(\"Expected )\");\n\t\t\t\t}\n\t\t\t\treturn expr;\n\t\t\t}\n\t\t\tthrow new SyntaxError(\"Tone.Expr: Parse error, cannot process token \" + token.value);\n\t\t}\n\n\t\tfunction parseFunctionCall(func) {\n\t\t\tvar token, args = [];\n\t\t\ttoken = lexer.next();\n\t\t\tif (!matchSyntax(token, \"(\")) {\n\t\t\t\tthrow new SyntaxError(\"Tone.Expr: Expected ( in a function call \\\"\" + func.value + \"\\\"\");\n\t\t\t}\n\t\t\ttoken = lexer.peek();\n\t\t\tif (!matchSyntax(token, \")\")) {\n\t\t\t\targs = parseArgumentList();\n\t\t\t}\n\t\t\ttoken = lexer.next();\n\t\t\tif (!matchSyntax(token, \")\")) {\n\t\t\t\tthrow new SyntaxError(\"Tone.Expr: Expected ) in a function call \\\"\" + func.value + \"\\\"\");\n\t\t\t}\n\t\t\treturn {\n\t\t\t\tmethod : func.method,\n\t\t\t\targs : args,\n\t\t\t\tname : name\n\t\t\t};\n\t\t}\n\n\t\tfunction parseArgumentList() {\n\t\t\tvar token, expr, args = [];\n\t\t\twhile (true) {\n\t\t\t\texpr = parseExpression();\n\t\t\t\tif (isUndef(expr)) {\n\t\t\t\t\t// TODO maybe throw exception?\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\targs.push(expr);\n\t\t\t\ttoken = lexer.peek();\n\t\t\t\tif (!matchSyntax(token, \",\")) {\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tlexer.next();\n\t\t\t}\n\t\t\treturn args;\n\t\t}\n\n\t\treturn parseExpression();\n\t};\n\n\t/**\n\t * recursively evaluate the expression tree\n\t * @param {Object} tree \n\t * @return {AudioNode} the resulting audio node from the expression\n\t * @private\n\t */\n\tTone.Expr.prototype._eval = function(tree){\n\t\tif (!this.isUndef(tree)){\n\t\t\tvar node = tree.method(tree.args, this);\n\t\t\tthis._nodes.push(node);\n\t\t\treturn node;\n\t\t} \n\t};\n\n\t/**\n\t * dispose all the nodes\n\t * @private\n\t */\n\tTone.Expr.prototype._disposeNodes = function(){\n\t\tfor (var i = 0; i < this._nodes.length; i++){\n\t\t\tvar node = this._nodes[i];\n\t\t\tif (this.isFunction(node.dispose)) {\n\t\t\t\tnode.dispose();\n\t\t\t} else if (this.isFunction(node.disconnect)) {\n\t\t\t\tnode.disconnect();\n\t\t\t}\n\t\t\tnode = null;\n\t\t\tthis._nodes[i] = null;\n\t\t}\n\t\tthis._nodes = null;\n\t};\n\n\t/**\n\t * clean up\n\t */\n\tTone.Expr.prototype.dispose = function(){\n\t\tTone.prototype.dispose.call(this);\n\t\tthis._disposeNodes();\n\t};\n\n\treturn Tone.Expr;\n});","define([\"Tone/core/Tone\", \"Tone/signal/GreaterThanZero\", \"Tone/signal/Subtract\", \"Tone/signal/Signal\"], \n\tfunction(Tone){\n\n\t\"use strict\";\n\n\t/**\n\t * @class Output 1 if the signal is greater than the value, otherwise outputs 0.\n\t * can compare two signals or a signal and a number. \n\t * \n\t * @constructor\n\t * @extends {Tone.Signal}\n\t * @param {number} [value=0] the value to compare to the incoming signal\n\t * @example\n\t * var gt = new Tone.GreaterThan(2);\n\t * var sig = new Tone.Signal(4).connect(gt);\n\t * //output of gt is equal 1. \n\t */\n\tTone.GreaterThan = function(value){\n\n\t\tthis.createInsOuts(2, 0);\n\t\t\n\t\t/**\n\t\t * subtract the amount from the incoming signal\n\t\t * @type {Tone.Subtract}\n\t\t * @private\n\t\t */\n\t\tthis._param = this.input[0] = new Tone.Subtract(value);\n\t\tthis.input[1] = this._param.input[1];\n\n\t\t/**\n\t\t * compare that amount to zero\n\t\t * @type {Tone.GreaterThanZero}\n\t\t * @private\n\t\t */\n\t\tthis._gtz = this.output = new Tone.GreaterThanZero();\n\n\t\t//connect\n\t\tthis._param.connect(this._gtz);\n\t};\n\n\tTone.extend(Tone.GreaterThan, Tone.Signal);\n\n\t/**\n\t * dispose method\n\t * @returns {Tone.GreaterThan} this\n\t */\n\tTone.GreaterThan.prototype.dispose = function(){\n\t\tTone.prototype.dispose.call(this);\n\t\tthis._param.dispose();\n\t\tthis._param = null;\n\t\tthis._gtz.dispose();\n\t\tthis._gtz = null;\n\t\treturn this;\n\t};\n\n\treturn Tone.GreaterThan;\n});","define([\"Tone/core/Tone\", \"Tone/signal/WaveShaper\", \"Tone/signal/SignalBase\"], \nfunction(Tone){\n\n\t\"use strict\";\n\n\t/**\n\t * @class Return the absolute value of an incoming signal. \n\t * \n\t * @constructor\n\t * @extends {Tone.SignalBase}\n\t * @example\n\t * var signal = new Tone.Signal(-1);\n\t * var abs = new Tone.Abs();\n\t * signal.connect(abs);\n\t * //the output of abs is 1. \n\t */\n\tTone.Abs = function(){\n\t\t/**\n\t\t * @type {Tone.LessThan}\n\t\t * @private\n\t\t */\n\t\tthis._abs = this.input = this.output = new Tone.WaveShaper(function(val){\n\t\t\tif (val === 0){\n\t\t\t\treturn 0;\n\t\t\t} else {\n\t\t\t\treturn Math.abs(val);\n\t\t\t}\n\t\t}, 127);\n\t};\n\n\tTone.extend(Tone.Abs, Tone.SignalBase);\n\n\t/**\n\t * dispose method\n\t * @returns {Tone.Abs} this\n\t */\n\tTone.Abs.prototype.dispose = function(){\n\t\tTone.prototype.dispose.call(this);\n\t\tthis._abs.dispose();\n\t\tthis._abs = null;\n\t\treturn this;\n\t}; \n\n\treturn Tone.Abs;\n});","define([\"Tone/core/Tone\", \"Tone/signal/WaveShaper\", \"Tone/signal/Multiply\", \"Tone/signal/Subtract\"], \nfunction(Tone){\n\n\t\"use strict\";\n\n\t/**\n\t * @class Signal-rate modulo operator. Only works in AudioRange [-1, 1] and for modulus\n\t * values in the NormalRange. \n\t *\n\t * @constructor\n\t * @extends {Tone.SignalBase}\n\t * @param {NormalRange} modulus The modulus to apply.\n\t * @example\n\t * var mod = new Tone.Modulo(0.2)\n\t * var sig = new Tone.Signal(0.5).connect(mod);\n\t * //mod outputs 0.1\n\t */\n\tTone.Modulo = function(modulus){\n\n\t\tthis.createInsOuts(1, 0);\n\n\t\t/**\n\t\t * A waveshaper gets the integer multiple of \n\t\t * the input signal and the modulus.\n\t\t * @private\n\t\t * @type {Tone.WaveShaper}\n\t\t */\n\t\tthis._shaper = new Tone.WaveShaper(Math.pow(2, 16));\n\n\t\t/**\n\t\t * the integer multiple is multiplied by the modulus\n\t\t * @type {Tone.Multiply}\n\t\t * @private\n\t\t */\n\t\tthis._multiply = new Tone.Multiply();\n\n\t\t/**\n\t\t * and subtracted from the input signal\n\t\t * @type {Tone.Subtract}\n\t\t * @private\n\t\t */\n\t\tthis._subtract = this.output = new Tone.Subtract();\n\n\t\t/**\n\t\t * the modulus signal\n\t\t * @type {Tone.Signal}\n\t\t * @private\n\t\t */\n\t\tthis._modSignal = new Tone.Signal(modulus);\n\n\t\t//connections\n\t\tthis.input.fan(this._shaper, this._subtract);\n\t\tthis._modSignal.connect(this._multiply, 0, 0);\n\t\tthis._shaper.connect(this._multiply, 0, 1);\n\t\tthis._multiply.connect(this._subtract, 0, 1);\n\t\tthis._setWaveShaper(modulus);\n\t};\n\n\tTone.extend(Tone.Modulo, Tone.SignalBase);\n\n\t/**\n\t * @param {number} mod the modulus to apply\n\t * @private\n\t */\n\tTone.Modulo.prototype._setWaveShaper = function(mod){\n\t\tthis._shaper.setMap(function(val){\n\t\t\tvar multiple = Math.floor((val + 0.0001) / mod);\n\t\t\treturn multiple;\n\t\t});\n\t};\n\n\t/**\n\t * The modulus value.\n\t * @memberOf Tone.Modulo#\n\t * @type {NormalRange}\n\t * @name value\n\t */\n\tObject.defineProperty(Tone.Modulo.prototype, \"value\", {\n\t\tget : function(){\n\t\t\treturn this._modSignal.value;\n\t\t},\n\t\tset : function(mod){\n\t\t\tthis._modSignal.value = mod;\n\t\t\tthis._setWaveShaper(mod);\n\t\t}\n\t});\n\n\t/**\n\t * clean up\n\t * @returns {Tone.Modulo} this\n\t */\n\tTone.Modulo.prototype.dispose = function(){\n\t\tTone.prototype.dispose.call(this);\n\t\tthis._shaper.dispose();\n\t\tthis._shaper = null;\n\t\tthis._multiply.dispose();\n\t\tthis._multiply = null;\n\t\tthis._subtract.dispose();\n\t\tthis._subtract = null;\n\t\tthis._modSignal.dispose();\n\t\tthis._modSignal = null;\n\t\treturn this;\n\t};\n\n\treturn Tone.Modulo;\n});","define([\"Tone/core/Tone\", \"Tone/signal/WaveShaper\"], function(Tone){\n\n\t\"use strict\";\n\n\t/**\n\t * @class Pow applies an exponent to the incoming signal. The incoming signal\n\t * must be AudioRange.\n\t *\n\t * @extends {Tone.SignalBase}\n\t * @constructor\n\t * @param {Positive} exp The exponent to apply to the incoming signal, must be at least 2. \n\t * @example\n\t * var pow = new Tone.Pow(2);\n\t * var sig = new Tone.Signal(0.5).connect(pow);\n\t * //output of pow is 0.25. \n\t */\n\tTone.Pow = function(exp){\n\n\t\t/**\n\t\t * the exponent\n\t\t * @private\n\t\t * @type {number}\n\t\t */\n\t\tthis._exp = this.defaultArg(exp, 1);\n\n\t\t/**\n\t\t * @type {WaveShaperNode}\n\t\t * @private\n\t\t */\n\t\tthis._expScaler = this.input = this.output = new Tone.WaveShaper(this._expFunc(this._exp), 8192);\n\t};\n\n\tTone.extend(Tone.Pow, Tone.SignalBase);\n\n\t/**\n\t * The value of the exponent.\n\t * @memberOf Tone.Pow#\n\t * @type {number}\n\t * @name value\n\t */\n\tObject.defineProperty(Tone.Pow.prototype, \"value\", {\n\t\tget : function(){\n\t\t\treturn this._exp;\n\t\t},\n\t\tset : function(exp){\n\t\t\tthis._exp = exp;\n\t\t\tthis._expScaler.setMap(this._expFunc(this._exp));\n\t\t}\n\t});\n\n\n\t/**\n\t * the function which maps the waveshaper\n\t * @param {number} exp\n\t * @return {function}\n\t * @private\n\t */\n\tTone.Pow.prototype._expFunc = function(exp){\n\t\treturn function(val){\n\t\t\treturn Math.pow(Math.abs(val), exp);\n\t\t};\n\t};\n\n\t/**\n\t * Clean up.\n\t * @returns {Tone.Pow} this\n\t */\n\tTone.Pow.prototype.dispose = function(){\n\t\tTone.prototype.dispose.call(this);\n\t\tthis._expScaler.dispose();\n\t\tthis._expScaler = null;\n\t\treturn this;\n\t};\n\n\treturn Tone.Pow;\n});","define([\"Tone/core/Tone\", \"Tone/signal/WaveShaper\", \"Tone/signal/Signal\"], function(Tone){\n\n\t\"use strict\";\n\n\t/**\n\t * @class AudioToGain converts an input in AudioRange [-1,1] to NormalRange [0,1]. \n\t * See Tone.GainToAudio.\n\t *\n\t * @extends {Tone.SignalBase}\n\t * @constructor\n\t * @example\n\t * var a2g = new Tone.AudioToGain();\n\t */\n\tTone.AudioToGain = function(){\n\n\t\t/**\n\t\t * @type {WaveShaperNode}\n\t\t * @private\n\t\t */\n\t\tthis._norm = this.input = this.output = new Tone.WaveShaper(function(x){\n\t\t\treturn (x + 1) / 2;\n\t\t});\n\t};\n\n\tTone.extend(Tone.AudioToGain, Tone.SignalBase);\n\n\t/**\n\t * clean up\n\t * @returns {Tone.AudioToGain} this\n\t */\n\tTone.AudioToGain.prototype.dispose = function(){\n\t\tTone.prototype.dispose.call(this);\n\t\tthis._norm.dispose();\n\t\tthis._norm = null;\n\t\treturn this;\n\t};\n\n\treturn Tone.AudioToGain;\n});","define([\"Tone/core/Tone\", \"Tone/signal/WaveShaper\"], function(Tone){\n\n\t\"use strict\";\n\n\t/**\n\t * @class Convert an incoming signal between 0, 1 to an equal power gain scale.\n\t *\n\t * @extends {Tone.SignalBase}\n\t * @constructor\n\t * @example\n\t * var eqPowGain = new Tone.EqualPowerGain();\n\t */\n\tTone.EqualPowerGain = function(){\n\n\t\t/**\n\t\t * @type {Tone.WaveShaper}\n\t\t * @private\n\t\t */\n\t\tthis._eqPower = this.input = this.output = new Tone.WaveShaper(function(val){\n\t\t\tif (Math.abs(val) < 0.001){\n\t\t\t\t//should output 0 when input is 0\n\t\t\t\treturn 0;\n\t\t\t} else {\n\t\t\t\treturn this.equalPowerScale(val);\n\t\t\t}\n\t\t}.bind(this), 4096);\n\t};\n\n\tTone.extend(Tone.EqualPowerGain, Tone.SignalBase);\n\n\t/**\n\t * clean up\n\t * @returns {Tone.EqualPowerGain} this\n\t */\n\tTone.EqualPowerGain.prototype.dispose = function(){\n\t\tTone.prototype.dispose.call(this);\n\t\tthis._eqPower.dispose();\n\t\tthis._eqPower = null;\n\t\treturn this;\n\t};\n\n\treturn Tone.EqualPowerGain;\n});","'use strict';\r\n\r\ndefine(function (require) {\r\n\r\n var Effect = require('effect');\r\n var EQFilter = require('eqFilter');\r\n\r\n /**\r\n * p5.EQ is an audio effect that performs the function of a multiband\r\n * audio equalizer. Equalization is used to adjust the balance of\r\n * frequency compoenents of an audio signal. This process is commonly used\r\n * in sound production and recording to change the waveform before it reaches\r\n * a sound output device. EQ can also be used as an audio effect to create\r\n * interesting distortions by filtering out parts of the spectrum. p5.EQ is\r\n * built using a chain of Web Audio Biquad Filter Nodes and can be\r\n * instantiated with 3 or 8 bands. Bands can be added or removed from\r\n * the EQ by directly modifying p5.EQ.bands (the array that stores filters).\r\n *\r\n * This class extends p5.Effect.\r\n * Methods amp(), chain(),\r\n * drywet(), connect(), and\r\n * disconnect() are available.\r\n *\r\n * @class p5.EQ\r\n * @constructor\r\n * @extends p5.Effect\r\n * @param {Number} [_eqsize] Constructor will accept 3 or 8, defaults to 3\r\n * @return {Object} p5.EQ object\r\n *\r\n * @example\r\n *
\r\n * var eq;\r\n * var band_names;\r\n * var band_index;\r\n *\r\n * var soundFile, play;\r\n *\r\n * function preload() {\r\n * soundFormats('mp3', 'ogg');\r\n * soundFile = loadSound('assets/beat');\r\n * }\r\n *\r\n * function setup() {\r\n * eq = new p5.EQ(3);\r\n * soundFile.disconnect();\r\n * eq.process(soundFile);\r\n *\r\n * band_names = ['lows','mids','highs'];\r\n * band_index = 0;\r\n * play = false;\r\n * textAlign(CENTER);\r\n * }\r\n *\r\n * function draw() {\r\n * background(30);\r\n * noStroke();\r\n * fill(255);\r\n * text('click to kill',50,25);\r\n *\r\n * fill(255, 40, 255);\r\n * textSize(26);\r\n * text(band_names[band_index],50,55);\r\n *\r\n * fill(255);\r\n * textSize(9);\r\n * text('space = play/pause',50,80);\r\n * }\r\n *\r\n * //If mouse is over canvas, cycle to the next band and kill the frequency\r\n * function mouseClicked() {\r\n * for (var i = 0; i < eq.bands.length; i++) {\r\n * eq.bands[i].gain(0);\r\n * }\r\n * eq.bands[band_index].gain(-40);\r\n * if (mouseX > 0 && mouseX < width && mouseY < height && mouseY > 0) {\r\n * band_index === 2 ? band_index = 0 : band_index++;\r\n * }\r\n * }\r\n *\r\n * //use space bar to trigger play / pause\r\n * function keyPressed() {\r\n * if (key===' ') {\r\n * play = !play\r\n * play ? soundFile.loop() : soundFile.pause();\r\n * }\r\n * }\r\n *
\r\n */\r\n p5.EQ = function(_eqsize) {\r\n Effect.call(this);\r\n\r\n //p5.EQ can be of size (3) or (8), defaults to 3\r\n _eqsize = _eqsize === 3 || _eqsize === 8 ? _eqsize : 3;\r\n\r\n var factor;\r\n _eqsize === 3 ? factor = Math.pow(2,3) : factor = 2;\r\n\r\n /**\r\n * The p5.EQ is built with abstracted p5.Filter objects.\r\n * To modify any bands, use methods of the \r\n * p5.Filter API, especially `gain` and `freq`.\r\n * Bands are stored in an array, with indices 0 - 3, or 0 - 7\r\n * @property {Array} bands\r\n *\r\n */\r\n this.bands = [];\r\n\r\n\r\n var freq, res;\r\n for (var i = 0; i < _eqsize; i++) {\r\n if (i === _eqsize - 1) {\r\n freq = 21000;\r\n res = .01;\r\n } else if (i === 0) {\r\n freq = 100;\r\n res = .1;\r\n }\r\n else if (i===1) {\r\n freq = _eqsize === 3 ? 360 * factor : 360;\r\n res = 1;\r\n }else {\r\n freq = this.bands[i-1].freq() * factor;\r\n res = 1;\r\n }\r\n this.bands[i] = this._newBand(freq, res);\r\n\r\n if (i>0) {\r\n this.bands[i-1].connect(this.bands[i].biquad);\r\n } else {\r\n this.input.connect(this.bands[i].biquad);\r\n }\r\n }\r\n this.bands[_eqsize-1].connect(this.output);\r\n };\r\n p5.EQ.prototype = Object.create(Effect.prototype);\r\n\r\n /**\r\n * Process an input by connecting it to the EQ\r\n * @method process\r\n * @param {Object} src Audio source\r\n */\r\n p5.EQ.prototype.process = function (src) {\r\n src.connect(this.input);\r\n };\r\n\r\n // /**\r\n // * Set the frequency and gain of each band in the EQ. This method should be\r\n // * called with 3 or 8 frequency and gain pairs, depending on the size of the EQ.\r\n // * ex. eq.set(freq0, gain0, freq1, gain1, freq2, gain2);\r\n // *\r\n // * @method set\r\n // * @for p5.EQ\r\n // * @param {Number} [freq0] Frequency value for band with index 0\r\n // * @param {Number} [gain0] Gain value for band with index 0\r\n // * @param {Number} [freq1] Frequency value for band with index 1\r\n // * @param {Number} [gain1] Gain value for band with index 1\r\n // * @param {Number} [freq2] Frequency value for band with index 2\r\n // * @param {Number} [gain2] Gain value for band with index 2\r\n // * @param {Number} [freq3] Frequency value for band with index 3\r\n // * @param {Number} [gain3] Gain value for band with index 3\r\n // * @param {Number} [freq4] Frequency value for band with index 4\r\n // * @param {Number} [gain4] Gain value for band with index 4\r\n // * @param {Number} [freq5] Frequency value for band with index 5\r\n // * @param {Number} [gain5] Gain value for band with index 5\r\n // * @param {Number} [freq6] Frequency value for band with index 6\r\n // * @param {Number} [gain6] Gain value for band with index 6\r\n // * @param {Number} [freq7] Frequency value for band with index 7\r\n // * @param {Number} [gain7] Gain value for band with index 7\r\n // */\r\n p5.EQ.prototype.set = function() {\r\n if (arguments.length === this.bands.length * 2) {\r\n for (var i = 0; i < arguments.length; i+=2) {\r\n this.bands[i/2].freq(arguments[i]);\r\n this.bands[i/2].gain(arguments[i+1]);\r\n }\r\n }\r\n else {\r\n console.error('Argument mismatch. .set() should be called with ' + this.bands.length*2 +\r\n ' arguments. (one frequency and gain value pair for each band of the eq)');\r\n }\r\n };\r\n\r\n /**\r\n * Add a new band. Creates a p5.Filter and strips away everything but\r\n * the raw biquad filter. This method returns an abstracted p5.Filter,\r\n * which can be added to p5.EQ.bands, in order to create new EQ bands.\r\n * @private\r\n * @for p5.EQ\r\n * @method _newBand\r\n * @param {Number} freq\r\n * @param {Number} res\r\n * @return {Object} Abstracted Filter\r\n */\r\n p5.EQ.prototype._newBand = function(freq, res) {\r\n return new EQFilter(freq, res);\r\n };\r\n\r\n p5.EQ.prototype.dispose = function () {\r\n Effect.prototype.dispose.apply(this);\r\n\r\n if (this.bands) {\r\n while (this.bands.length > 0) {\r\n delete this.bands.pop().dispose();\r\n }\r\n delete this.bands;\r\n }\r\n };\r\n\r\n return p5.EQ;\r\n});\r\n","'use strict';\r\n\r\ndefine(function (require) {\r\n var Filter = require('filter');\r\n var p5sound = require('master');\r\n\r\n /**\r\n * EQFilter extends p5.Filter with constraints\r\n * necessary for the p5.EQ\r\n *\r\n * @private\r\n */\r\n var EQFilter = function(freq, res) {\r\n Filter.call(this, 'peaking');\r\n this.disconnect();\r\n this.set(freq, res);\r\n this.biquad.gain.value = 0;\r\n delete this.input;\r\n delete this.output;\r\n delete this._drywet;\r\n delete this.wet;\r\n\r\n };\r\n EQFilter.prototype = Object.create(Filter.prototype);\r\n\r\n EQFilter.prototype.amp = function() {\r\n console.warn('`amp()` is not available for p5.EQ bands. Use `.gain()`');\r\n };\r\n EQFilter.prototype.drywet = function() {\r\n console.warn('`drywet()` is not available for p5.EQ bands.');\r\n };\r\n EQFilter.prototype.connect = function(unit) {\r\n var u = unit || p5.soundOut.input;\r\n if (this.biquad) {\r\n this.biquad.connect(u.input ? u.input : u);\r\n } else {\r\n this.output.connect(u.input ? u.input : u);\r\n }\r\n };\r\n\r\n EQFilter.prototype.disconnect = function() {\r\n if (this.biquad) {\r\n this.biquad.disconnect();\r\n }\r\n };\r\n EQFilter.prototype.dispose = function() {\r\n // remove reference form soundArray\r\n var index = p5sound.soundArray.indexOf(this);\r\n p5sound.soundArray.splice(index, 1);\r\n this.disconnect();\r\n delete this.biquad;\r\n };\r\n\r\n return EQFilter;\r\n});\r\n","'use strict'\r\n\r\ndefine(function (require) {\r\n var p5sound = require('master');\r\n var Effect = require('effect');\r\n\r\n /**\r\n * Panner3D is based on the \r\n * Web Audio Spatial Panner Node.\r\n * This panner is a spatial processing node that allows audio to be positioned\r\n * and oriented in 3D space.\r\n *\r\n * The position is relative to an \r\n * Audio Context Listener, which can be accessed\r\n * by p5.soundOut.audiocontext.listener\r\n *\r\n *\r\n * @class p5.Panner3D\r\n * @constructor\r\n */\r\n\tp5.Panner3D = function() {\r\n Effect.call(this);\r\n\r\n /**\r\n * \r\n * Web Audio Spatial Panner Node\r\n *\r\n * Properties include\r\n * - panningModel: \"equal power\" or \"HRTF\"\r\n * - distanceModel: \"linear\", \"inverse\", or \"exponential\"\r\n *\r\n * @property {AudioNode} panner\r\n *\r\n */\r\n this.panner = this.ac.createPanner();\r\n this.panner.panningModel = 'HRTF';\r\n this.panner.distanceModel = 'linear';\r\n this.panner.connect(this.output);\r\n this.input.connect(this.panner);\r\n\t};\r\n\r\n p5.Panner3D.prototype = Object.create(Effect.prototype);\r\n\r\n\r\n /**\r\n * Connect an audio sorce\r\n *\r\n * @method process\r\n * @for p5.Panner3D\r\n * @param {Object} src Input source\r\n */\r\n p5.Panner3D.prototype.process = function(src) {\r\n src.connect(this.input);\r\n }\r\n /**\r\n * Set the X,Y,Z position of the Panner\r\n * @method set\r\n * @for p5.Panner3D\r\n * @param {Number} xVal\r\n * @param {Number} yVal\r\n * @param {Number} zVal\r\n * @param {Number} time\r\n * @return {Array} Updated x, y, z values as an array\r\n */\r\n p5.Panner3D.prototype.set = function(xVal, yVal, zVal, time) {\r\n this.positionX(xVal,time);\r\n this.positionY(yVal,time);\r\n this.positionZ(zVal,time);\r\n return [this.panner.positionX.value,\r\n this.panner.positionY.value,\r\n this.panner.positionZ.value];\r\n };\r\n\r\n /**\r\n * Getter and setter methods for position coordinates\r\n * @method positionX\r\n * @for p5.Panner3D\r\n * @return {Number} updated coordinate value\r\n */\r\n /**\r\n * Getter and setter methods for position coordinates\r\n * @method positionY\r\n * @for p5.Panner3D\r\n * @return {Number} updated coordinate value\r\n */\r\n /**\r\n * Getter and setter methods for position coordinates\r\n * @method positionZ\r\n * @for p5.Panner3D\r\n * @return {Number} updated coordinate value\r\n */\r\n p5.Panner3D.prototype.positionX = function(xVal, time) {\r\n var t = time || 0;\r\n if (typeof xVal === 'number') {\r\n this.panner.positionX.value = xVal;\r\n this.panner.positionX.cancelScheduledValues(this.ac.currentTime + 0.01 + t);\r\n this.panner.positionX.linearRampToValueAtTime(xVal, this.ac.currentTime + 0.02 + t);\r\n } else if (xVal) {\r\n xVal.connect(this.panner.positionX);\r\n }\r\n return this.panner.positionX.value;\r\n };\r\n p5.Panner3D.prototype.positionY = function(yVal, time) {\r\n var t = time || 0;\r\n if (typeof yVal === 'number') {\r\n this.panner.positionY.value = yVal;\r\n this.panner.positionY.cancelScheduledValues(this.ac.currentTime + 0.01 + t);\r\n this.panner.positionY.linearRampToValueAtTime(yVal, this.ac.currentTime + 0.02 + t);\r\n } else if (yVal) {\r\n yVal.connect(this.panner.positionY);\r\n }\r\n return this.panner.positionY.value;\r\n };\r\n p5.Panner3D.prototype.positionZ = function(zVal, time) {\r\n var t = time || 0;\r\n if (typeof zVal === 'number') {\r\n this.panner.positionZ.value = zVal;\r\n this.panner.positionZ.cancelScheduledValues(this.ac.currentTime + 0.01 + t);\r\n this.panner.positionZ.linearRampToValueAtTime(zVal, this.ac.currentTime + 0.02 + t);\r\n } else if (zVal) {\r\n zVal.connect(this.panner.positionZ);\r\n }\r\n return this.panner.positionZ.value;\r\n };\r\n\r\n /**\r\n * Set the X,Y,Z position of the Panner\r\n * @method orient\r\n * @for p5.Panner3D\r\n * @param {Number} xVal\r\n * @param {Number} yVal\r\n * @param {Number} zVal\r\n * @param {Number} time\r\n * @return {Array} Updated x, y, z values as an array\r\n */\r\n p5.Panner3D.prototype.orient = function(xVal, yVal, zVal, time) {\r\n this.orientX(xVal,time);\r\n this.orientY(yVal,time);\r\n this.orientZ(zVal,time);\r\n return [this.panner.orientationX.value,\r\n this.panner.orientationY.value,\r\n this.panner.orientationZ.value];\r\n };\r\n\r\n /**\r\n * Getter and setter methods for orient coordinates\r\n * @method orientX\r\n * @for p5.Panner3D\r\n * @return {Number} updated coordinate value\r\n */\r\n /**\r\n * Getter and setter methods for orient coordinates\r\n * @method orientY\r\n * @for p5.Panner3D\r\n * @return {Number} updated coordinate value\r\n */\r\n /**\r\n * Getter and setter methods for orient coordinates\r\n * @method orientZ\r\n * @for p5.Panner3D\r\n * @return {Number} updated coordinate value\r\n */\r\n p5.Panner3D.prototype.orientX = function(xVal, time) {\r\n var t = time || 0;\r\n if (typeof xVal === 'number') {\r\n this.panner.orientationX.value = xVal;\r\n this.panner.orientationX.cancelScheduledValues(this.ac.currentTime + 0.01 + t);\r\n this.panner.orientationX.linearRampToValueAtTime(xVal, this.ac.currentTime + 0.02 + t);\r\n } else if (xVal) {\r\n xVal.connect(this.panner.orientationX);\r\n }\r\n return this.panner.orientationX.value;\r\n };\r\n p5.Panner3D.prototype.orientY = function(yVal, time) {\r\n var t = time || 0;\r\n if (typeof yVal === 'number') {\r\n this.panner.orientationY.value = yVal;\r\n this.panner.orientationY.cancelScheduledValues(this.ac.currentTime + 0.01 + t);\r\n this.panner.orientationY.linearRampToValueAtTime(yVal, this.ac.currentTime + 0.02 + t);\r\n } else if (yVal) {\r\n yVal.connect(this.panner.orientationY);\r\n }\r\n return this.panner.orientationY.value;\r\n };\r\n p5.Panner3D.prototype.orientZ = function(zVal, time) {\r\n var t = time || 0;\r\n if (typeof zVal === 'number') {\r\n this.panner.orientationZ.value = zVal;\r\n this.panner.orientationZ.cancelScheduledValues(this.ac.currentTime + 0.01 + t);\r\n this.panner.orientationZ.linearRampToValueAtTime(zVal, this.ac.currentTime + 0.02 + t);\r\n } else if (zVal) {\r\n zVal.connect(this.panner.orientationZ);\r\n }\r\n return this.panner.orientationZ.value;\r\n };\r\n\r\n /**\r\n * Set the rolloff factor and max distance\r\n * @method setFalloff\r\n * @for p5.Panner3D\r\n * @param {Number} [maxDistance]\r\n * @param {Number} [rolloffFactor]\r\n */\r\n p5.Panner3D.prototype.setFalloff = function(maxDistance, rolloffFactor) {\r\n this.maxDist(maxDistance);\r\n this.rolloff(rolloffFactor);\r\n };\r\n /**\r\n * Maxium distance between the source and the listener\r\n * @method maxDist\r\n * @for p5.Panner3D\r\n * @param {Number} maxDistance\r\n * @return {Number} updated value\r\n */\r\n p5.Panner3D.prototype.maxDist = function(maxDistance){\r\n if (typeof maxDistance === 'number') {\r\n this.panner.maxDistance = maxDistance;\r\n }\r\n return this.panner.maxDistance;\r\n };\r\n\r\n /**\r\n * How quickly the volume is reduced as the source moves away from the listener\r\n * @method rollof\r\n * @for p5.Panner3D\r\n * @param {Number} rolloffFactor\r\n * @return {Number} updated value\r\n */\r\n p5.Panner3D.prototype.rolloff = function(rolloffFactor){\r\n if (typeof rolloffFactor === 'number') {\r\n this.panner.rolloffFactor = rolloffFactor;\r\n }\r\n return this.panner.rolloffFactor;\r\n };\r\n\r\n p5.Panner3D.dispose = function() {\r\n Effect.prototype.dispose.apply(this);\r\n if (this.panner) {\r\n this.panner.disconnect();\r\n delete this.panner;\r\n }\r\n };\r\n\r\n return p5.Panner3D;\r\n\r\n});\r\n","'use strict'\r\n\r\ndefine(function (require) {\r\n var p5sound = require('master');\r\n var Effect = require('effect');\r\n\r\n// /**\r\n// * listener is a class that can construct both a Spatial Panner\r\n// * and a Spatial Listener. The panner is based on the \r\n// * Web Audio Spatial Panner Node\r\n// * https://www.w3.org/TR/webaudio/#the-listenernode-interface\r\n// * This panner is a spatial processing node that allows audio to be positioned\r\n// * and oriented in 3D space. \r\n// *\r\n// * The Listener modifies the properties of the Audio Context Listener. \r\n// * Both objects types use the same methods. The default is a spatial panner.\r\n// *\r\n// * p5.Panner3D - Constructs a Spatial Panner \r\n// * p5.Listener3D - Constructs a Spatial Listener \r\n// *\r\n// * @class listener\r\n// * @constructor\r\n// * @return {Object} p5.Listener3D Object\r\n// *\r\n// * @param {Web Audio Node} listener Web Audio Spatial Panning Node\r\n// * @param {AudioParam} listener.panningModel \"equal power\" or \"HRTF\"\r\n// * @param {AudioParam} listener.distanceModel \"linear\", \"inverse\", or \"exponential\"\r\n// * @param {String} [type] [Specify construction of a spatial panner or listener]\r\n// */\r\n \r\n\tp5.Listener3D = function(type) {\r\n this.ac = p5sound.audiocontext;\r\n this.listener = this.ac.listener;\r\n\t}; \r\n\r\n// /**\r\n// * Connect an audio sorce\r\n// * @param {Object} src Input source\r\n// */\r\n p5.Listener3D.prototype.process = function(src) {\r\n src.connect(this.input);\r\n }\r\n// /**\r\n// * Set the X,Y,Z position of the Panner\r\n// * @param {[Number]} xVal\r\n// * @param {[Number]} yVal\r\n// * @param {[Number]} zVal\r\n// * @param {[Number]} time\r\n// * @return {[Array]} [Updated x, y, z values as an array]\r\n// */\r\n p5.Listener3D.prototype.position = function(xVal, yVal, zVal, time) {\r\n this.positionX(xVal,time);\r\n this.positionY(yVal,time);\r\n this.positionZ(zVal,time);\r\n return [this.listener.positionX.value, \r\n this.listener.positionY.value,\r\n this.listener.positionZ.value];\r\n };\r\n\r\n// /**\r\n// * Getter and setter methods for position coordinates\r\n// * @return {Number} [updated coordinate value]\r\n// */\r\n p5.Listener3D.prototype.positionX = function(xVal, time) {\r\n var t = time || 0;\r\n if (typeof xVal === 'number') {\r\n this.listener.positionX.value = xVal;\r\n this.listener.positionX.cancelScheduledValues(this.ac.currentTime + 0.01 + t);\r\n this.listener.positionX.linearRampToValueAtTime(xVal, this.ac.currentTime + 0.02 + t);\r\n } else if (xVal) {\r\n xVal.connect(this.listener.positionX);\r\n }\r\n return this.listener.positionX.value;\r\n };\r\n p5.Listener3D.prototype.positionY = function(yVal, time) {\r\n var t = time || 0;\r\n if (typeof yVal === 'number') {\r\n this.listener.positionY.value = yVal;\r\n this.listener.positionY.cancelScheduledValues(this.ac.currentTime + 0.01 + t);\r\n this.listener.positionY.linearRampToValueAtTime(yVal, this.ac.currentTime + 0.02 + t);\r\n } else if (yVal) {\r\n yVal.connect(this.listener.positionY);\r\n }\r\n return this.listener.positionY.value;\r\n };\r\n p5.Listener3D.prototype.positionZ = function(zVal, time) {\r\n var t = time || 0;\r\n if (typeof zVal === 'number') {\r\n this.listener.positionZ.value = zVal;\r\n this.listener.positionZ.cancelScheduledValues(this.ac.currentTime + 0.01 + t);\r\n this.listener.positionZ.linearRampToValueAtTime(zVal, this.ac.currentTime + 0.02 + t);\r\n } else if (zVal) {\r\n zVal.connect(this.listener.positionZ);\r\n }\r\n return this.listener.positionZ.value;\r\n };\r\n\r\n// cannot define method when class definition is commented\r\n// /**\r\n// * Overrides the listener orient() method because Listener has slightly\r\n// * different params. In human terms, Forward vectors are the direction the \r\n// * nose is pointing. Up vectors are the direction of the top of the head.\r\n// *\r\n// * @method orient\r\n// * @param {Number} xValF Forward vector X direction\r\n// * @param {Number} yValF Forward vector Y direction\r\n// * @param {Number} zValF Forward vector Z direction\r\n// * @param {Number} xValU Up vector X direction\r\n// * @param {Number} yValU Up vector Y direction\r\n// * @param {Number} zValU Up vector Z direction\r\n// * @param {Number} time \r\n// * @return {Array} All orienation params\r\n// */\r\n p5.Listener3D.prototype.orient = function(xValF, yValF, zValF, \r\n xValU, yValU, zValU, time) {\r\n\r\n if (arguments.length === 3 || arguments.length === 4) {\r\n time = arguments[3];\r\n this.orientForward(xValF, yValF, zValF, time);\r\n } else if (arguments.length === 6 || arguments === 7) {\r\n this.orientForward(xValF, yValF, zValF);\r\n this.orientUp(xValU, yValU, zValU, time);\r\n }\r\n \r\n return [this.listener.forwardX.value, \r\n this.listener.forwardY.value,\r\n this.listener.forwardZ.value,\r\n this.listener.upX.value,\r\n this.listener.upY.value,\r\n this.listener.upZ.value];\r\n };\r\n\r\n\r\n p5.Listener3D.prototype.orientForward = function(xValF, yValF, zValF, time) {\r\n this.forwardX(xValF,time);\r\n this.forwardY(yValF,time);\r\n this.forwardZ(zValF,time);\r\n\r\n return [this.listener.forwardX, \r\n this.listener.forwardY,\r\n this.listener.forwardZ];\r\n };\r\n\r\n p5.Listener3D.prototype.orientUp = function(xValU, yValU, zValU, time) {\r\n this.upX(xValU,time);\r\n this.upY(yValU,time);\r\n this.upZ(zValU,time);\r\n\r\n return [this.listener.upX, \r\n this.listener.upY,\r\n this.listener.upZ];\r\n };\r\n// /**\r\n// * Getter and setter methods for orient coordinates\r\n// * @return {Number} [updated coordinate value]\r\n// */\r\n p5.Listener3D.prototype.forwardX = function(xVal, time) {\r\n var t = time || 0;\r\n if (typeof xVal === 'number') {\r\n this.listener.forwardX.value = xVal;\r\n this.listener.forwardX.cancelScheduledValues(this.ac.currentTime + 0.01 + t);\r\n this.listener.forwardX.linearRampToValueAtTime(xVal, this.ac.currentTime + 0.02 + t);\r\n } else if (xVal) {\r\n xVal.connect(this.listener.forwardX);\r\n }\r\n return this.listener.forwardX.value;\r\n };\r\n p5.Listener3D.prototype.forwardY = function(yVal, time) {\r\n var t = time || 0;\r\n if (typeof yVal === 'number') {\r\n this.listener.forwardY.value = yVal;\r\n this.listener.forwardY.cancelScheduledValues(this.ac.currentTime + 0.01 + t);\r\n this.listener.forwardY.linearRampToValueAtTime(yVal, this.ac.currentTime + 0.02 + t);\r\n } else if (yVal) {\r\n yVal.connect(this.listener.forwardY);\r\n }\r\n return this.listener.forwardY.value;\r\n };\r\n p5.Listener3D.prototype.forwardZ = function(zVal, time) {\r\n var t = time || 0;\r\n if (typeof zVal === 'number') {\r\n this.listener.forwardZ.value = zVal;\r\n this.listener.forwardZ.cancelScheduledValues(this.ac.currentTime + 0.01 + t);\r\n this.listener.forwardZ.linearRampToValueAtTime(zVal, this.ac.currentTime + 0.02 + t);\r\n } else if (zVal) {\r\n zVal.connect(this.listener.forwardZ);\r\n }\r\n return this.listener.forwardZ.value;\r\n };\r\n p5.Listener3D.prototype.upX = function(xVal, time) {\r\n var t = time || 0;\r\n if (typeof xVal === 'number') {\r\n this.listener.upX.value = xVal;\r\n this.listener.upX.cancelScheduledValues(this.ac.currentTime + 0.01 + t);\r\n this.listener.upX.linearRampToValueAtTime(xVal, this.ac.currentTime + 0.02 + t);\r\n } else if (xVal) {\r\n xVal.connect(this.listener.upX);\r\n }\r\n return this.listener.upX.value;\r\n };\r\n p5.Listener3D.prototype.upY = function(yVal, time) {\r\n var t = time || 0;\r\n if (typeof yVal === 'number') {\r\n this.listener.upY.value = yVal;\r\n this.listener.upY.cancelScheduledValues(this.ac.currentTime + 0.01 + t);\r\n this.listener.upY.linearRampToValueAtTime(yVal, this.ac.currentTime + 0.02 + t);\r\n } else if (yVal) {\r\n yVal.connect(this.listener.upY);\r\n }\r\n return this.listener.upY.value;\r\n };\r\n p5.Listener3D.prototype.upZ = function(zVal, time) {\r\n var t = time || 0;\r\n if (typeof zVal === 'number') {\r\n this.listener.upZ.value = zVal;\r\n this.listener.upZ.cancelScheduledValues(this.ac.currentTime + 0.01 + t);\r\n this.listener.upZ.linearRampToValueAtTime(zVal, this.ac.currentTime + 0.02 + t);\r\n } else if (zVal) {\r\n zVal.connect(this.listener.upZ);\r\n }\r\n return this.listener.upZ.value;\r\n };\r\n \r\n return p5.Listener3D;\r\n\r\n});","'use strict';\r\n\r\ndefine(function (require) {\r\n var Filter = require('filter');\r\n var Effect = require('effect');\r\n\r\n /**\r\n * Delay is an echo effect. It processes an existing sound source,\r\n * and outputs a delayed version of that sound. The p5.Delay can\r\n * produce different effects depending on the delayTime, feedback,\r\n * filter, and type. In the example below, a feedback of 0.5 (the\r\n * defaul value) will produce a looping delay that decreases in\r\n * volume by 50% each repeat. A filter will cut out the high\r\n * frequencies so that the delay does not sound as piercing as the\r\n * original source.\r\n *\r\n *\r\n * This class extends p5.Effect.\r\n * Methods amp(), chain(),\r\n * drywet(), connect(), and\r\n * disconnect() are available.\r\n * @class p5.Delay\r\n * @extends p5.Effect\r\n * @constructor\r\n * @example\r\n *
\r\n * var noise, env, delay;\r\n *\r\n * function setup() {\r\n * background(0);\r\n * noStroke();\r\n * fill(255);\r\n * textAlign(CENTER);\r\n * text('click to play', width/2, height/2);\r\n *\r\n * noise = new p5.Noise('brown');\r\n * noise.amp(0);\r\n * noise.start();\r\n *\r\n * delay = new p5.Delay();\r\n *\r\n * // delay.process() accepts 4 parameters:\r\n * // source, delayTime, feedback, filter frequency\r\n * // play with these numbers!!\r\n * delay.process(noise, .12, .7, 2300);\r\n *\r\n * // play the noise with an envelope,\r\n * // a series of fades ( time / value pairs )\r\n * env = new p5.Envelope(.01, 0.2, .2, .1);\r\n * }\r\n *\r\n * // mouseClick triggers envelope\r\n * function mouseClicked() {\r\n * // is mouse over canvas?\r\n * if (mouseX > 0 && mouseX < width && mouseY > 0 && mouseY < height) {\r\n * env.play(noise);\r\n * }\r\n * }\r\n *
\r\n */\r\n p5.Delay = function() {\r\n \tEffect.call(this);\r\n\r\n this._split = this.ac.createChannelSplitter(2);\r\n this._merge = this.ac.createChannelMerger(2);\r\n\r\n this._leftGain = this.ac.createGain();\r\n this._rightGain = this.ac.createGain();\r\n\r\n /**\r\n * The p5.Delay is built with two\r\n * \r\n * Web Audio Delay Nodes, one for each stereo channel.\r\n *\r\n * @property {DelayNode} leftDelay\r\n */\r\n this.leftDelay = this.ac.createDelay();\r\n /**\r\n * The p5.Delay is built with two\r\n * \r\n * Web Audio Delay Nodes, one for each stereo channel.\r\n *\r\n * @property {DelayNode} rightDelay\r\n */\r\n this.rightDelay = this.ac.createDelay();\r\n\r\n this._leftFilter = new Filter();\r\n this._rightFilter = new Filter();\r\n this._leftFilter.disconnect();\r\n this._rightFilter.disconnect();\r\n\r\n this._leftFilter.biquad.frequency.setValueAtTime(1200, this.ac.currentTime);\r\n this._rightFilter.biquad.frequency.setValueAtTime(1200, this.ac.currentTime);\r\n this._leftFilter.biquad.Q.setValueAtTime(0.3, this.ac.currentTime);\r\n this._rightFilter.biquad.Q.setValueAtTime(0.3, this.ac.currentTime);\r\n\r\n // graph routing\r\n this.input.connect(this._split);\r\n this.leftDelay.connect(this._leftGain);\r\n this.rightDelay.connect(this._rightGain);\r\n this._leftGain.connect(this._leftFilter.input);\r\n this._rightGain.connect(this._rightFilter.input);\r\n this._merge.connect(this.wet);\r\n\r\n\r\n this._leftFilter.biquad.gain.setValueAtTime(1, this.ac.currentTime);\r\n this._rightFilter.biquad.gain.setValueAtTime(1, this.ac.currentTime);\r\n\r\n // default routing\r\n this.setType(0);\r\n\r\n this._maxDelay = this.leftDelay.delayTime.maxValue;\r\n\r\n // set initial feedback to 0.5\r\n this.feedback(0.5);\r\n\r\n\r\n };\r\n\r\n p5.Delay.prototype = Object.create(Effect.prototype);\r\n /**\r\n * Add delay to an audio signal according to a set\r\n * of delay parameters.\r\n *\r\n * @method process\r\n * @for p5.Delay\r\n * @param {Object} Signal An object that outputs audio\r\n * @param {Number} [delayTime] Time (in seconds) of the delay/echo.\r\n * Some browsers limit delayTime to\r\n * 1 second.\r\n * @param {Number} [feedback] sends the delay back through itself\r\n * in a loop that decreases in volume\r\n * each time.\r\n * @param {Number} [lowPass] Cutoff frequency. Only frequencies\r\n * below the lowPass will be part of the\r\n * delay.\r\n */\r\n p5.Delay.prototype.process = function(src, _delayTime, _feedback, _filter) {\r\n var feedback = _feedback || 0;\r\n var delayTime = _delayTime || 0;\r\n if (feedback >= 1.0) {\r\n throw new Error('Feedback value will force a positive feedback loop.');\r\n }\r\n if (delayTime >= this._maxDelay) {\r\n throw new Error('Delay Time exceeds maximum delay time of ' + this._maxDelay + ' second.');\r\n }\r\n\r\n src.connect(this.input);\r\n this.leftDelay.delayTime.setValueAtTime(delayTime, this.ac.currentTime);\r\n this.rightDelay.delayTime.setValueAtTime(delayTime, this.ac.currentTime);\r\n this._leftGain.gain.value = feedback;\r\n this._rightGain.gain.value = feedback;\r\n\r\n if (_filter) {\r\n this._leftFilter.freq(_filter);\r\n this._rightFilter.freq(_filter);\r\n }\r\n };\r\n\r\n /**\r\n * Set the delay (echo) time, in seconds. Usually this value will be\r\n * a floating point number between 0.0 and 1.0.\r\n *\r\n * @method delayTime\r\n * @for p5.Delay\r\n * @param {Number} delayTime Time (in seconds) of the delay\r\n */\r\n p5.Delay.prototype.delayTime = function(t) {\r\n // if t is an audio node...\r\n if (typeof t !== 'number') {\r\n t.connect(this.leftDelay.delayTime);\r\n t.connect(this.rightDelay.delayTime);\r\n }\r\n\r\n else {\r\n this.leftDelay.delayTime.cancelScheduledValues(this.ac.currentTime);\r\n this.rightDelay.delayTime.cancelScheduledValues(this.ac.currentTime);\r\n this.leftDelay.delayTime.linearRampToValueAtTime(t, this.ac.currentTime);\r\n this.rightDelay.delayTime.linearRampToValueAtTime(t, this.ac.currentTime);\r\n }\r\n };\r\n\r\n /**\r\n * Feedback occurs when Delay sends its signal back through its input\r\n * in a loop. The feedback amount determines how much signal to send each\r\n * time through the loop. A feedback greater than 1.0 is not desirable because\r\n * it will increase the overall output each time through the loop,\r\n * creating an infinite feedback loop. The default value is 0.5\r\n *\r\n * @method feedback\r\n * @for p5.Delay\r\n * @param {Number|Object} feedback 0.0 to 1.0, or an object such as an\r\n * Oscillator that can be used to\r\n * modulate this param\r\n * @returns {Number} Feedback value\r\n *\r\n */\r\n p5.Delay.prototype.feedback = function(f) {\r\n // if f is an audio node...\r\n if (f && typeof f !== 'number') {\r\n f.connect(this._leftGain.gain);\r\n f.connect(this._rightGain.gain);\r\n }\r\n else if (f >= 1.0) {\r\n throw new Error('Feedback value will force a positive feedback loop.');\r\n }\r\n else if (typeof f === 'number') {\r\n this._leftGain.gain.value = f;\r\n this._rightGain.gain.value = f;\r\n }\r\n\r\n // return value of feedback\r\n return this._leftGain.gain.value;\r\n };\r\n\r\n /**\r\n * Set a lowpass filter frequency for the delay. A lowpass filter\r\n * will cut off any frequencies higher than the filter frequency.\r\n *\r\n * @method filter\r\n * @for p5.Delay\r\n * @param {Number|Object} cutoffFreq A lowpass filter will cut off any\r\n * frequencies higher than the filter frequency.\r\n * @param {Number|Object} res Resonance of the filter frequency\r\n * cutoff, or an object (i.e. a p5.Oscillator)\r\n * that can be used to modulate this parameter.\r\n * High numbers (i.e. 15) will produce a resonance,\r\n * low numbers (i.e. .2) will produce a slope.\r\n */\r\n p5.Delay.prototype.filter = function(freq, q) {\r\n this._leftFilter.set(freq, q);\r\n this._rightFilter.set(freq, q);\r\n };\r\n\r\n\r\n /**\r\n * Choose a preset type of delay. 'pingPong' bounces the signal\r\n * from the left to the right channel to produce a stereo effect.\r\n * Any other parameter will revert to the default delay setting.\r\n *\r\n * @method setType\r\n * @for p5.Delay\r\n * @param {String|Number} type 'pingPong' (1) or 'default' (0)\r\n */\r\n p5.Delay.prototype.setType = function(t) {\r\n if (t === 1) {\r\n t = 'pingPong';\r\n }\r\n this._split.disconnect();\r\n this._leftFilter.disconnect();\r\n this._rightFilter.disconnect();\r\n this._split.connect(this.leftDelay, 0);\r\n this._split.connect(this.rightDelay, 1);\r\n switch(t) {\r\n case 'pingPong':\r\n this._rightFilter.setType( this._leftFilter.biquad.type );\r\n this._leftFilter.output.connect(this._merge, 0, 0);\r\n this._rightFilter.output.connect(this._merge, 0, 1);\r\n this._leftFilter.output.connect(this.rightDelay);\r\n this._rightFilter.output.connect(this.leftDelay);\r\n break;\r\n default:\r\n this._leftFilter.output.connect(this._merge, 0, 0);\r\n this._rightFilter.output.connect(this._merge, 0, 1);\r\n this._leftFilter.output.connect(this.leftDelay);\r\n this._rightFilter.output.connect(this.rightDelay);\r\n }\r\n };\r\n\r\n // DocBlocks for methods inherited from p5.Effect\r\n /**\r\n * Set the output level of the delay effect.\r\n *\r\n * @method amp\r\n * @for p5.Delay\r\n * @param {Number} volume amplitude between 0 and 1.0\r\n * @param {Number} [rampTime] create a fade that lasts rampTime\r\n * @param {Number} [timeFromNow] schedule this event to happen\r\n * seconds from now\r\n */\r\n /**\r\n * Send output to a p5.sound or web audio object\r\n *\r\n * @method connect\r\n * @for p5.Delay\r\n * @param {Object} unit\r\n */\r\n /**\r\n * Disconnect all output.\r\n *\r\n * @method disconnect\r\n * @for p5.Delay\r\n */\r\n\r\n p5.Delay.prototype.dispose = function() {\r\n\r\n Effect.prototype.dispose.apply(this);\r\n\r\n this._split.disconnect();\r\n this._leftFilter.dispose();\r\n this._rightFilter.dispose();\r\n this._merge.disconnect();\r\n this._leftGain.disconnect();\r\n this._rightGain.disconnect();\r\n this.leftDelay.disconnect();\r\n this.rightDelay.disconnect();\r\n\r\n this._split = undefined;\r\n this._leftFilter = undefined;\r\n this._rightFilter = undefined;\r\n this._merge = undefined;\r\n this._leftGain = undefined;\r\n this._rightGain = undefined;\r\n this.leftDelay = undefined;\r\n this.rightDelay = undefined;\r\n };\r\n\r\n});\r\n","'use strict';\r\n\r\ndefine(function (require) {\r\n var CustomError = require('errorHandler');\r\n var Effect = require('effect');\r\n\r\n /**\r\n * Reverb adds depth to a sound through a large number of decaying\r\n * echoes. It creates the perception that sound is occurring in a\r\n * physical space. The p5.Reverb has paramters for Time (how long does the\r\n * reverb last) and decayRate (how much the sound decays with each echo)\r\n * that can be set with the .set() or .process() methods. The p5.Convolver\r\n * extends p5.Reverb allowing you to recreate the sound of actual physical\r\n * spaces through convolution.\r\n *\r\n * This class extends p5.Effect.\r\n * Methods amp(), chain(),\r\n * drywet(), connect(), and\r\n * disconnect() are available.\r\n *\r\n * @class p5.Reverb\r\n * @extends p5.Effect\r\n * @constructor\r\n * @example\r\n *
\r\n * var soundFile, reverb;\r\n * function preload() {\r\n * soundFile = loadSound('assets/Damscray_DancingTiger.mp3');\r\n * }\r\n *\r\n * function setup() {\r\n * reverb = new p5.Reverb();\r\n * soundFile.disconnect(); // so we'll only hear reverb...\r\n *\r\n * // connect soundFile to reverb, process w/\r\n * // 3 second reverbTime, decayRate of 2%\r\n * reverb.process(soundFile, 3, 2);\r\n * soundFile.play();\r\n * }\r\n *
\r\n */\r\n\r\n\r\n p5.Reverb = function() {\r\n Effect.call(this);\r\n\r\n this._initConvolverNode();\r\n\r\n // otherwise, Safari distorts\r\n this.input.gain.value = 0.5;\r\n\r\n // default params\r\n this._seconds = 3;\r\n this._decay = 2;\r\n this._reverse = false;\r\n\r\n this._buildImpulse();\r\n\r\n };\r\n\r\n p5.Reverb.prototype = Object.create(Effect.prototype);\r\n\r\n p5.Reverb.prototype._initConvolverNode = function() {\r\n this.convolverNode = this.ac.createConvolver();\r\n this.input.connect(this.convolverNode);\r\n this.convolverNode.connect(this.wet);\r\n };\r\n\r\n p5.Reverb.prototype._teardownConvolverNode = function() {\r\n if (this.convolverNode) {\r\n this.convolverNode.disconnect();\r\n delete this.convolverNode;\r\n }\r\n };\r\n\r\n p5.Reverb.prototype._setBuffer = function(audioBuffer) {\r\n this._teardownConvolverNode();\r\n this._initConvolverNode();\r\n this.convolverNode.buffer = audioBuffer;\r\n };\r\n /**\r\n * Connect a source to the reverb, and assign reverb parameters.\r\n *\r\n * @method process\r\n * @for p5.Reverb\r\n * @param {Object} src p5.sound / Web Audio object with a sound\r\n * output.\r\n * @param {Number} [seconds] Duration of the reverb, in seconds.\r\n * Min: 0, Max: 10. Defaults to 3.\r\n * @param {Number} [decayRate] Percentage of decay with each echo.\r\n * Min: 0, Max: 100. Defaults to 2.\r\n * @param {Boolean} [reverse] Play the reverb backwards or forwards.\r\n */\r\n p5.Reverb.prototype.process = function(src, seconds, decayRate, reverse) {\r\n src.connect(this.input);\r\n var rebuild = false;\r\n if (seconds) {\r\n this._seconds = seconds;\r\n rebuild = true;\r\n }\r\n if (decayRate) {\r\n this._decay = decayRate;\r\n }\r\n if (reverse) {\r\n this._reverse = reverse;\r\n }\r\n if (rebuild) {\r\n this._buildImpulse();\r\n }\r\n };\r\n\r\n /**\r\n * Set the reverb settings. Similar to .process(), but without\r\n * assigning a new input.\r\n *\r\n * @method set\r\n * @for p5.Reverb\r\n * @param {Number} [seconds] Duration of the reverb, in seconds.\r\n * Min: 0, Max: 10. Defaults to 3.\r\n * @param {Number} [decayRate] Percentage of decay with each echo.\r\n * Min: 0, Max: 100. Defaults to 2.\r\n * @param {Boolean} [reverse] Play the reverb backwards or forwards.\r\n */\r\n p5.Reverb.prototype.set = function(seconds, decayRate, reverse) {\r\n var rebuild = false;\r\n if (seconds) {\r\n this._seconds = seconds;\r\n rebuild = true;\r\n }\r\n if (decayRate) {\r\n this._decay = decayRate;\r\n }\r\n if (reverse) {\r\n this._reverse = reverse;\r\n }\r\n if (rebuild) {\r\n this._buildImpulse();\r\n }\r\n };\r\n\r\n // DocBlocks for methods inherited from p5.Effect\r\n /**\r\n * Set the output level of the reverb effect.\r\n *\r\n * @method amp\r\n * @for p5.Reverb\r\n * @param {Number} volume amplitude between 0 and 1.0\r\n * @param {Number} [rampTime] create a fade that lasts rampTime\r\n * @param {Number} [timeFromNow] schedule this event to happen\r\n * seconds from now\r\n */\r\n /**\r\n * Send output to a p5.sound or web audio object\r\n *\r\n * @method connect\r\n * @for p5.Reverb\r\n * @param {Object} unit\r\n */\r\n /**\r\n * Disconnect all output.\r\n *\r\n * @method disconnect\r\n * @for p5.Reverb\r\n */\r\n\r\n /**\r\n * Inspired by Simple Reverb by Jordan Santell\r\n * https://github.com/web-audio-components/simple-reverb/blob/master/index.js\r\n *\r\n * Utility function for building an impulse response\r\n * based on the module parameters.\r\n *\r\n * @private\r\n */\r\n p5.Reverb.prototype._buildImpulse = function() {\r\n var rate = this.ac.sampleRate;\r\n var length = rate*this._seconds;\r\n var decay = this._decay;\r\n var impulse = this.ac.createBuffer(2, length, rate);\r\n var impulseL = impulse.getChannelData(0);\r\n var impulseR = impulse.getChannelData(1);\r\n var n, i;\r\n for (i = 0; i < length; i++) {\r\n n = this._reverse ? length - i : i;\r\n impulseL[i] = (Math.random() * 2 - 1) * Math.pow(1 - n / length, decay);\r\n impulseR[i] = (Math.random() * 2 - 1) * Math.pow(1 - n / length, decay);\r\n }\r\n this._setBuffer(impulse);\r\n };\r\n\r\n p5.Reverb.prototype.dispose = function() {\r\n Effect.prototype.dispose.apply(this);\r\n this._teardownConvolverNode();\r\n };\r\n\r\n // =======================================================================\r\n // *** p5.Convolver ***\r\n // =======================================================================\r\n\r\n /**\r\n *
p5.Convolver extends p5.Reverb. It can emulate the sound of real\r\n * physical spaces through a process called \r\n * convolution.
\r\n *\r\n *
Convolution multiplies any audio input by an \"impulse response\"\r\n * to simulate the dispersion of sound over time. The impulse response is\r\n * generated from an audio file that you provide. One way to\r\n * generate an impulse response is to pop a balloon in a reverberant space\r\n * and record the echo. Convolution can also be used to experiment with\r\n * sound.
\r\n *\r\n *
Use the method createConvolution(path) to instantiate a\r\n * p5.Convolver with a path to your impulse response audio file.
\r\n *\r\n * @class p5.Convolver\r\n * @extends p5.Effect\r\n * @constructor\r\n * @param {String} path path to a sound file\r\n * @param {Function} [callback] function to call when loading succeeds\r\n * @param {Function} [errorCallback] function to call if loading fails.\r\n * This function will receive an error or\r\n * XMLHttpRequest object with information\r\n * about what went wrong.\r\n * @example\r\n *
\r\n * var cVerb, sound;\r\n * function preload() {\r\n * // We have both MP3 and OGG versions of all sound assets\r\n * soundFormats('ogg', 'mp3');\r\n *\r\n * // Try replacing 'bx-spring' with other soundfiles like\r\n * // 'concrete-tunnel' 'small-plate' 'drum' 'beatbox'\r\n * cVerb = createConvolver('assets/bx-spring.mp3');\r\n *\r\n * // Try replacing 'Damscray_DancingTiger' with\r\n * // 'beat', 'doorbell', lucky_dragons_-_power_melody'\r\n * sound = loadSound('assets/Damscray_DancingTiger.mp3');\r\n * }\r\n *\r\n * function setup() {\r\n * // disconnect from master output...\r\n * sound.disconnect();\r\n *\r\n * // ...and process with cVerb\r\n * // so that we only hear the convolution\r\n * cVerb.process(sound);\r\n *\r\n * sound.play();\r\n * }\r\n *
\r\n */\r\n p5.Convolver = function(path, callback, errorCallback) {\r\n \t p5.Reverb.call(this);\r\n\r\n /**\r\n * Internally, the p5.Convolver uses the a\r\n * \r\n * Web Audio Convolver Node.\r\n *\r\n * @property {ConvolverNode} convolverNode\r\n */\r\n this._initConvolverNode();\r\n\r\n // otherwise, Safari distorts\r\n this.input.gain.value = 0.5;\r\n\r\n if (path) {\r\n this.impulses = [];\r\n this._loadBuffer(path, callback, errorCallback);\r\n }\r\n else {\r\n // parameters\r\n this._seconds = 3;\r\n this._decay = 2;\r\n this._reverse = false;\r\n\r\n this._buildImpulse();\r\n }\r\n\r\n };\r\n\r\n p5.Convolver.prototype = Object.create(p5.Reverb.prototype);\r\n\r\n p5.prototype.registerPreloadMethod('createConvolver', p5.prototype);\r\n\r\n /**\r\n * Create a p5.Convolver. Accepts a path to a soundfile\r\n * that will be used to generate an impulse response.\r\n *\r\n * @method createConvolver\r\n * @for p5\r\n * @param {String} path path to a sound file\r\n * @param {Function} [callback] function to call if loading is successful.\r\n * The object will be passed in as the argument\r\n * to the callback function.\r\n * @param {Function} [errorCallback] function to call if loading is not successful.\r\n * A custom error will be passed in as the argument\r\n * to the callback function.\r\n * @return {p5.Convolver}\r\n * @example\r\n *
\r\n * var cVerb, sound;\r\n * function preload() {\r\n * // We have both MP3 and OGG versions of all sound assets\r\n * soundFormats('ogg', 'mp3');\r\n *\r\n * // Try replacing 'bx-spring' with other soundfiles like\r\n * // 'concrete-tunnel' 'small-plate' 'drum' 'beatbox'\r\n * cVerb = createConvolver('assets/bx-spring.mp3');\r\n *\r\n * // Try replacing 'Damscray_DancingTiger' with\r\n * // 'beat', 'doorbell', lucky_dragons_-_power_melody'\r\n * sound = loadSound('assets/Damscray_DancingTiger.mp3');\r\n * }\r\n *\r\n * function setup() {\r\n * // disconnect from master output...\r\n * sound.disconnect();\r\n *\r\n * // ...and process with cVerb\r\n * // so that we only hear the convolution\r\n * cVerb.process(sound);\r\n *\r\n * sound.play();\r\n * }\r\n *
\r\n */\r\n p5.prototype.createConvolver = function(path, callback, errorCallback) {\r\n // if loading locally without a server\r\n if (window.location.origin.indexOf('file://') > -1 && window.cordova === 'undefined') {\r\n alert('This sketch may require a server to load external files. Please see http://bit.ly/1qcInwS');\r\n }\r\n var self = this;\r\n var cReverb = new p5.Convolver(path, function(buffer) {\r\n if (typeof callback === 'function') {\r\n callback(buffer);\r\n }\r\n\r\n if (typeof self._decrementPreload === 'function') {\r\n self._decrementPreload();\r\n }\r\n }, errorCallback);\r\n cReverb.impulses = [];\r\n return cReverb;\r\n };\r\n\r\n /**\r\n * Private method to load a buffer as an Impulse Response,\r\n * assign it to the convolverNode, and add to the Array of .impulses.\r\n *\r\n * @param {String} path\r\n * @param {Function} callback\r\n * @param {Function} errorCallback\r\n * @private\r\n */\r\n p5.Convolver.prototype._loadBuffer = function(path, callback, errorCallback) {\r\n var path = p5.prototype._checkFileFormats(path);\r\n var self = this;\r\n var errorTrace = new Error().stack;\r\n var ac = p5.prototype.getAudioContext();\r\n\r\n var request = new XMLHttpRequest();\r\n request.open('GET', path, true);\r\n request.responseType = 'arraybuffer';\r\n\r\n request.onload = function() {\r\n if (request.status === 200) {\r\n // on success loading file:\r\n ac.decodeAudioData(request.response,\r\n function(buff) {\r\n var buffer = {};\r\n var chunks = path.split('/');\r\n buffer.name = chunks[chunks.length - 1];\r\n buffer.audioBuffer = buff;\r\n self.impulses.push(buffer);\r\n self._setBuffer(buffer.audioBuffer);\r\n if (callback) {\r\n callback(buffer);\r\n }\r\n },\r\n // error decoding buffer. \"e\" is undefined in Chrome 11/22/2015\r\n function() {\r\n var err = new CustomError('decodeAudioData', errorTrace, self.url);\r\n var msg = 'AudioContext error at decodeAudioData for ' + self.url;\r\n if (errorCallback) {\r\n err.msg = msg;\r\n errorCallback(err);\r\n } else {\r\n console.error(msg +'\\n The error stack trace includes: \\n' + err.stack);\r\n }\r\n }\r\n );\r\n }\r\n // if request status != 200, it failed\r\n else {\r\n var err = new CustomError('loadConvolver', errorTrace, self.url);\r\n var msg = 'Unable to load ' + self.url +\r\n '. The request status was: ' + request.status + ' (' + request.statusText + ')';\r\n\r\n if (errorCallback) {\r\n err.message = msg;\r\n errorCallback(err);\r\n } else {\r\n console.error(msg +'\\n The error stack trace includes: \\n' + err.stack);\r\n }\r\n }\r\n };\r\n\r\n // if there is another error, aside from 404...\r\n request.onerror = function() {\r\n var err = new CustomError('loadConvolver', errorTrace, self.url);\r\n var msg = 'There was no response from the server at ' + self.url + '. Check the url and internet connectivity.';\r\n\r\n if (errorCallback) {\r\n err.message = msg;\r\n errorCallback(err);\r\n } else {\r\n console.error(msg +'\\n The error stack trace includes: \\n' + err.stack);\r\n }\r\n };\r\n request.send();\r\n };\r\n\r\n p5.Convolver.prototype.set = null;\r\n\r\n /**\r\n * Connect a source to the reverb, and assign reverb parameters.\r\n *\r\n * @method process\r\n * @for p5.Convolver\r\n * @param {Object} src p5.sound / Web Audio object with a sound\r\n * output.\r\n * @example\r\n *
\r\n * var cVerb, sound;\r\n * function preload() {\r\n * soundFormats('ogg', 'mp3');\r\n *\r\n * cVerb = createConvolver('assets/concrete-tunnel.mp3');\r\n *\r\n * sound = loadSound('assets/beat.mp3');\r\n * }\r\n *\r\n * function setup() {\r\n * // disconnect from master output...\r\n * sound.disconnect();\r\n *\r\n * // ...and process with (i.e. connect to) cVerb\r\n * // so that we only hear the convolution\r\n * cVerb.process(sound);\r\n *\r\n * sound.play();\r\n * }\r\n *
\r\n */\r\n p5.Convolver.prototype.process = function(src) {\r\n src.connect(this.input);\r\n };\r\n\r\n /**\r\n * If you load multiple impulse files using the .addImpulse method,\r\n * they will be stored as Objects in this Array. Toggle between them\r\n * with the toggleImpulse(id) method.\r\n *\r\n * @property {Array} impulses\r\n * @for p5.Convolver\r\n */\r\n p5.Convolver.prototype.impulses = [];\r\n\r\n /**\r\n * Load and assign a new Impulse Response to the p5.Convolver.\r\n * The impulse is added to the .impulses array. Previous\r\n * impulses can be accessed with the .toggleImpulse(id)\r\n * method.\r\n *\r\n * @method addImpulse\r\n * @for p5.Convolver\r\n * @param {String} path path to a sound file\r\n * @param {Function} callback function (optional)\r\n * @param {Function} errorCallback function (optional)\r\n */\r\n p5.Convolver.prototype.addImpulse = function(path, callback, errorCallback) {\r\n // if loading locally without a server\r\n if (window.location.origin.indexOf('file://') > -1 && window.cordova === 'undefined') {\r\n alert('This sketch may require a server to load external files. Please see http://bit.ly/1qcInwS');\r\n }\r\n this._loadBuffer(path, callback, errorCallback);\r\n };\r\n\r\n /**\r\n * Similar to .addImpulse, except that the .impulses\r\n * Array is reset to save memory. A new .impulses\r\n * array is created with this impulse as the only item.\r\n *\r\n * @method resetImpulse\r\n * @for p5.Convolver\r\n * @param {String} path path to a sound file\r\n * @param {Function} callback function (optional)\r\n * @param {Function} errorCallback function (optional)\r\n */\r\n p5.Convolver.prototype.resetImpulse = function(path, callback, errorCallback) {\r\n // if loading locally without a server\r\n if (window.location.origin.indexOf('file://') > -1 && window.cordova === 'undefined') {\r\n alert('This sketch may require a server to load external files. Please see http://bit.ly/1qcInwS');\r\n }\r\n this.impulses = [];\r\n this._loadBuffer(path, callback, errorCallback);\r\n };\r\n\r\n /**\r\n * If you have used .addImpulse() to add multiple impulses\r\n * to a p5.Convolver, then you can use this method to toggle between\r\n * the items in the .impulses Array. Accepts a parameter\r\n * to identify which impulse you wish to use, identified either by its\r\n * original filename (String) or by its position in the .impulses\r\n * Array (Number). \r\n * You can access the objects in the .impulses Array directly. Each\r\n * Object has two attributes: an .audioBuffer (type:\r\n * Web Audio \r\n * AudioBuffer) and a .name, a String that corresponds\r\n * with the original filename.\r\n *\r\n * @method toggleImpulse\r\n * @for p5.Convolver\r\n * @param {String|Number} id Identify the impulse by its original filename\r\n * (String), or by its position in the\r\n * .impulses Array (Number).\r\n */\r\n p5.Convolver.prototype.toggleImpulse = function(id) {\r\n if (typeof id === 'number' && id < this.impulses.length) {\r\n this._setBuffer(this.impulses[id].audioBuffer);\r\n }\r\n if (typeof id === 'string') {\r\n for (var i = 0; i < this.impulses.length; i++) {\r\n if (this.impulses[i].name === id) {\r\n this._setBuffer(this.impulses[i].audioBuffer);\r\n break;\r\n }\r\n }\r\n }\r\n };\r\n\r\n p5.Convolver.prototype.dispose = function() {\r\n p5.Reverb.prototype.dispose.apply(this);\r\n\r\n // remove all the Impulse Response buffers\r\n for (var i in this.impulses) {\r\n if (this.impulses[i]) {\r\n this.impulses[i] = null;\r\n }\r\n }\r\n };\r\n\r\n});\r\n","'use strict';\r\n\r\ndefine(function (require) {\r\n var p5sound = require('master');\r\n\r\n // requires the Tone.js library's Clock (MIT license, Yotam Mann)\r\n // https://github.com/TONEnoTONE/Tone.js/\r\n var Clock = require('Tone/core/Clock');\r\n\r\n p5.Metro = function() {\r\n this.clock = new Clock({\r\n 'callback': this.ontick.bind(this)\r\n });\r\n this.syncedParts = [];\r\n this.bpm = 120; // gets overridden by p5.Part\r\n this._init();\r\n\r\n this.prevTick = 0;\r\n this.tatumTime = 0;\r\n\r\n this.tickCallback = function() {};\r\n };\r\n\r\n p5.Metro.prototype.ontick = function(tickTime) {\r\n var elapsedTime = tickTime - this.prevTick;\r\n var secondsFromNow = tickTime - p5sound.audiocontext.currentTime;\r\n if (elapsedTime - this.tatumTime <= -0.02) {\r\n return;\r\n } else {\r\n // console.log('ok', this.syncedParts[0].phrases[0].name);\r\n this.prevTick = tickTime;\r\n\r\n // for all of the active things on the metro:\r\n var self = this;\r\n this.syncedParts.forEach(function(thisPart) {\r\n if (!thisPart.isPlaying) return;\r\n thisPart.incrementStep(secondsFromNow);\r\n // each synced source keeps track of its own beat number\r\n thisPart.phrases.forEach(function(thisPhrase) {\r\n var phraseArray = thisPhrase.sequence;\r\n var bNum = self.metroTicks % phraseArray.length;\r\n if (phraseArray[bNum] !== 0 && (self.metroTicks < phraseArray.length || !thisPhrase.looping) ) {\r\n thisPhrase.callback(secondsFromNow, phraseArray[bNum]);\r\n }\r\n });\r\n });\r\n this.metroTicks += 1;\r\n this.tickCallback(secondsFromNow);\r\n }\r\n };\r\n\r\n p5.Metro.prototype.setBPM = function(bpm, rampTime) {\r\n var beatTime = 60 / (bpm*this.tatums);\r\n var now = p5sound.audiocontext.currentTime;\r\n this.tatumTime = beatTime;\r\n\r\n var rampTime = rampTime || 0;\r\n this.clock.frequency.setValueAtTime(this.clock.frequency.value, now);\r\n this.clock.frequency.linearRampToValueAtTime(bpm, now + rampTime);\r\n this.bpm = bpm;\r\n };\r\n\r\n p5.Metro.prototype.getBPM = function() {\r\n return this.clock.getRate() / this.tatums * 60;\r\n };\r\n\r\n p5.Metro.prototype._init = function() {\r\n this.metroTicks = 0;\r\n // this.setBPM(120);\r\n };\r\n\r\n // clear existing synced parts, add only this one\r\n p5.Metro.prototype.resetSync = function(part) {\r\n this.syncedParts = [part];\r\n };\r\n\r\n // push a new synced part to the array\r\n p5.Metro.prototype.pushSync = function(part) {\r\n this.syncedParts.push(part);\r\n };\r\n\r\n p5.Metro.prototype.start = function(timeFromNow) {\r\n var t = timeFromNow || 0;\r\n var now = p5sound.audiocontext.currentTime;\r\n this.clock.start(now + t);\r\n this.setBPM(this.bpm);\r\n };\r\n\r\n p5.Metro.prototype.stop = function(timeFromNow) {\r\n var t = timeFromNow || 0;\r\n var now = p5sound.audiocontext.currentTime;\r\n this.clock.stop(now + t);\r\n };\r\n\r\n p5.Metro.prototype.beatLength = function(tatums) {\r\n this.tatums = 1/tatums / 4; // lowest possible division of a beat\r\n };\r\n\r\n});\r\n","define([\"Tone/core/Tone\", \"Tone/core/Timeline\", \"Tone/type/Type\"], function (Tone) {\n\n\t\"use strict\";\n\n\t/**\n\t * @class A Timeline State. Provides the methods: setStateAtTime(\"state\", time)\n\t * and getValueAtTime(time).\n\t *\n\t * @extends {Tone.Timeline}\n\t * @param {String} initial The initial state of the TimelineState. \n\t * Defaults to undefined\n\t */\n\tTone.TimelineState = function(initial){\n\n\t\tTone.Timeline.call(this);\n\n\t\t/**\n\t\t * The initial state\n\t\t * @private\n\t\t * @type {String}\n\t\t */\n\t\tthis._initial = initial;\n\t};\n\n\tTone.extend(Tone.TimelineState, Tone.Timeline);\n\n\t/**\n\t * Returns the scheduled state scheduled before or at\n\t * the given time.\n\t * @param {Number} time The time to query.\n\t * @return {String} The name of the state input in setStateAtTime.\n\t */\n\tTone.TimelineState.prototype.getValueAtTime = function(time){\n\t\tvar event = this.get(time);\n\t\tif (event !== null){\n\t\t\treturn event.state;\n\t\t} else {\n\t\t\treturn this._initial;\n\t\t}\n\t};\n\n\t/**\n\t * Returns the scheduled state scheduled before or at\n\t * the given time.\n\t * @param {String} state The name of the state to set.\n\t * @param {Number} time The time to query.\n\t */\n\tTone.TimelineState.prototype.setStateAtTime = function(state, time){\n\t\tthis.add({\n\t\t\t\"state\" : state,\n\t\t\t\"time\" : time\n\t\t});\n\t};\n\n\treturn Tone.TimelineState;\n});","'use strict';\r\n\r\ndefine(function(require) {\r\n var p5sound = require('master');\r\n\r\n var BPM = 120;\r\n\r\n /**\r\n * Set the global tempo, in beats per minute, for all\r\n * p5.Parts. This method will impact all active p5.Parts.\r\n *\r\n * @method setBPM\r\n * @for p5\r\n * @param {Number} BPM Beats Per Minute\r\n * @param {Number} rampTime Seconds from now\r\n */\r\n p5.prototype.setBPM = function(bpm, rampTime) {\r\n BPM = bpm;\r\n for (var i in p5sound.parts) {\r\n if (p5sound.parts[i]) {\r\n p5sound.parts[i].setBPM(bpm, rampTime);\r\n }\r\n }\r\n };\r\n\r\n /**\r\n *
A phrase is a pattern of musical events over time, i.e.\r\n * a series of notes and rests.
\r\n *\r\n *
Phrases must be added to a p5.Part for playback, and\r\n * each part can play multiple phrases at the same time.\r\n * For example, one Phrase might be a kick drum, another\r\n * could be a snare, and another could be the bassline.
\r\n *\r\n *
The first parameter is a name so that the phrase can be\r\n * modified or deleted later. The callback is a a function that\r\n * this phrase will call at every step—for example it might be\r\n * called playNote(value){}. The array determines\r\n * which value is passed into the callback at each step of the\r\n * phrase. It can be numbers, an object with multiple numbers,\r\n * or a zero (0) indicates a rest so the callback won't be called).
\r\n *\r\n * @class p5.Phrase\r\n * @constructor\r\n * @param {String} name Name so that you can access the Phrase.\r\n * @param {Function} callback The name of a function that this phrase\r\n * will call. Typically it will play a sound,\r\n * and accept two parameters: a time at which\r\n * to play the sound (in seconds from now),\r\n * and a value from the sequence array. The\r\n * time should be passed into the play() or\r\n * start() method to ensure precision.\r\n * @param {Array} sequence Array of values to pass into the callback\r\n * at each step of the phrase.\r\n * @example\r\n *
\r\n */\r\n p5.Phrase = function(name, callback, sequence) {\r\n this.phraseStep = 0;\r\n this.name = name;\r\n this.callback = callback;\r\n /**\r\n * Array of values to pass into the callback\r\n * at each step of the phrase. Depending on the callback\r\n * function's requirements, these values may be numbers,\r\n * strings, or an object with multiple parameters.\r\n * Zero (0) indicates a rest.\r\n *\r\n * @property {Array} sequence\r\n */\r\n this.sequence = sequence;\r\n };\r\n\r\n /**\r\n *
A p5.Part plays back one or more p5.Phrases. Instantiate a part\r\n * with steps and tatums. By default, each step represents a 1/16th note.
\r\n *\r\n *
See p5.Phrase for more about musical timing.
\r\n *\r\n * @class p5.Part\r\n * @constructor\r\n * @param {Number} [steps] Steps in the part\r\n * @param {Number} [tatums] Divisions of a beat, e.g. use 1/4, or 0.25 for a quater note (default is 1/16, a sixteenth note)\r\n * @example\r\n *
\r\n * var box, drum, myPart;\r\n * var boxPat = [1,0,0,2,0,2,0,0];\r\n * var drumPat = [0,1,1,0,2,0,1,0];\r\n * var msg = 'click to play';\r\n *\r\n * function preload() {\r\n * box = loadSound('assets/beatbox.mp3');\r\n * drum = loadSound('assets/drum.mp3');\r\n * }\r\n *\r\n * function setup() {\r\n * noStroke();\r\n * fill(255);\r\n * textAlign(CENTER);\r\n * masterVolume(0.1);\r\n *\r\n * var boxPhrase = new p5.Phrase('box', playBox, boxPat);\r\n * var drumPhrase = new p5.Phrase('drum', playDrum, drumPat);\r\n * myPart = new p5.Part();\r\n * myPart.addPhrase(boxPhrase);\r\n * myPart.addPhrase(drumPhrase);\r\n * myPart.setBPM(60);\r\n * masterVolume(0.1);\r\n * }\r\n *\r\n * function draw() {\r\n * background(0);\r\n * text(msg, width/2, height/2);\r\n * }\r\n *\r\n * function playBox(time, playbackRate) {\r\n * box.rate(playbackRate);\r\n * box.play(time);\r\n * }\r\n *\r\n * function playDrum(time, playbackRate) {\r\n * drum.rate(playbackRate);\r\n * drum.play(time);\r\n * }\r\n *\r\n * function mouseClicked() {\r\n * if (mouseX > 0 && mouseX < width && mouseY > 0 && mouseY < height) {\r\n * myPart.start();\r\n * msg = 'playing part';\r\n * }\r\n * }\r\n *
\r\n */\r\n p5.Part = function(steps, bLength) {\r\n this.length = steps || 0; // how many beats\r\n this.partStep = 0;\r\n this.phrases = [];\r\n this.isPlaying = false;\r\n this.noLoop();\r\n this.tatums = bLength || 0.0625; // defaults to quarter note\r\n\r\n this.metro = new p5.Metro();\r\n this.metro._init();\r\n this.metro.beatLength(this.tatums);\r\n this.metro.setBPM(BPM);\r\n p5sound.parts.push(this);\r\n this.callback = function() {};\r\n };\r\n\r\n /**\r\n * Set the tempo of this part, in Beats Per Minute.\r\n *\r\n * @method setBPM\r\n * @for p5.Part\r\n * @param {Number} BPM Beats Per Minute\r\n * @param {Number} [rampTime] Seconds from now\r\n */\r\n p5.Part.prototype.setBPM = function(tempo, rampTime) {\r\n this.metro.setBPM(tempo, rampTime);\r\n };\r\n\r\n /**\r\n * Returns the tempo, in Beats Per Minute, of this part.\r\n *\r\n * @method getBPM\r\n * @for p5.Part\r\n * @return {Number}\r\n */\r\n p5.Part.prototype.getBPM = function() {\r\n return this.metro.getBPM();\r\n };\r\n\r\n /**\r\n * Start playback of this part. It will play\r\n * through all of its phrases at a speed\r\n * determined by setBPM.\r\n *\r\n * @method start\r\n * @for p5.Part\r\n * @param {Number} [time] seconds from now\r\n */\r\n p5.Part.prototype.start = function(time) {\r\n if (!this.isPlaying) {\r\n this.isPlaying = true;\r\n this.metro.resetSync(this);\r\n var t = time || 0;\r\n this.metro.start(t);\r\n }\r\n };\r\n\r\n /**\r\n * Loop playback of this part. It will begin\r\n * looping through all of its phrases at a speed\r\n * determined by setBPM.\r\n *\r\n * @method loop\r\n * @for p5.Part\r\n * @param {Number} [time] seconds from now\r\n */\r\n p5.Part.prototype.loop = function(time) {\r\n this.looping = true;\r\n // rest onended function\r\n this.onended = function() {\r\n this.partStep = 0;\r\n };\r\n var t = time || 0;\r\n this.start(t);\r\n };\r\n\r\n /**\r\n * Tell the part to stop looping.\r\n *\r\n * @method noLoop\r\n * @for p5.Part\r\n */\r\n p5.Part.prototype.noLoop = function() {\r\n this.looping = false;\r\n // rest onended function\r\n this.onended = function() {\r\n this.stop();\r\n };\r\n };\r\n\r\n /**\r\n * Stop the part and cue it to step 0. Playback will resume from the begining of the Part when it is played again.\r\n *\r\n * @method stop\r\n * @for p5.Part\r\n * @param {Number} [time] seconds from now\r\n */\r\n p5.Part.prototype.stop = function(time) {\r\n this.partStep = 0;\r\n this.pause(time);\r\n };\r\n\r\n /**\r\n * Pause the part. Playback will resume\r\n * from the current step.\r\n *\r\n * @method pause\r\n * @for p5.Part\r\n * @param {Number} time seconds from now\r\n */\r\n p5.Part.prototype.pause = function(time) {\r\n this.isPlaying = false;\r\n var t = time || 0;\r\n this.metro.stop(t);\r\n };\r\n\r\n /**\r\n * Add a p5.Phrase to this Part.\r\n *\r\n * @method addPhrase\r\n * @for p5.Part\r\n * @param {p5.Phrase} phrase reference to a p5.Phrase\r\n */\r\n p5.Part.prototype.addPhrase = function(name, callback, array) {\r\n var p;\r\n if (arguments.length === 3) {\r\n p = new p5.Phrase(name, callback, array);\r\n } else if (arguments[0] instanceof p5.Phrase) {\r\n p = arguments[0];\r\n } else {\r\n throw 'invalid input. addPhrase accepts name, callback, array or a p5.Phrase';\r\n }\r\n this.phrases.push(p);\r\n // reset the length if phrase is longer than part's existing length\r\n if (p.sequence.length > this.length) {\r\n this.length = p.sequence.length;\r\n }\r\n };\r\n\r\n /**\r\n * Remove a phrase from this part, based on the name it was\r\n * given when it was created.\r\n *\r\n * @method removePhrase\r\n * @for p5.Part\r\n * @param {String} phraseName\r\n */\r\n p5.Part.prototype.removePhrase = function(name) {\r\n for (var i in this.phrases) {\r\n if (this.phrases[i].name === name) {\r\n this.phrases.splice(i, 1);\r\n }\r\n }\r\n };\r\n\r\n /**\r\n * Get a phrase from this part, based on the name it was\r\n * given when it was created. Now you can modify its array.\r\n *\r\n * @method getPhrase\r\n * @for p5.Part\r\n * @param {String} phraseName\r\n */\r\n p5.Part.prototype.getPhrase = function(name) {\r\n for (var i in this.phrases) {\r\n if (this.phrases[i].name === name) {\r\n return this.phrases[i];\r\n }\r\n }\r\n };\r\n\r\n /**\r\n * Find all sequences with the specified name, and replace their patterns with the specified array.\r\n *\r\n * @method replaceSequence\r\n * @for p5.Part\r\n * @param {String} phraseName\r\n * @param {Array} sequence Array of values to pass into the callback\r\n * at each step of the phrase.\r\n */\r\n p5.Part.prototype.replaceSequence = function(name, array) {\r\n for (var i in this.phrases) {\r\n if (this.phrases[i].name === name) {\r\n this.phrases[i].sequence = array;\r\n }\r\n }\r\n };\r\n\r\n p5.Part.prototype.incrementStep = function(time) {\r\n if (this.partStep < this.length - 1) {\r\n this.callback(time);\r\n this.partStep += 1;\r\n } else {\r\n if (!this.looping && this.partStep === this.length - 1) {\r\n console.log('done');\r\n // this.callback(time);\r\n this.onended();\r\n }\r\n }\r\n };\r\n\r\n /**\r\n * Set the function that will be called at every step. This will clear the previous function.\r\n *\r\n * @method onStep\r\n * @for p5.Part\r\n * @param {Function} callback The name of the callback\r\n * you want to fire\r\n * on every beat/tatum.\r\n */\r\n p5.Part.prototype.onStep = function(callback) {\r\n this.callback = callback;\r\n };\r\n\r\n\r\n // ===============\r\n // p5.Score\r\n // ===============\r\n\r\n /**\r\n * A Score consists of a series of Parts. The parts will\r\n * be played back in order. For example, you could have an\r\n * A part, a B part, and a C part, and play them back in this order\r\n * new p5.Score(a, a, b, a, c)\r\n *\r\n * @class p5.Score\r\n * @constructor\r\n * @param {p5.Part} [...parts] One or multiple parts, to be played in sequence.\r\n */\r\n p5.Score = function() {\r\n // for all of the arguments\r\n this.parts = [];\r\n this.currentPart = 0;\r\n\r\n var thisScore = this;\r\n for (var i in arguments) {\r\n if (arguments[i] && this.parts[i]) {\r\n this.parts[i] = arguments[i];\r\n this.parts[i].nextPart = this.parts[i + 1];\r\n this.parts[i].onended = function() {\r\n thisScore.resetPart(i);\r\n playNextPart(thisScore);\r\n };\r\n }\r\n }\r\n this.looping = false;\r\n };\r\n\r\n p5.Score.prototype.onended = function() {\r\n if (this.looping) {\r\n // this.resetParts();\r\n this.parts[0].start();\r\n } else {\r\n this.parts[this.parts.length - 1].onended = function() {\r\n this.stop();\r\n this.resetParts();\r\n };\r\n }\r\n this.currentPart = 0;\r\n };\r\n\r\n /**\r\n * Start playback of the score.\r\n *\r\n * @method start\r\n * @for p5.Score\r\n */\r\n p5.Score.prototype.start = function() {\r\n this.parts[this.currentPart].start();\r\n this.scoreStep = 0;\r\n };\r\n\r\n /**\r\n * Stop playback of the score.\r\n *\r\n * @method stop\r\n * @for p5.Score\r\n */\r\n p5.Score.prototype.stop = function() {\r\n this.parts[this.currentPart].stop();\r\n this.currentPart = 0;\r\n this.scoreStep = 0;\r\n };\r\n\r\n /**\r\n * Pause playback of the score.\r\n *\r\n * @method pause\r\n * @for p5.Score\r\n */\r\n p5.Score.prototype.pause = function() {\r\n this.parts[this.currentPart].stop();\r\n };\r\n\r\n /**\r\n * Loop playback of the score.\r\n *\r\n * @method loop\r\n * @for p5.Score\r\n */\r\n p5.Score.prototype.loop = function() {\r\n this.looping = true;\r\n this.start();\r\n };\r\n\r\n /**\r\n * Stop looping playback of the score. If it\r\n * is currently playing, this will go into effect\r\n * after the current round of playback completes.\r\n *\r\n * @method noLoop\r\n * @for p5.Score\r\n */\r\n p5.Score.prototype.noLoop = function() {\r\n this.looping = false;\r\n };\r\n\r\n p5.Score.prototype.resetParts = function() {\r\n var self = this;\r\n this.parts.forEach(function(part) {\r\n self.resetParts[part];\r\n });\r\n };\r\n\r\n p5.Score.prototype.resetPart = function(i) {\r\n this.parts[i].stop();\r\n this.parts[i].partStep = 0;\r\n for (var p in this.parts[i].phrases) {\r\n if (this.parts[i]) {\r\n this.parts[i].phrases[p].phraseStep = 0;\r\n }\r\n }\r\n };\r\n\r\n /**\r\n * Set the tempo for all parts in the score\r\n *\r\n * @method setBPM\r\n * @for p5.Score\r\n * @param {Number} BPM Beats Per Minute\r\n * @param {Number} rampTime Seconds from now\r\n */\r\n p5.Score.prototype.setBPM = function(bpm, rampTime) {\r\n for (var i in this.parts) {\r\n if (this.parts[i]) {\r\n this.parts[i].setBPM(bpm, rampTime);\r\n }\r\n }\r\n };\r\n\r\n function playNextPart(aScore) {\r\n aScore.currentPart++;\r\n if (aScore.currentPart >= aScore.parts.length) {\r\n aScore.scoreStep = 0;\r\n aScore.onended();\r\n } else {\r\n aScore.scoreStep = 0;\r\n aScore.parts[aScore.currentPart - 1].stop();\r\n aScore.parts[aScore.currentPart].start();\r\n }\r\n }\r\n\r\n});\r\n","'use strict';\r\n\r\ndefine(function (require) {\r\n var p5sound = require('master');\r\n var Clock = require('Tone/core/Clock');\r\n\r\n /**\r\n * SoundLoop\r\n *\r\n * @class p5.SoundLoop\r\n * @constructor\r\n *\r\n * @param {Function} callback this function will be called on each iteration of theloop\r\n * @param {Number|String} [interval] amount of time or beats for each iteration of the loop\r\n * defaults to 1\r\n *\r\n * @example\r\n *
\r\n * var click;\r\n * var looper1;\r\n *\r\n * function preload() {\r\n * click = loadSound('assets/drum.mp3');\r\n * }\r\n *\r\n * function setup() {\r\n * //the looper's callback is passed the timeFromNow\r\n * //this value should be used as a reference point from\r\n * //which to schedule sounds\r\n * looper1 = new p5.SoundLoop(function(timeFromNow){\r\n * click.play(timeFromNow);\r\n * background(255 * (looper1.iterations % 2));\r\n * }, 2);\r\n *\r\n * //stop after 10 iteratios;\r\n * looper1.maxIterations = 10;\r\n * //start the loop\r\n * looper1.start();\r\n * }\r\n *
\r\n */\r\n p5.SoundLoop = function(callback, interval) {\r\n this.callback = callback;\r\n /**\r\n * musicalTimeMode uses Tone.Time convention\r\n\t * true if string, false if number\r\n * @property {Boolean} musicalTimeMode\r\n */\r\n this.musicalTimeMode = typeof this._interval === 'number' ? false : true;\r\n\r\n this._interval = interval || 1;\r\n\r\n /**\r\n * musicalTimeMode variables\r\n * modify these only when the interval is specified in musicalTime format as a string\r\n */\r\n this._timeSignature = 4;\r\n this._bpm = 60;\r\n\r\n this.isPlaying = false;\r\n\r\n /**\r\n * Set a limit to the number of loops to play. defaults to Infinity\r\n * @property {Number} maxIterations\r\n */\r\n this.maxIterations = Infinity;\r\n var self = this;\r\n\r\n this.clock = new Clock({\r\n 'callback' : function(time) {\r\n var timeFromNow = time - p5sound.audiocontext.currentTime;\r\n /**\r\n * Do not initiate the callback if timeFromNow is < 0\r\n * This ususually occurs for a few milliseconds when the page\r\n * is not fully loaded\r\n *\r\n * The callback should only be called until maxIterations is reached\r\n */\r\n if (timeFromNow > 0 && self.iterations <= self.maxIterations) {\r\n self.callback(timeFromNow);}\r\n },\r\n 'frequency' : this._calcFreq()\r\n });\r\n };\r\n\r\n /**\r\n * Start the loop\r\n * @method start\r\n * @for p5.SoundLoop\r\n * @param {Number} [timeFromNow] schedule a starting time\r\n */\r\n p5.SoundLoop.prototype.start = function(timeFromNow) {\r\n var t = timeFromNow || 0;\r\n var now = p5sound.audiocontext.currentTime;\r\n if (!this.isPlaying) {\r\n this.clock.start(now + t);\r\n this.isPlaying = true;\r\n }\r\n };\r\n\r\n /**\r\n * Stop the loop\r\n * @method stop\r\n * @for p5.SoundLoop\r\n * @param {Number} [timeFromNow] schedule a stopping time\r\n */\r\n p5.SoundLoop.prototype.stop = function(timeFromNow) {\r\n var t = timeFromNow || 0;\r\n var now = p5sound.audiocontext.currentTime;\r\n if (this.isPlaying) {\r\n this.clock.stop(now + t);\r\n this.isPlaying = false;\r\n }\r\n };\r\n /**\r\n * Pause the loop\r\n * @method pause\r\n * @for p5.SoundLoop\r\n * @param {Number} [timeFromNow] schedule a pausing time\r\n */\r\n p5.SoundLoop.prototype.pause = function(timeFromNow) {\r\n var t = timeFromNow || 0;\r\n var now = p5sound.audiocontext.currentTime;\r\n if (this.isPlaying) {\r\n this.clock.pause(now + t);\r\n this.isPlaying = false;\r\n }\r\n };\r\n\r\n\r\n /**\r\n * Synchronize loops. Use this method to start two more more loops in synchronization\r\n * or to start a loop in synchronization with a loop that is already playing\r\n * This method will schedule the implicit loop in sync with the explicit master loop\r\n * i.e. loopToStart.syncedStart(loopToSyncWith)\r\n *\r\n * @method syncedStart\r\n * @for p5.SoundLoop\r\n * @param {Object} otherLoop a p5.SoundLoop to sync with\r\n * @param {Number} [timeFromNow] Start the loops in sync after timeFromNow seconds\r\n */\r\n p5.SoundLoop.prototype.syncedStart = function(otherLoop, timeFromNow) {\r\n var t = timeFromNow || 0;\r\n var now = p5sound.audiocontext.currentTime;\r\n\r\n if (!otherLoop.isPlaying) {\r\n otherLoop.clock.start(now + t);\r\n otherLoop.isPlaying = true;\r\n this.clock.start(now + t);\r\n this.isPlaying = true;\r\n } else if (otherLoop.isPlaying) {\r\n var time = otherLoop.clock._nextTick - p5sound.audiocontext.currentTime;\r\n this.clock.start(now + time);\r\n this.isPlaying = true;\r\n }\r\n };\r\n\r\n\r\n /**\r\n * Updates frequency value, reflected in next callback\r\n * @private\r\n * @for p5.SoundLoop\r\n * @method _update\r\n */\r\n p5.SoundLoop.prototype._update = function() {\r\n this.clock.frequency.value = this._calcFreq();\r\n };\r\n\r\n /**\r\n * Calculate the frequency of the clock's callback based on bpm, interval, and timesignature\r\n * @private\r\n * @for p5.SoundLoop\r\n * @method _calcFreq\r\n * @return {Number} new clock frequency value\r\n */\r\n p5.SoundLoop.prototype._calcFreq = function() {\r\n //Seconds mode, bpm / timesignature has no effect\r\n if (typeof this._interval === 'number') {\r\n this.musicalTimeMode = false;\r\n return 1 / this._interval;\r\n }\r\n //Musical timing mode, calculate interval based bpm, interval,and time signature\r\n else if (typeof this._interval === 'string') {\r\n this.musicalTimeMode = true;\r\n return this._bpm / 60 / this._convertNotation(this._interval) * (this._timeSignature / 4);\r\n }\r\n };\r\n\r\n /**\r\n * Convert notation from musical time format to seconds\r\n * Uses Tone.Time convention\r\n * @private\r\n * @for p5.SoundLoop\r\n * @method _convertNotation\r\n * @param {String} value value to be converted\r\n * @return {Number} converted value in seconds\r\n */\r\n p5.SoundLoop.prototype._convertNotation = function(value) {\r\n var type = value.slice(-1);\r\n value = Number(value.slice(0,-1));\r\n switch (type) {\r\n case 'm':\r\n return this._measure(value);\r\n case 'n':\r\n return this._note(value);\r\n default:\r\n console.warn('Specified interval is not formatted correctly. See Tone.js '+\r\n 'timing reference for more info: https://github.com/Tonejs/Tone.js/wiki/Time');\r\n }\r\n };\r\n\r\n /**\r\n * Helper conversion methods of measure and note\r\n * @private\r\n * @for p5.SoundLoop\r\n * @method _measure\r\n */\r\n p5.SoundLoop.prototype._measure = function(value) {\r\n return value * this._timeSignature;\r\n };\r\n\r\n /**\r\n * @private\r\n * @method _note\r\n * @for p5.SoundLoop\r\n */\r\n p5.SoundLoop.prototype._note = function(value) {\r\n return this._timeSignature / value ;\r\n };\r\n\r\n\r\n /**\r\n * Getters and Setters, setting any paramter will result in a change in the clock's\r\n * frequency, that will be reflected after the next callback\r\n * beats per minute (defaults to 60)\r\n * @property {Number} bpm\r\n * @for p5.SoundLoop\r\n */\r\n Object.defineProperty(p5.SoundLoop.prototype, 'bpm', {\r\n get : function() {\r\n return this._bpm;\r\n },\r\n set : function(bpm) {\r\n if (!this.musicalTimeMode) {\r\n console.warn('Changing the BPM in \"seconds\" mode has no effect. '+\r\n 'BPM is only relevant in musicalTimeMode '+\r\n 'when the interval is specified as a string '+\r\n '(\"2n\", \"4n\", \"1m\"...etc)');\r\n }\r\n this._bpm = bpm;\r\n this._update();\r\n }\r\n });\r\n\r\n /**\r\n * number of quarter notes in a measure (defaults to 4)\r\n * @property {Number} timeSignature\r\n * @for p5.SoundLoop\r\n */\r\n Object.defineProperty(p5.SoundLoop.prototype, 'timeSignature', {\r\n get : function() {\r\n return this._timeSignature;\r\n },\r\n set : function(timeSig) {\r\n if (!this.musicalTimeMode) {\r\n console.warn('Changing the timeSignature in \"seconds\" mode has no effect. '+\r\n 'BPM is only relevant in musicalTimeMode '+\r\n 'when the interval is specified as a string '+\r\n '(\"2n\", \"4n\", \"1m\"...etc)');\r\n }\r\n this._timeSignature = timeSig;\r\n this._update();\r\n }\r\n });\r\n\r\n /**\r\n * length of the loops interval\r\n * @property {Number|String} interval\r\n * @for p5.SoundLoop\r\n */\r\n Object.defineProperty(p5.SoundLoop.prototype, 'interval', {\r\n get : function() {\r\n return this._interval;\r\n },\r\n set : function(interval) {\r\n this.musicalTimeMode = typeof interval === 'Number'? false : true;\r\n this._interval = interval;\r\n this._update();\r\n }\r\n });\r\n\r\n /**\r\n * how many times the callback has been called so far\r\n * @property {Number} iterations\r\n * @for p5.SoundLoop\r\n * @readonly\r\n */\r\n Object.defineProperty(p5.SoundLoop.prototype, 'iterations', {\r\n get : function() {\r\n return this.clock.ticks;\r\n }\r\n });\r\n\r\n return p5.SoundLoop;\r\n});\r\n","define(function (require) {\r\n\t'use strict';\r\n\r\n\tvar p5sound = require('master');\r\n\tvar Effect = require('effect');\r\n var CustomError = require('errorHandler');\r\n\r\n /**\r\n * Compressor is an audio effect class that performs dynamics compression\r\n * on an audio input source. This is a very commonly used technique in music\r\n * and sound production. Compression creates an overall louder, richer,\r\n * and fuller sound by lowering the volume of louds and raising that of softs.\r\n * Compression can be used to avoid clipping (sound distortion due to\r\n * peaks in volume) and is especially useful when many sounds are played\r\n * at once. Compression can be used on indivudal sound sources in addition\r\n * to the master output.\r\n *\r\n * This class extends p5.Effect.\r\n * Methods amp(), chain(),\r\n * drywet(), connect(), and\r\n * disconnect() are available.\r\n *\r\n * @class p5.Compressor\r\n * @constructor\r\n * @extends p5.Effect\r\n *\r\n *\r\n */\r\n\tp5.Compressor = function() {\r\n\t\tEffect.call(this);\r\n\r\n /**\r\n * The p5.Compressor is built with a Web Audio Dynamics Compressor Node\r\n * \r\n * @property {AudioNode} compressor\r\n */\r\n\r\n\r\n\t\tthis.compressor = this.ac.createDynamicsCompressor();\r\n\r\n this.input.connect(this.compressor);\r\n this.compressor.connect(this.wet);\r\n\t};\r\n\r\n\tp5.Compressor.prototype = Object.create(Effect.prototype);\r\n\r\n /**\r\n * Performs the same function as .connect, but also accepts\r\n * optional parameters to set compressor's audioParams\r\n * @method process\r\n * @for p5.Compressor\r\n *\r\n * @param {Object} src Sound source to be connected\r\n *\r\n * @param {Number} [attack] The amount of time (in seconds) to reduce the gain by 10dB,\r\n * default = .003, range 0 - 1\r\n * @param {Number} [knee] A decibel value representing the range above the\r\n * threshold where the curve smoothly transitions to the \"ratio\" portion.\r\n * default = 30, range 0 - 40\r\n * @param {Number} [ratio] The amount of dB change in input for a 1 dB change in output\r\n * default = 12, range 1 - 20\r\n * @param {Number} [threshold] The decibel value above which the compression will start taking effect\r\n * default = -24, range -100 - 0\r\n * @param {Number} [release] The amount of time (in seconds) to increase the gain by 10dB\r\n * default = .25, range 0 - 1\r\n */\r\n\tp5.Compressor.prototype.process = function(src, attack, knee,\r\n ratio, threshold, release) {\r\n\t\tsrc.connect(this.input);\r\n\t\tthis.set(attack, knee, ratio, threshold, release);\r\n\t};\r\n\r\n /**\r\n * Set the paramters of a compressor.\r\n * @method set\r\n * @for p5.Compressor\r\n * @param {Number} attack The amount of time (in seconds) to reduce the gain by 10dB,\r\n * default = .003, range 0 - 1\r\n * @param {Number} knee A decibel value representing the range above the\r\n * threshold where the curve smoothly transitions to the \"ratio\" portion.\r\n * default = 30, range 0 - 40\r\n * @param {Number} ratio The amount of dB change in input for a 1 dB change in output\r\n * default = 12, range 1 - 20\r\n * @param {Number} threshold The decibel value above which the compression will start taking effect\r\n * default = -24, range -100 - 0\r\n * @param {Number} release The amount of time (in seconds) to increase the gain by 10dB\r\n * default = .25, range 0 - 1\r\n */\r\n p5.Compressor.prototype.set = function (attack, knee,\r\n ratio, threshold, release) {\r\n\r\n if (typeof attack !== 'undefined') {this.attack(attack);}\r\n if (typeof knee !== 'undefined') {this.knee(knee);}\r\n if (typeof ratio !== 'undefined') {this.ratio(ratio);}\r\n if (typeof threshold !== 'undefined') {this.threshold(threshold);}\r\n if (typeof release !== 'undefined') {this.release(release);}\r\n };\r\n\r\n\r\n /**\r\n * Get current attack or set value w/ time ramp\r\n *\r\n *\r\n * @method attack\r\n * @for p5.Compressor\r\n * @param {Number} [attack] Attack is the amount of time (in seconds) to reduce the gain by 10dB,\r\n * default = .003, range 0 - 1\r\n * @param {Number} [time] Assign time value to schedule the change in value\r\n */\r\n p5.Compressor.prototype.attack = function (attack, time){\r\n var t = time || 0;\r\n if (typeof attack == 'number'){\r\n this.compressor.attack.value = attack;\r\n this.compressor.attack.cancelScheduledValues(this.ac.currentTime + 0.01 + t);\r\n this.compressor.attack.linearRampToValueAtTime(attack, this.ac.currentTime + 0.02 + t);\r\n } else if (typeof attack !== 'undefined') {\r\n attack.connect(this.compressor.attack);\r\n }\r\n return this.compressor.attack.value;\r\n };\r\n\r\n\r\n /**\r\n * Get current knee or set value w/ time ramp\r\n *\r\n * @method knee\r\n * @for p5.Compressor\r\n * @param {Number} [knee] A decibel value representing the range above the\r\n * threshold where the curve smoothly transitions to the \"ratio\" portion.\r\n * default = 30, range 0 - 40\r\n * @param {Number} [time] Assign time value to schedule the change in value\r\n */\r\n p5.Compressor.prototype.knee = function (knee, time){\r\n var t = time || 0;\r\n if (typeof knee == 'number'){\r\n this.compressor.knee.value = knee;\r\n this.compressor.knee.cancelScheduledValues(this.ac.currentTime + 0.01 + t);\r\n this.compressor.knee.linearRampToValueAtTime(knee, this.ac.currentTime + 0.02 + t);\r\n } else if (typeof knee !== 'undefined') {\r\n knee.connect(this.compressor.knee);\r\n }\r\n return this.compressor.knee.value;\r\n };\r\n\r\n\r\n /**\r\n * Get current ratio or set value w/ time ramp\r\n * @method ratio\r\n * @for p5.Compressor\r\n * @param {Number} [ratio] The amount of dB change in input for a 1 dB change in output\r\n * default = 12, range 1 - 20\r\n * @param {Number} [time] Assign time value to schedule the change in value\r\n */\r\n p5.Compressor.prototype.ratio = function (ratio, time){\r\n var t = time || 0;\r\n if (typeof ratio == 'number'){\r\n this.compressor.ratio.value = ratio;\r\n this.compressor.ratio.cancelScheduledValues(this.ac.currentTime + 0.01 + t);\r\n this.compressor.ratio.linearRampToValueAtTime(ratio, this.ac.currentTime + 0.02 + t);\r\n } else if (typeof ratio !== 'undefined') {\r\n ratio.connect(this.compressor.ratio);\r\n }\r\n return this.compressor.ratio.value;\r\n };\r\n\r\n\r\n /**\r\n * Get current threshold or set value w/ time ramp\r\n * @method threshold\r\n * @for p5.Compressor\r\n * @param {Number} threshold The decibel value above which the compression will start taking effect\r\n * default = -24, range -100 - 0\r\n * @param {Number} [time] Assign time value to schedule the change in value\r\n */\r\n p5.Compressor.prototype.threshold = function (threshold, time){\r\n var t = time || 0;\r\n if (typeof threshold == 'number'){\r\n this.compressor.threshold.value = threshold;\r\n this.compressor.threshold.cancelScheduledValues(this.ac.currentTime + 0.01 + t);\r\n this.compressor.threshold.linearRampToValueAtTime(threshold, this.ac.currentTime + 0.02 + t);\r\n } else if (typeof threshold !== 'undefined') {\r\n threshold.connect(this.compressor.threshold);\r\n }\r\n return this.compressor.threshold.value;\r\n };\r\n\r\n\r\n /**\r\n * Get current release or set value w/ time ramp\r\n * @method release\r\n * @for p5.Compressor\r\n * @param {Number} release The amount of time (in seconds) to increase the gain by 10dB\r\n * default = .25, range 0 - 1\r\n *\r\n * @param {Number} [time] Assign time value to schedule the change in value\r\n */\r\n p5.Compressor.prototype.release = function (release, time){\r\n var t = time || 0;\r\n if (typeof release == 'number'){\r\n this.compressor.release.value = release;\r\n this.compressor.release.cancelScheduledValues(this.ac.currentTime + 0.01 + t);\r\n this.compressor.release.linearRampToValueAtTime(release, this.ac.currentTime + 0.02 + t);\r\n } else if (typeof number !== 'undefined') {\r\n release.connect(this.compressor.release);\r\n }\r\n return this.compressor.release.value;\r\n };\r\n\r\n /**\r\n * Return the current reduction value\r\n *\r\n * @method reduction\r\n * @for p5.Compressor\r\n * @return {Number} Value of the amount of gain reduction that is applied to the signal\r\n */\r\n p5.Compressor.prototype.reduction =function() {\r\n return this.compressor.reduction.value;\r\n };\r\n\r\n\r\n\tp5.Compressor.prototype.dispose = function() {\r\n Effect.prototype.dispose.apply(this);\r\n if (this.compressor) {\r\n this.compressor.disconnect();\r\n delete this.compressor;\r\n }\r\n\t};\r\n\r\n return p5.Compressor;\r\n});\r\n","'use strict';\r\n\r\ndefine(function (require) {\r\n\r\n // inspiration: recorder.js, Tone.js & typedarray.org\r\n\r\n var p5sound = require('master');\r\n var convertToWav = require('helpers').convertToWav;\r\n var processorNames = require('./audioWorklet/processorNames');\r\n var ac = p5sound.audiocontext;\r\n\r\n /**\r\n *
Record sounds for playback and/or to save as a .wav file.\r\n * The p5.SoundRecorder records all sound output from your sketch,\r\n * or can be assigned a specific source with setInput().
\r\n *
The record() method accepts a p5.SoundFile as a parameter.\r\n * When playback is stopped (either after the given amount of time,\r\n * or with the stop() method), the p5.SoundRecorder will send its\r\n * recording to that p5.SoundFile for playback.
\r\n * var mic, recorder, soundFile;\r\n * var state = 0;\r\n *\r\n * function setup() {\r\n * background(200);\r\n * // create an audio in\r\n * mic = new p5.AudioIn();\r\n *\r\n * // prompts user to enable their browser mic\r\n * mic.start();\r\n *\r\n * // create a sound recorder\r\n * recorder = new p5.SoundRecorder();\r\n *\r\n * // connect the mic to the recorder\r\n * recorder.setInput(mic);\r\n *\r\n * // this sound file will be used to\r\n * // playback & save the recording\r\n * soundFile = new p5.SoundFile();\r\n *\r\n * text('keyPress to record', 20, 20);\r\n * }\r\n *\r\n * function keyPressed() {\r\n * // make sure user enabled the mic\r\n * if (state === 0 && mic.enabled) {\r\n *\r\n * // record to our p5.SoundFile\r\n * recorder.record(soundFile);\r\n *\r\n * background(255,0,0);\r\n * text('Recording!', 20, 20);\r\n * state++;\r\n * }\r\n * else if (state === 1) {\r\n * background(0,255,0);\r\n *\r\n * // stop recorder and\r\n * // send result to soundFile\r\n * recorder.stop();\r\n *\r\n * text('Stopped', 20, 20);\r\n * state++;\r\n * }\r\n *\r\n * else if (state === 2) {\r\n * soundFile.play(); // play the result!\r\n * save(soundFile, 'mySound.wav');\r\n * state++;\r\n * }\r\n * }\r\n *
\r\n */\r\n p5.SoundRecorder = function() {\r\n this.input = ac.createGain();\r\n this.output = ac.createGain();\r\n\r\n this._inputChannels = 2;\r\n this._outputChannels = 2; // stereo output, even if input is mono\r\n\r\n this._workletNode = new AudioWorkletNode(ac, processorNames.recorderProcessor, {\r\n outputChannelCount: [this._outputChannels],\r\n processorOptions: { numInputChannels: this._inputChannels }\r\n });\r\n\r\n this._workletNode.port.onmessage = function(event) {\r\n if (event.data.name === 'buffers') {\r\n const buffers = [\r\n new Float32Array(event.data.leftBuffer),\r\n new Float32Array(event.data.rightBuffer)\r\n ];\r\n this._callback(buffers);\r\n }\r\n }.bind(this);\r\n\r\n /**\r\n * callback invoked when the recording is over\r\n * @private\r\n * @type Function(Float32Array)\r\n */\r\n this._callback = function() {};\r\n\r\n // connections\r\n this._workletNode.connect(p5.soundOut._silentNode);\r\n this.setInput();\r\n\r\n // add this p5.SoundFile to the soundArray\r\n p5sound.soundArray.push(this);\r\n };\r\n\r\n /**\r\n * Connect a specific device to the p5.SoundRecorder.\r\n * If no parameter is given, p5.SoundRecorer will record\r\n * all audible p5.sound from your sketch.\r\n *\r\n * @method setInput\r\n * @for p5.SoundRecorder\r\n * @param {Object} [unit] p5.sound object or a web audio unit\r\n * that outputs sound\r\n */\r\n p5.SoundRecorder.prototype.setInput = function(unit) {\r\n this.input.disconnect();\r\n this.input = null;\r\n this.input = ac.createGain();\r\n this.input.connect(this._workletNode);\r\n this.input.connect(this.output);\r\n if (unit) {\r\n unit.connect(this.input);\r\n } else {\r\n p5.soundOut.output.connect(this.input);\r\n }\r\n };\r\n\r\n /**\r\n * Start recording. To access the recording, provide\r\n * a p5.SoundFile as the first parameter. The p5.SoundRecorder\r\n * will send its recording to that p5.SoundFile for playback once\r\n * recording is complete. Optional parameters include duration\r\n * (in seconds) of the recording, and a callback function that\r\n * will be called once the complete recording has been\r\n * transfered to the p5.SoundFile.\r\n *\r\n * @method record\r\n * @for p5.SoundRecorder\r\n * @param {p5.SoundFile} soundFile p5.SoundFile\r\n * @param {Number} [duration] Time (in seconds)\r\n * @param {Function} [callback] The name of a function that will be\r\n * called once the recording completes\r\n */\r\n p5.SoundRecorder.prototype.record = function(sFile, duration, callback) {\r\n this._workletNode.port.postMessage({ name: 'start', duration: duration });\r\n\r\n if (sFile && callback) {\r\n this._callback = function(buffer) {\r\n sFile.setBuffer(buffer);\r\n callback();\r\n };\r\n }\r\n else if (sFile) {\r\n this._callback = function(buffer) {\r\n sFile.setBuffer(buffer);\r\n };\r\n }\r\n };\r\n\r\n /**\r\n * Stop the recording. Once the recording is stopped,\r\n * the results will be sent to the p5.SoundFile that\r\n * was given on .record(), and if a callback function\r\n * was provided on record, that function will be called.\r\n *\r\n * @method stop\r\n * @for p5.SoundRecorder\r\n */\r\n p5.SoundRecorder.prototype.stop = function() {\r\n this._workletNode.port.postMessage({ name: 'stop' });\r\n };\r\n\r\n p5.SoundRecorder.prototype.dispose = function() {\r\n // remove reference from soundArray\r\n var index = p5sound.soundArray.indexOf(this);\r\n p5sound.soundArray.splice(index, 1);\r\n\r\n this._callback = function() {};\r\n if (this.input) {\r\n this.input.disconnect();\r\n }\r\n this.input = null;\r\n this._workletNode = null;\r\n };\r\n\r\n\r\n /**\r\n * Save a p5.SoundFile as a .wav file. The browser will prompt the user\r\n * to download the file to their device.\r\n * For uploading audio to a server, use\r\n * `p5.SoundFile.saveBlob`.\r\n *\r\n * @for p5\r\n * @method saveSound\r\n * @param {p5.SoundFile} soundFile p5.SoundFile that you wish to save\r\n * @param {String} fileName name of the resulting .wav file.\r\n */\r\n // add to p5.prototype as this is used by the p5 `save()` method.\r\n p5.prototype.saveSound = function (soundFile, fileName) {\r\n const dataView = convertToWav(soundFile.buffer);\r\n p5.prototype.writeFile([dataView], fileName, 'wav');\r\n };\r\n});\r\n","'use strict';\r\n\r\ndefine(function () {\r\n /**\r\n *
PeakDetect works in conjunction with p5.FFT to\r\n * look for onsets in some or all of the frequency spectrum.\r\n *
\r\n *
\r\n * To use p5.PeakDetect, call update in the draw loop\r\n * and pass in a p5.FFT object.\r\n *
\r\n *
\r\n * You can listen for a specific part of the frequency spectrum by\r\n * setting the range between freq1 and freq2.\r\n *
\r\n *\r\n *
threshold is the threshold for detecting a peak,\r\n * scaled between 0 and 1. It is logarithmic, so 0.1 is half as loud\r\n * as 1.0.
\r\n *\r\n *
\r\n * The update method is meant to be run in the draw loop, and\r\n * frames determines how many loops must pass before\r\n * another peak can be detected.\r\n * For example, if the frameRate() = 60, you could detect the beat of a\r\n * 120 beat-per-minute song with this equation:\r\n * framesPerPeak = 60 / (estimatedBPM / 60 );\r\n *
\r\n *\r\n *
\r\n * Based on example contribtued by @b2renger, and a simple beat detection\r\n * explanation by Felix Turner.\r\n *
\r\n *\r\n * @class p5.PeakDetect\r\n * @constructor\r\n * @param {Number} [freq1] lowFrequency - defaults to 20Hz\r\n * @param {Number} [freq2] highFrequency - defaults to 20000 Hz\r\n * @param {Number} [threshold] Threshold for detecting a beat between 0 and 1\r\n * scaled logarithmically where 0.1 is 1/2 the loudness\r\n * of 1.0. Defaults to 0.35.\r\n * @param {Number} [framesPerPeak] Defaults to 20.\r\n * @example\r\n *
\r\n */\r\n p5.PeakDetect = function(freq1, freq2, threshold, _framesPerPeak) {\r\n // framesPerPeak determines how often to look for a beat.\r\n // If a beat is provided, try to look for a beat based on bpm\r\n this.framesPerPeak = _framesPerPeak || 20;\r\n this.framesSinceLastPeak = 0;\r\n this.decayRate = 0.95;\r\n\r\n this.threshold = threshold || 0.35;\r\n this.cutoff = 0;\r\n\r\n // how much to increase the cutoff\r\n // TO DO: document this / figure out how to make it accessible\r\n this.cutoffMult = 1.5;\r\n\r\n this.energy = 0;\r\n this.penergy = 0;\r\n\r\n // TO DO: document this property / figure out how to make it accessible\r\n this.currentValue = 0;\r\n\r\n /**\r\n * isDetected is set to true when a peak is detected.\r\n *\r\n * @attribute isDetected {Boolean}\r\n * @default false\r\n */\r\n this.isDetected = false;\r\n\r\n this.f1 = freq1 || 40;\r\n this.f2 = freq2 || 20000;\r\n\r\n // function to call when a peak is detected\r\n this._onPeak = function() {};\r\n };\r\n\r\n\r\n /**\r\n * The update method is run in the draw loop.\r\n *\r\n * Accepts an FFT object. You must call .analyze()\r\n * on the FFT object prior to updating the peakDetect\r\n * because it relies on a completed FFT analysis.\r\n *\r\n * @method update\r\n * @param {p5.FFT} fftObject A p5.FFT object\r\n */\r\n p5.PeakDetect.prototype.update = function(fftObject) {\r\n var nrg = this.energy = fftObject.getEnergy(this.f1,this.f2)/255;\r\n if (nrg > this.cutoff && nrg > this.threshold && nrg-this.penergy > 0) {\r\n\r\n // trigger callback\r\n this._onPeak();\r\n this.isDetected = true;\r\n\r\n // debounce\r\n this.cutoff = nrg * this.cutoffMult;\r\n this.framesSinceLastPeak = 0;\r\n } else {\r\n this.isDetected = false;\r\n if (this.framesSinceLastPeak <= this.framesPerPeak) {\r\n this.framesSinceLastPeak++;\r\n } else {\r\n this.cutoff *= this.decayRate;\r\n this.cutoff = Math.max(this.cutoff, this.threshold);\r\n }\r\n }\r\n\r\n this.currentValue = nrg;\r\n this.penergy = nrg;\r\n };\r\n\r\n /**\r\n * onPeak accepts two arguments: a function to call when\r\n * a peak is detected. The value of the peak,\r\n * between 0.0 and 1.0, is passed to the callback.\r\n *\r\n * @method onPeak\r\n * @param {Function} callback Name of a function that will\r\n * be called when a peak is\r\n * detected.\r\n * @param {Object} [val] Optional value to pass\r\n * into the function when\r\n * a peak is detected.\r\n * @example\r\n *
\r\n * var cnv, soundFile, fft, peakDetect;\r\n * var ellipseWidth = 0;\r\n *\r\n * function preload() {\r\n * soundFile = loadSound('assets/beat.mp3');\r\n * }\r\n *\r\n * function setup() {\r\n * cnv = createCanvas(100,100);\r\n * textAlign(CENTER);\r\n *\r\n * fft = new p5.FFT();\r\n * peakDetect = new p5.PeakDetect();\r\n *\r\n * setupSound();\r\n *\r\n * // when a beat is detected, call triggerBeat()\r\n * peakDetect.onPeak(triggerBeat);\r\n * }\r\n *\r\n * function draw() {\r\n * background(0);\r\n * fill(255);\r\n * text('click to play', width/2, height/2);\r\n *\r\n * fft.analyze();\r\n * peakDetect.update(fft);\r\n *\r\n * ellipseWidth *= 0.95;\r\n * ellipse(width/2, height/2, ellipseWidth, ellipseWidth);\r\n * }\r\n *\r\n * // this function is called by peakDetect.onPeak\r\n * function triggerBeat() {\r\n * ellipseWidth = 50;\r\n * }\r\n *\r\n * // mouseclick starts/stops sound\r\n * function setupSound() {\r\n * cnv.mouseClicked( function() {\r\n * if (soundFile.isPlaying() ) {\r\n * soundFile.stop();\r\n * } else {\r\n * soundFile.play();\r\n * }\r\n * });\r\n * }\r\n *
\r\n */\r\n p5.PeakDetect.prototype.onPeak = function(callback, val) {\r\n var self = this;\r\n\r\n self._onPeak = function() {\r\n callback(self.energy, val);\r\n };\r\n };\r\n\r\n});\r\n","'use strict';\r\n\r\ndefine(function (require) {\r\n var p5sound = require('master');\r\n\r\n /**\r\n * A gain node is usefull to set the relative volume of sound.\r\n * It's typically used to build mixers.\r\n *\r\n * @class p5.Gain\r\n * @constructor\r\n * @example\r\n *
\r\n *\r\n * // load two soundfile and crossfade beetween them\r\n * var sound1,sound2;\r\n * var gain1, gain2, gain3;\r\n *\r\n * function preload(){\r\n * soundFormats('ogg', 'mp3');\r\n * sound1 = loadSound('assets/Damscray_-_Dancing_Tiger_01');\r\n * sound2 = loadSound('assets/beat.mp3');\r\n * }\r\n *\r\n * function setup() {\r\n * createCanvas(400,200);\r\n *\r\n * // create a 'master' gain to which we will connect both soundfiles\r\n * gain3 = new p5.Gain();\r\n * gain3.connect();\r\n *\r\n * // setup first sound for playing\r\n * sound1.rate(1);\r\n * sound1.loop();\r\n * sound1.disconnect(); // diconnect from p5 output\r\n *\r\n * gain1 = new p5.Gain(); // setup a gain node\r\n * gain1.setInput(sound1); // connect the first sound to its input\r\n * gain1.connect(gain3); // connect its output to the 'master'\r\n *\r\n * sound2.rate(1);\r\n * sound2.disconnect();\r\n * sound2.loop();\r\n *\r\n * gain2 = new p5.Gain();\r\n * gain2.setInput(sound2);\r\n * gain2.connect(gain3);\r\n *\r\n * }\r\n *\r\n * function draw(){\r\n * background(180);\r\n *\r\n * // calculate the horizontal distance beetween the mouse and the right of the screen\r\n * var d = dist(mouseX,0,width,0);\r\n *\r\n * // map the horizontal position of the mouse to values useable for volume control of sound1\r\n * var vol1 = map(mouseX,0,width,0,1);\r\n * var vol2 = 1-vol1; // when sound1 is loud, sound2 is quiet and vice versa\r\n *\r\n * gain1.amp(vol1,0.5,0);\r\n * gain2.amp(vol2,0.5,0);\r\n *\r\n * // map the vertical position of the mouse to values useable for 'master volume control'\r\n * var vol3 = map(mouseY,0,height,0,1);\r\n * gain3.amp(vol3,0.5,0);\r\n * }\r\n *
\r\n *\r\n */\r\n\r\n p5.Gain = function() {\r\n this.ac = p5sound.audiocontext;\r\n\r\n this.input = this.ac.createGain();\r\n this.output = this.ac.createGain();\r\n\r\n // otherwise, Safari distorts\r\n this.input.gain.value = 0.5;\r\n this.input.connect(this.output);\r\n\r\n // add to the soundArray\r\n p5sound.soundArray.push(this);\r\n };\r\n\r\n /**\r\n * Connect a source to the gain node.\r\n *\r\n * @method setInput\r\n * @for p5.Gain\r\n * @param {Object} src p5.sound / Web Audio object with a sound\r\n * output.\r\n */\r\n\r\n\r\n p5.Gain.prototype.setInput = function(src) {\r\n src.connect(this.input);\r\n };\r\n\r\n /**\r\n * Send output to a p5.sound or web audio object\r\n *\r\n * @method connect\r\n * @for p5.Gain\r\n * @param {Object} unit\r\n */\r\n p5.Gain.prototype.connect = function(unit) {\r\n var u = unit || p5.soundOut.input;\r\n this.output.connect(u.input ? u.input : u);\r\n };\r\n\r\n /**\r\n * Disconnect all output.\r\n *\r\n * @method disconnect\r\n * @for p5.Gain\r\n */\r\n p5.Gain.prototype.disconnect = function() {\r\n if (this.output) {\r\n this.output.disconnect();\r\n }\r\n };\r\n\r\n /**\r\n * Set the output level of the gain node.\r\n *\r\n * @method amp\r\n * @for p5.Gain\r\n * @param {Number} volume amplitude between 0 and 1.0\r\n * @param {Number} [rampTime] create a fade that lasts rampTime\r\n * @param {Number} [timeFromNow] schedule this event to happen\r\n * seconds from now\r\n */\r\n p5.Gain.prototype.amp = function(vol, rampTime, tFromNow) {\r\n var rampTime = rampTime || 0;\r\n var tFromNow = tFromNow || 0;\r\n var now = p5sound.audiocontext.currentTime;\r\n var currentVol = this.output.gain.value;\r\n this.output.gain.cancelScheduledValues(now);\r\n this.output.gain.linearRampToValueAtTime(currentVol, now + tFromNow);\r\n this.output.gain.linearRampToValueAtTime(vol, now + tFromNow + rampTime);\r\n };\r\n\r\n p5.Gain.prototype.dispose = function() {\r\n // remove reference from soundArray\r\n var index = p5sound.soundArray.indexOf(this);\r\n p5sound.soundArray.splice(index, 1);\r\n if (this.output) {\r\n this.output.disconnect();\r\n delete this.output;\r\n }\r\n if (this.input) {\r\n this.input.disconnect();\r\n delete this.input;\r\n }\r\n };\r\n\r\n});\r\n","'use strict';\r\n\r\ndefine(function (require) {\r\n\r\n var Effect = require('effect');\r\n\r\n /*\r\n * Adapted from [Kevin Ennis on StackOverflow](http://stackoverflow.com/questions/22312841/waveshaper-node-in-webaudio-how-to-emulate-distortion)\r\n */\r\n function makeDistortionCurve(amount) {\r\n var k = typeof amount === 'number' ? amount : 50;\r\n var numSamples = 44100;\r\n var curve = new Float32Array(numSamples);\r\n var deg = Math.PI / 180;\r\n var i = 0;\r\n var x;\r\n for ( ; i < numSamples; ++i ) {\r\n x = i * 2 / numSamples - 1;\r\n curve[i] = ( 3 + k ) * x * 20 * deg / ( Math.PI + k * Math.abs(x) );\r\n }\r\n return curve;\r\n }\r\n\r\n /**\r\n * A Distortion effect created with a Waveshaper Node,\r\n * with an approach adapted from\r\n * [Kevin Ennis](http://stackoverflow.com/questions/22312841/waveshaper-node-in-webaudio-how-to-emulate-distortion)\r\n *\r\n * This class extends p5.Effect.\r\n * Methods amp(), chain(),\r\n * drywet(), connect(), and\r\n * disconnect() are available.\r\n *\r\n * @class p5.Distortion\r\n * @extends p5.Effect\r\n * @constructor\r\n * @param {Number} [amount=0.25] Unbounded distortion amount.\r\n * Normal values range from 0-1.\r\n * @param {String} [oversample='none'] 'none', '2x', or '4x'.\r\n *\r\n */\r\n p5.Distortion = function(amount, oversample) {\r\n Effect.call(this);\r\n\r\n if (typeof amount === 'undefined') {\r\n amount = 0.25;\r\n } if (typeof amount !== 'number') {\r\n throw new Error('amount must be a number');\r\n } if (typeof oversample === 'undefined') {\r\n oversample = '2x';\r\n } if (typeof oversample !== 'string') {\r\n throw new Error('oversample must be a String');\r\n }\r\n\r\n var curveAmount = p5.prototype.map(amount, 0.0, 1.0, 0, 2000);\r\n\r\n /**\r\n * The p5.Distortion is built with a\r\n * \r\n * Web Audio WaveShaper Node.\r\n *\r\n * @property {AudioNode} WaveShaperNode\r\n */\r\n this.waveShaperNode = this.ac.createWaveShaper();\r\n\r\n this.amount = curveAmount;\r\n this.waveShaperNode.curve = makeDistortionCurve(curveAmount);\r\n this.waveShaperNode.oversample = oversample;\r\n\r\n this.input.connect(this.waveShaperNode);\r\n\r\n this.waveShaperNode.connect(this.wet);\r\n };\r\n\r\n p5.Distortion.prototype = Object.create(Effect.prototype);\r\n\r\n\r\n /**\r\n * Process a sound source, optionally specify amount and oversample values.\r\n *\r\n * @method process\r\n * @for p5.Distortion\r\n * @param {Number} [amount=0.25] Unbounded distortion amount.\r\n * Normal values range from 0-1.\r\n * @param {String} [oversample='none'] 'none', '2x', or '4x'.\r\n */\r\n p5.Distortion.prototype.process = function(src, amount, oversample) {\r\n src.connect(this.input);\r\n this.set(amount, oversample);\r\n };\r\n\r\n /**\r\n * Set the amount and oversample of the waveshaper distortion.\r\n *\r\n * @method set\r\n * @for p5.Distortion\r\n * @param {Number} [amount=0.25] Unbounded distortion amount.\r\n * Normal values range from 0-1.\r\n * @param {String} [oversample='none'] 'none', '2x', or '4x'.\r\n */\r\n p5.Distortion.prototype.set = function(amount, oversample) {\r\n if (amount) {\r\n var curveAmount = p5.prototype.map(amount, 0.0, 1.0, 0, 2000);\r\n this.amount = curveAmount;\r\n this.waveShaperNode.curve = makeDistortionCurve(curveAmount);\r\n }\r\n if (oversample) {\r\n this.waveShaperNode.oversample = oversample;\r\n }\r\n };\r\n\r\n /**\r\n * Return the distortion amount, typically between 0-1.\r\n *\r\n * @method getAmount\r\n * @for p5.Distortion\r\n * @return {Number} Unbounded distortion amount.\r\n * Normal values range from 0-1.\r\n */\r\n p5.Distortion.prototype.getAmount = function() {\r\n return this.amount;\r\n };\r\n\r\n /**\r\n * Return the oversampling.\r\n *\r\n * @method getOversample\r\n * @for p5.Distortion\r\n * @return {String} Oversample can either be 'none', '2x', or '4x'.\r\n */\r\n p5.Distortion.prototype.getOversample = function() {\r\n return this.waveShaperNode.oversample;\r\n };\r\n\r\n\r\n p5.Distortion.prototype.dispose = function() {\r\n Effect.prototype.dispose.apply(this);\r\n if (this.waveShaperNode) {\r\n this.waveShaperNode.disconnect();\r\n this.waveShaperNode = null;\r\n }\r\n };\r\n});\r\n","export default \"function _typeof(obj) { if (typeof Symbol === \\\"function\\\" && typeof Symbol.iterator === \\\"symbol\\\") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === \\\"function\\\" && obj.constructor === Symbol && obj !== Symbol.prototype ? \\\"symbol\\\" : typeof obj; }; } return _typeof(obj); }\\n\\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\\\"Cannot call a class as a function\\\"); } }\\n\\nfunction _possibleConstructorReturn(self, call) { if (call && (_typeof(call) === \\\"object\\\" || typeof call === \\\"function\\\")) { return call; } return _assertThisInitialized(self); }\\n\\nfunction _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError(\\\"this hasn't been initialised - super() hasn't been called\\\"); } return self; }\\n\\nfunction _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if (\\\"value\\\" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }\\n\\nfunction _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }\\n\\nfunction _inherits(subClass, superClass) { if (typeof superClass !== \\\"function\\\" && superClass !== null) { throw new TypeError(\\\"Super expression must either be null or a function\\\"); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, writable: true, configurable: true } }); if (superClass) _setPrototypeOf(subClass, superClass); }\\n\\nfunction _wrapNativeSuper(Class) { var _cache = typeof Map === \\\"function\\\" ? new Map() : undefined; _wrapNativeSuper = function _wrapNativeSuper(Class) { if (Class === null || !_isNativeFunction(Class)) return Class; if (typeof Class !== \\\"function\\\") { throw new TypeError(\\\"Super expression must either be null or a function\\\"); } if (typeof _cache !== \\\"undefined\\\") { if (_cache.has(Class)) return _cache.get(Class); _cache.set(Class, Wrapper); } function Wrapper() { return _construct(Class, arguments, _getPrototypeOf(this).constructor); } Wrapper.prototype = Object.create(Class.prototype, { constructor: { value: Wrapper, enumerable: false, writable: true, configurable: true } }); return _setPrototypeOf(Wrapper, Class); }; return _wrapNativeSuper(Class); }\\n\\nfunction isNativeReflectConstruct() { if (typeof Reflect === \\\"undefined\\\" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === \\\"function\\\") return true; try { Date.prototype.toString.call(Reflect.construct(Date, [], function () {})); return true; } catch (e) { return false; } }\\n\\nfunction _construct(Parent, args, Class) { if (isNativeReflectConstruct()) { _construct = Reflect.construct; } else { _construct = function _construct(Parent, args, Class) { var a = [null]; a.push.apply(a, args); var Constructor = Function.bind.apply(Parent, a); var instance = new Constructor(); if (Class) _setPrototypeOf(instance, Class.prototype); return instance; }; } return _construct.apply(null, arguments); }\\n\\nfunction _isNativeFunction(fn) { return Function.toString.call(fn).indexOf(\\\"[native code]\\\") !== -1; }\\n\\nfunction _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); }\\n\\nfunction _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); }; return _getPrototypeOf(o); }\\n\\n// import processor name via preval.require so that it's available as a value at compile time\\nvar processorNames = {\\n \\\"recorderProcessor\\\": \\\"recorder-processor\\\",\\n \\\"soundFileProcessor\\\": \\\"sound-file-processor\\\",\\n \\\"amplitudeProcessor\\\": \\\"amplitude-processor\\\"\\n}; // TO DO make this stereo / dependent on # of audio channels\\n\\nvar AmplitudeProcessor =\\n/*#__PURE__*/\\nfunction (_AudioWorkletProcesso) {\\n _inherits(AmplitudeProcessor, _AudioWorkletProcesso);\\n\\n _createClass(AmplitudeProcessor, null, [{\\n key: \\\"parameterDescriptors\\\",\\n get: function get() {\\n return [{\\n name: 'smoothing',\\n defaultValue: 0,\\n minValue: 0,\\n maxValue: 1,\\n automationRate: 'k-rate'\\n }];\\n }\\n }]);\\n\\n function AmplitudeProcessor(options) {\\n var _this;\\n\\n _classCallCheck(this, AmplitudeProcessor);\\n\\n _this = _possibleConstructorReturn(this, _getPrototypeOf(AmplitudeProcessor).call(this));\\n var processorOptions = options.processorOptions || {};\\n _this.normalize = processorOptions.normalize || false;\\n _this.stereoVol = [0, 0];\\n _this.stereoVolNorm = [0, 0];\\n _this.volMax = 0.001;\\n\\n _this.port.onmessage = function (event) {\\n var data = event.data;\\n\\n if (data.name === 'toggleNormalize') {\\n _this.normalize = data.normalize;\\n }\\n };\\n\\n return _this;\\n }\\n\\n _createClass(AmplitudeProcessor, [{\\n key: \\\"process\\\",\\n value: function process(inputs, outputs, parameters) {\\n var input = inputs[0];\\n var output = outputs[0];\\n var smoothing = parameters.smoothing;\\n\\n for (var channel = 0; channel < input.length; ++channel) {\\n var inputBuffer = input[channel];\\n var bufLength = inputBuffer.length;\\n var sum = 0;\\n\\n for (var i = 0; i < bufLength; i++) {\\n var x = inputBuffer[i];\\n\\n if (this.normalize) {\\n sum += Math.max(Math.min(x / this.volMax, 1), -1) * Math.max(Math.min(x / this.volMax, 1), -1);\\n } else {\\n sum += x * x;\\n }\\n } // ... then take the square root of the sum.\\n\\n\\n var rms = Math.sqrt(sum / bufLength);\\n this.stereoVol[channel] = Math.max(rms, this.stereoVol[channel] * smoothing);\\n this.volMax = Math.max(this.stereoVol[channel], this.volMax);\\n } // calculate stero normalized volume and add volume from all channels together\\n\\n\\n var volSum = 0;\\n\\n for (var index = 0; index < this.stereoVol.length; index++) {\\n this.stereoVolNorm[index] = Math.max(Math.min(this.stereoVol[index] / this.volMax, 1), 0);\\n volSum += this.stereoVol[index];\\n } // volume is average of channels\\n\\n\\n var volume = volSum / this.stereoVol.length; // normalized value\\n\\n var volNorm = Math.max(Math.min(volume / this.volMax, 1), 0);\\n this.port.postMessage({\\n name: 'amplitude',\\n volume: volume,\\n volNorm: volNorm,\\n stereoVol: this.stereoVol,\\n stereoVolNorm: this.stereoVolNorm\\n }); // pass input through to output\\n\\n for (var _channel = 0; _channel < output.length; ++_channel) {\\n output[_channel].set(input[_channel]);\\n }\\n\\n return true;\\n }\\n }]);\\n\\n return AmplitudeProcessor;\\n}(_wrapNativeSuper(AudioWorkletProcessor));\\n\\nregisterProcessor(processorNames.amplitudeProcessor, AmplitudeProcessor);\""],"sourceRoot":""}
\ No newline at end of file
+{"version":3,"sources":["webpack:///webpack/bootstrap","webpack:///../node_modules/tone/Tone/core/Tone.js","webpack:///./master.js","webpack:///../node_modules/tone/Tone/signal/Signal.js","webpack:///../node_modules/tone/Tone/signal/Multiply.js","webpack:///./effect.js","webpack:///../node_modules/tone/Tone/signal/WaveShaper.js","webpack:///./helpers.js","webpack:///../node_modules/tone/Tone/signal/Add.js","webpack:///../node_modules/tone/Tone/type/Type.js","webpack:///../node_modules/tone/Tone/core/Gain.js","webpack:///./errorHandler.js","webpack:///../node_modules/tone/Tone/core/Context.js","webpack:///./audioWorklet/processorNames.js","webpack:///../node_modules/tone/Tone/signal/Scale.js","webpack:///../node_modules/tone/Tone/signal/TimelineSignal.js","webpack:///./filter.js","webpack:///../node_modules/tone/Tone/signal/Subtract.js","webpack:///./audiocontext.js","webpack:///../node_modules/tone/Tone/core/Emitter.js","webpack:///../node_modules/tone/Tone/signal/SignalBase.js","webpack:///../node_modules/tone/Tone/type/Time.js","webpack:///../node_modules/tone/Tone/type/TimeBase.js","webpack:///../node_modules/tone/Tone/core/Param.js","webpack:///./oscillator.js","webpack:///../node_modules/tone/Tone/core/Timeline.js","webpack:///../node_modules/tone/Tone/signal/Negate.js","webpack:///../node_modules/tone/Tone/signal/GreaterThanZero.js","webpack:///../node_modules/tone/Tone/core/Clock.js","webpack:///./monosynth.js","webpack:///./audioVoice.js","webpack:///./polysynth.js","webpack:///./app.js","webpack:///../node_modules/audioworklet-polyfill/dist/audioworklet-polyfill.js","webpack:///./shims.js","webpack:///../node_modules/webpack/buildin/global.js","webpack:///../node_modules/startaudiocontext/StartAudioContext.js","webpack:///./audioWorklet/index.js","webpack:///./audioWorklet/recorderProcessor.js","webpack:///./audioWorklet/soundFileProcessor.js","webpack:///./audioWorklet/amplitudeProcessor.js","webpack:///./panner.js","webpack:///./soundfile.js","webpack:///./amplitude.js","webpack:///./fft.js","webpack:///./signal.js","webpack:///../node_modules/tone/Tone/type/Frequency.js","webpack:///../node_modules/tone/Tone/type/TransportTime.js","webpack:///./envelope.js","webpack:///./pulse.js","webpack:///./noise.js","webpack:///./audioin.js","webpack:///../node_modules/tone/Tone/component/CrossFade.js","webpack:///../node_modules/tone/Tone/signal/Expr.js","webpack:///../node_modules/tone/Tone/signal/GreaterThan.js","webpack:///../node_modules/tone/Tone/signal/Abs.js","webpack:///../node_modules/tone/Tone/signal/Modulo.js","webpack:///../node_modules/tone/Tone/signal/Pow.js","webpack:///../node_modules/tone/Tone/signal/AudioToGain.js","webpack:///../node_modules/tone/Tone/signal/EqualPowerGain.js","webpack:///./eq.js","webpack:///./eqFilter.js","webpack:///./panner3d.js","webpack:///./listener3d.js","webpack:///./delay.js","webpack:///./reverb.js","webpack:///./metro.js","webpack:///../node_modules/tone/Tone/core/TimelineState.js","webpack:///./looper.js","webpack:///./soundLoop.js","webpack:///./compressor.js","webpack:///./soundRecorder.js","webpack:///./peakDetect.js","webpack:///./gain.js","webpack:///./distortion.js"],"names":["installedModules","__webpack_require__","moduleId","exports","module","i","l","modules","call","m","c","d","name","getter","o","Object","defineProperty","enumerable","get","r","Symbol","toStringTag","value","t","mode","__esModule","ns","create","key","bind","n","object","property","prototype","hasOwnProperty","p","s","define","Tone","inputs","outputs","this","isUndef","input","context","createGain","Array","output","audioContext","set","params","rampTime","isObject","isString","tmpObj","paramLoop","attr","parent","indexOf","attrSplit","split","length","splice","innerParam","join","param","Signal","Param","rampTo","AudioParam","_collectDefaults","constructor","ret","subRet","j","subAttr","isFunction","constr","defaults","keys","_super","superDefs","push","toString","className","isLetter","match","sameConstructor","isArray","dispose","AudioNode","disconnect","connect","unit","outputNum","inputNum","defaultArg","destination","isNumber","apply","arguments","connectSeries","currentUnit","toUnit","chain","fan","given","fallback","givenProp","fallbackProp","optionsObject","values","options","val","arg","isBoolean","noOp","_readOnly","writable","_writable","State","Started","Stopped","Paused","equalPowerScale","percent","piFactor","Math","PI","sin","dbToGain","db","pow","gainToDb","gain","log","LN10","intervalToFrequencyRatio","interval","now","extend","child","TempConstructor","Context","emit","setContext","ctx","sampleRate","hasAudioContext","window","hasPromises","hasWorkers","version","TONE_SILENCE_VERSION_LOGGING","__WEBPACK_AMD_DEFINE_ARRAY__","__WEBPACK_AMD_DEFINE_RESULT__","undefined","audiocontext","p5sound","limiter","createDynamicsCompressor","threshold","ratio","knee","meter","fftMeter","soundArray","parts","extensions","p5","getMasterVolume","masterVolume","vol","tFromNow","currentTime","currentVol","cancelScheduledValues","linearRampToValueAtTime","soundOut","_silentNode","_gain","_param","getConstant","units","Type","Default","convert","SignalBase","Multiply","createInsOuts","_mult","Gain","require","CrossFade","Effect","ac","_drywet","wet","a","b","amp","drywet","fade","u","index","WaveShaper","mapping","bufferLen","_shaper","createWaveShaper","_curve","curve","isFinite","Float32Array","setMap","len","normalized","oversample","oversampling","RangeError","freqToMidi","f","mathlog2","round","midiToFreq","writeUTFBytes","view","offset","string","lng","setUint8","charCodeAt","soundFormats","toLowerCase","disposeSound","registerMethod","_checkFileFormats","paths","path","extTest","pop","isFileSupported","pathSplit","pathCore","extension","_typeof","_mathChain","math","thisChain","nextChain","type","mathOps","convertToWav","audioBuffer","leftChannel","interleaved","rightChannel","result","inputIndex","interleave","getChannelData","numberOfChannels","buffer","ArrayBuffer","DataView","setUint32","setUint16","setInt16","noteToFreq","note","A","B","C","D","E","F","G","toUpperCase","slice","Add","_sum","Time","Frequency","TransportTime","Ticks","NormalRange","AudioRange","Decibels","Interval","BPM","Positive","Cents","Degrees","MIDI","BarsBeatsSixteenths","Samples","Hertz","Note","Milliseconds","Seconds","Notation","toSeconds","time","TimeBase","toFrequency","freq","valueOf","toTicks","Transport","ticks","GainNode","AudioContext","createGainNode","_gainNode","errorTrace","failedPath","tempStack","splitStack","err","Error","originalStack","stack","filter","ln","toneConnect","outNum","inNum","nativeConnect","e","nativeDisconnect","webkitAudioContext","prop","Emitter","_context","_defineProperty","_latencyHint","_lookAhead","_updateInterval","_computedUpdateInterval","_worker","_createWorker","_constants","mixin","URL","webkitURL","blob","Blob","toFixed","blobUrl","createObjectURL","worker","Worker","addEventListener","_lastUpdate","diff","max","createBuffer","arr","constant","createBufferSource","channelCount","channelCountMode","loop","start","lA","blockTime","postMessage","hint","lookAhead","latencyHint","updateInterval","supported","recorderProcessor","soundFileProcessor","amplitudeProcessor","Scale","outputMin","outputMax","_outputMin","_outputMax","_scale","_add","_setRange","min","TimelineSignal","_events","Timeline","_initial","_fromUnits","Linear","Exponential","Target","Curve","Set","getValueAtTime","_toUnits","convertedVal","setValueAtTime","startTime","add","endTime","exponentialRampToValueAtTime","beforeEvent","_searchBefore","_minOutput","setValue","sampleTime","setTargetAtTime","timeConstant","setValueCurveAtTime","duration","scaling","floats","segmentTime","after","cancel","setRampPoint","before","_searchAfter","linearRampToValueBetween","finish","exponentialRampToValueBetween","getAfter","previouVal","previous","getBefore","_exponentialApproach","_curveInterpolate","_linearInterpolate","_exponentialInterpolate","t0","v0","v1","exp","t1","progress","lowerIndex","floor","upperIndex","ceil","lowerVal","upperVal","Filter","biquad","createBiquadFilter","setType","_on","_untoggledType","process","src","res","frequency","Q","toggle","LowPass","HighPass","BandPass","Subtract","_neg","Negate","global","StartAudioContext","getAudioContext","userStartAudio","elements","callback","elt","Element","map","on","event","events","eventName","off","ev","eventList","args","functions","func","emitterFunc","node","outputNumber","inputNumber","overridden","_plusNow","_unaryExpressions","quantize","regexp","method","rh","nextSubdivision","lh","subdiv","_expr","expr","subdivision","addNow","_defaultExpr","_noOp","copy","toNotation","retNotation","_toNotationHelper","retTripletNotation","testNotations","_notationToUnits","notationTime","multiple","notation","primaryExprs","_primaryExpressions","notationExprs","toBarsBeatsSixteenths","quarterTime","_beatsToUnits","quarters","measures","_timeSignature","sixteenths","parseFloat","PPQ","toSamples","toMilliseconds","_defaultUnits","exprString","_parseExprString","clone","instance","parseInt","_ticksToUnits","hz","_frequencyToUnits","tr","q","total","_secondsToUnits","samples","default","_binaryExpressions","+","precedence","-","*","/","neg","_syntaxGlue","(",")","_tokenize","position","tokens","token","getNextToken","trim","substr","expressions","group","opName","op","reg","SyntaxError","next","peek","_matchGroup","prec","test","_parseBinary","lexer","_parseUnary","_parsePrimary","matching","beats","bpm","seconds","timeSignature","_pushExpr","sub","mult","div","_lfo","lfo","LFO","currentVal","exponentialRampToValue","linearRampToValue","Mult","Oscillator","started","phaseAmount","oscillator","createOscillator","_freqMods","panPosition","connection","panner","Panner","stop","abs","freqNode","getAmp","isNaN","phase","getFreq","getType","oscMods","pan","pval","getPan","osc2","delayAmt","dNode","createDelay","delayTime","sigChain","mathObj","chainSource","num","scale","inMin","inMax","outMin","outMax","mapOutMin","mapOutMax","SinOsc","TriOsc","SawOsc","SqrOsc","_timeline","_toRemove","_iterating","memory","Infinity","_search","remove","shift","cancelBefore","beginning","end","midPoint","nextEvent","_iterate","lowerBound","upperBound","forEach","forEachBefore","forEachAfter","forEachFrom","forEachAtTime","_multiply","GreaterThanZero","_thresh","Clock","_nextTick","_lastState","_state","TimelineState","_boundLoop","_loop","state","setStateAtTime","pause","loopInterval","lag","currentState","tickTime","getStateAtTime","AudioVoice","MonoSynth","env","Envelope","setRange","setExp","setADSR","setInput","play","velocity","secondsFromNow","susTime","triggerAttack","triggerRelease","vel","ramp","attack","decay","sustain","release","defineProperties","aTime","dTime","sPercent","rTime","sustime","PolySynth","audioVoice","maxVoices","audiovoices","notes","_newest","_oldest","_voicesInUse","_allocateVoices","noteAttack","noteRelease","noteADSR","timeFromNow","voice","_note","_velocity","currentVoice","acTime","oldestNote","previousVal","_updateAfter","maxRange","nextTime","p5SOUND","parameters","bufferSize","fill","processor","realm","exec","inputBuffer","outputBuffer","$$processors","$$context","AudioWorkletNode","self","createScriptProcessor","outputChannelCount","Map","properties","defaultValue","MessageChannel","port2","Processor","port","port1","onaudioprocess","$$audioWorklet","AudioWorklet","addModule","fetch","then","ok","status","text","AudioWorkletProcessor","registerProcessor","parameterDescriptors","document","createElement","style","cssText","appendChild","contentWindow","createTextNode","body","$hook","console","documentElement","transpile","String","fixSetTarget","setTargetValueAtTime","createDelayNode","createJavaScriptNode","createPeriodicWave","createWaveTable","internal_createGain","internal_createDelay","maxDelayTime","internal_createBufferSource","internal_start","when","noteGrainOn","noteOn","internal_stop","noteOff","playbackRate","internal_createDynamicsCompressor","reduction","internal_createBiquadFilter","detune","internal_createOscillator","setPeriodicWave","setWaveTable","OfflineAudioContext","webkitOfflineAudioContext","navigator","getUserMedia","webkitGetUserMedia","mozGetUserMedia","msGetUserMedia","el","isSupported","canPlayType","g","Function","__WEBPACK_AMD_DEFINE_FACTORY__","TapListener","element","_dragged","_element","_bindedMove","_moved","_bindedEnd","_ended","isStarted","source","resume","startContext","removeEventListener","promise","Promise","success","checkLoop","requestAnimationFrame","onStarted","tapListeners","bindTapListener","NodeList","querySelectorAll","jquery","toArray","tap","moduleSources","preload","_preloadCount","onWorkletModulesLoad","_decrementPreload","all","moduleSrc","objectURL","audioWorklet","__webpack_exports__","createStereoPanner","stereoPanner","inputChannels","obj","numInputChannels","left","right","channelInterpretation","splitter","createChannelSplitter","createChannelMerger","v","rightVal","cos","leftVal","numChannels","CustomError","processorNames","SoundFile","onload","onerror","whileLoading","url","File","FileReader","FileList","file","_onended","_looping","_playing","_paused","_pauseTime","_cues","_cueIDCounter","_lastPos","_counterNode","_workletNode","bufferSourceNodes","bufferSourceNode","reversed","pauseTime","startMillis","load","_whileLoading","_clearOnEnd","thisBufferSourceNode","target","soundFile","registerPreloadMethod","loadSound","location","origin","cordova","alert","errorCallback","request","XMLHttpRequest","evt","_updateProgress","open","responseType","decodeAudioData","response","buff","msg","statusText","message","send","reader","readAsArrayBuffer","lengthComputable","percentComplete","loaded","isLoaded","rate","_cueStart","cueStart","cueEnd","setVolume","isPlaying","_initSourceNode","_initCounterNode","_arrayIndex","loopStart","loopEnd","playMode","str","pTime","setLoop","bool","isLooping","isPaused","stopAll","_time","_rampTime","_tFromNow","getVolume","reverse","reverseBuffer","setPitch","newPlaybackRate","getPlaybackRate","jump","cueTime","cTime","dur","channels","frames","getPeaks","width","sampleSize","sampleStep","peaks","chan","currentPos","curVol","onended","getLevel","setPath","setBuffer","buf","size","newBuffer","channelNum","cNode","onmessage","data","_onTimeUpdate","audioBuf","arrayBuffer","_createCounterBuffer","processPeaks","_initThreshold","_minThreshold","_minPeaks","bufLen","allPeaks","minThreshold","minPeaks","offlineContext","startRendering","oncomplete","filteredBuffer","renderedBuffer","bufferData","getPeaksAtThreshold","topTempos","intervalCounts","tempoCounts","intervalCount","theoreticalTempo","mapTempo","some","tempoCount","tempo","count","groupNeighborsByTempo","peaksObj","peaksArray","sort","startPeak","endPeak","startPos","sampleIndex","intervals","countIntervalsBetweenNearbyPeaks","intA","intB","tempoPeaks","bpmVariance","peaksAtTopTempo","peak","intervalBPM","peakTime","getPeaksAtTopTempo","Peak","amplitude","tempos","Cue","id","addCue","cue","removeCue","cueLength","clearCues","playbackTime","callbackTime","_prevTime","save","fileName","dataView","saveSound","getBlob","Amplitude","smoothing","processorOptions","normalize","volume","volNorm","stereoVol","stereoVolNorm","channel","toggleNormalize","smooth","FFT","bins","analyser","createAnalyser","fftSize","configurable","smoothingTimeConstant","freqDomain","Uint8Array","frequencyBinCount","timeDomain","bass","lowMid","mid","highMid","treble","waveform","_isSafari","timeToFloat","getFloatTimeDomainData","timeToInt","getByteTimeDomainData","normalArray","scaled","analyze","freqToFloat","getFloatFrequencyData","freqToInt","getByteFrequencyData","getEnergy","frequency1","frequency2","nyquist","swap","lowIndex","highIndex","numFrequencies","freq1","freq2","getCentroid","cumulative_sum","centroid_normalization","mean_freq_index","linAverages","N","spectrum","spectrumLength","spectrumStep","linearAverages","groupIndex","specIndex","logAverages","octaveBands","octaveIndex","hi","getOctaveBands","fCtr0","lastFrequencyBand","lo","ctr","newFrequencyBand","fft","_input","midi","midiToFrequency","pitch","octave","noteNumber","noteToScaleIndex","transpose","harmonize","toMidi","frequencyToMidi","toNote","A4","LN2","scaleIndexToNote","cbb","cb","c#","cx","dbb","d#","dx","ebb","eb","e#","ex","fbb","fb","f#","fx","gbb","gb","g#","gx","abb","ab","a#","ax","bbb","bb","b#","bx","_secondsToTicks","l1","t2","l2","t3","l3","aLevel","dLevel","rLevel","_rampHighPercentage","_rampLowPercentage","control","_init","isExponential","sourceToClear","wasTriggered","_setRampAD","_rampAttackTime","checkExpInput","_rampDecayTime","TCDenominator","_rampAttackTC","_rampDecayTC","setRampPercentages","p1","p2","isExp","lastAttack","valToSet","v2","destination1","destination2","AudioIn","Reverb","Noise","Delay","Env","createDCOffset","bufferSource","Pulse","w","dcOffset","dcGain","mW","sig","SignalAdd","mods","currentFreq","freqMod","assignType","_brownNoise","_pinkNoise","_whiteNoise","whiteBuffer","noiseData","random","b0","b1","b2","b3","b4","b5","b6","pinkBuffer","white","brownBuffer","lastOut","noise","inputSources","stream","mediaStream","currentSource","enabled","MediaStreamTrack","mediaDevices","successCallback","audioSource","constraints","audio","echoCancellation","deviceId","createMediaStreamSource","getTracks","track","getSources","onSuccess","onError","resolve","reject","enumerateDevices","devices","device","kind","error","setSource","active","initialFade","_equalPowerA","EqualPowerGain","_equalPowerB","_invert","Expr","applyBinary","Constructor","_eval","applyUnary","getNumber","literalNumber","_replacements","inputCount","_parseInputs","_nodes","tree","_parseTree","_disposeNodes","_Expressions","signal","glue",",","Abs","mod","modulus","Modulo","Pow","a2g","AudioToGain","binary","unary","!","NOT","inputArray","inputMax","replace","matchSyntax","syn","matchGroup","groupName","parseExpression","parseUnary","operator","parsePrimary","GreaterThan","_gtz","_abs","_subtract","_modSignal","_setWaveShaper","_exp","_expScaler","_expFunc","_norm","x","_eqPower","EQFilter","EQ","_eqsize","factor","bands","_newBand","Panner3D","createPanner","panningModel","distanceModel","xVal","yVal","zVal","positionX","positionY","positionZ","orient","orientX","orientY","orientZ","orientationX","orientationY","orientationZ","setFalloff","maxDistance","rolloffFactor","maxDist","rolloff","Listener3D","listener","xValF","yValF","zValF","xValU","yValU","zValU","orientForward","orientUp","forwardX","forwardY","forwardZ","upX","upY","upZ","_split","_merge","_leftGain","_rightGain","leftDelay","rightDelay","_leftFilter","_rightFilter","_maxDelay","maxValue","feedback","_delayTime","_feedback","_filter","_initConvolverNode","_seconds","_decay","_reverse","_buildImpulse","convolverNode","createConvolver","_teardownConvolverNode","_setBuffer","decayRate","rebuild","impulse","impulseL","impulseR","Convolver","impulses","_loadBuffer","cReverb","chunks","addImpulse","resetImpulse","toggleImpulse","Metro","clock","ontick","syncedParts","prevTick","tatumTime","tickCallback","elapsedTime","thisPart","incrementStep","phrases","thisPhrase","phraseArray","sequence","bNum","metroTicks","looping","setBPM","beatTime","tatums","getBPM","getRate","resetSync","part","pushSync","beatLength","initial","playNextPart","aScore","currentPart","scoreStep","Phrase","phraseStep","Part","steps","bLength","partStep","noLoop","metro","addPhrase","array","removePhrase","getPhrase","replaceSequence","onStep","Score","thisScore","nextPart","resetPart","resetParts","SoundLoop","musicalTimeMode","_interval","_bpm","maxIterations","iterations","_calcFreq","syncedStart","otherLoop","_update","_convertNotation","Number","_measure","timeSig","Compressor","compressor","number","SoundRecorder","_inputChannels","_outputChannels","buffers","leftBuffer","rightBuffer","_callback","record","sFile","writeFile","PeakDetect","_framesPerPeak","framesPerPeak","framesSinceLastPeak","cutoff","cutoffMult","energy","penergy","currentValue","isDetected","f1","f2","_onPeak","update","fftObject","nrg","onPeak","makeDistortionCurve","amount","k","deg","Distortion","curveAmount","waveShaperNode","getAmount","getOversample"],"mappings":"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","file":"p5.sound.min.js","sourcesContent":[" \t// The module cache\n \tvar installedModules = {};\n\n \t// The require function\n \tfunction __webpack_require__(moduleId) {\n\n \t\t// Check if module is in cache\n \t\tif(installedModules[moduleId]) {\n \t\t\treturn installedModules[moduleId].exports;\n \t\t}\n \t\t// Create a new module (and put it into the cache)\n \t\tvar module = installedModules[moduleId] = {\n \t\t\ti: moduleId,\n \t\t\tl: false,\n \t\t\texports: {}\n \t\t};\n\n \t\t// Execute the module function\n \t\tmodules[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n\n \t\t// Flag the module as loaded\n \t\tmodule.l = true;\n\n \t\t// Return the exports of the module\n \t\treturn module.exports;\n \t}\n\n\n \t// expose the modules object (__webpack_modules__)\n \t__webpack_require__.m = modules;\n\n \t// expose the module cache\n \t__webpack_require__.c = installedModules;\n\n \t// define getter function for harmony exports\n \t__webpack_require__.d = function(exports, name, getter) {\n \t\tif(!__webpack_require__.o(exports, name)) {\n \t\t\tObject.defineProperty(exports, name, { enumerable: true, get: getter });\n \t\t}\n \t};\n\n \t// define __esModule on exports\n \t__webpack_require__.r = function(exports) {\n \t\tif(typeof Symbol !== 'undefined' && Symbol.toStringTag) {\n \t\t\tObject.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });\n \t\t}\n \t\tObject.defineProperty(exports, '__esModule', { value: true });\n \t};\n\n \t// create a fake namespace object\n \t// mode & 1: value is a module id, require it\n \t// mode & 2: merge all properties of value into the ns\n \t// mode & 4: return value when already ns object\n \t// mode & 8|1: behave like require\n \t__webpack_require__.t = function(value, mode) {\n \t\tif(mode & 1) value = __webpack_require__(value);\n \t\tif(mode & 8) return value;\n \t\tif((mode & 4) && typeof value === 'object' && value && value.__esModule) return value;\n \t\tvar ns = Object.create(null);\n \t\t__webpack_require__.r(ns);\n \t\tObject.defineProperty(ns, 'default', { enumerable: true, value: value });\n \t\tif(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key));\n \t\treturn ns;\n \t};\n\n \t// getDefaultExport function for compatibility with non-harmony modules\n \t__webpack_require__.n = function(module) {\n \t\tvar getter = module && module.__esModule ?\n \t\t\tfunction getDefault() { return module['default']; } :\n \t\t\tfunction getModuleExports() { return module; };\n \t\t__webpack_require__.d(getter, 'a', getter);\n \t\treturn getter;\n \t};\n\n \t// Object.prototype.hasOwnProperty.call\n \t__webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };\n\n \t// __webpack_public_path__\n \t__webpack_require__.p = \"\";\n\n\n \t// Load entry module and return exports\n \treturn __webpack_require__(__webpack_require__.s = 31);\n","/**\n * Tone.js\n * @author Yotam Mann\n * @license http://opensource.org/licenses/MIT MIT License\n * @copyright 2014-2017 Yotam Mann\n */\ndefine(function(){\n\n\t\"use strict\";\n\n\t///////////////////////////////////////////////////////////////////////////\n\t//\tTONE\n\t///////////////////////////////////////////////////////////////////////////\n\n\t/**\n\t * @class Tone is the base class of all other classes. It provides \n\t * a lot of methods and functionality to all classes that extend\n\t * it. \n\t * \n\t * @constructor\n\t * @alias Tone\n\t * @param {number} [inputs=1] the number of input nodes\n\t * @param {number} [outputs=1] the number of output nodes\n\t */\n\tvar Tone = function(inputs, outputs){\n\n\t\t/**\n\t\t * the input node(s)\n\t\t * @type {GainNode|Array}\n\t\t */\n\t\tif (this.isUndef(inputs) || inputs === 1){\n\t\t\tthis.input = this.context.createGain();\n\t\t} else if (inputs > 1){\n\t\t\tthis.input = new Array(inputs);\n\t\t}\n\n\t\t/**\n\t\t * the output node(s)\n\t\t * @type {GainNode|Array}\n\t\t */\n\t\tif (this.isUndef(outputs) || outputs === 1){\n\t\t\tthis.output = this.context.createGain();\n\t\t} else if (outputs > 1){\n\t\t\tthis.output = new Array(inputs);\n\t\t}\n\t};\n\n\t/**\n\t * Set the parameters at once. Either pass in an\n\t * object mapping parameters to values, or to set a\n\t * single parameter, by passing in a string and value.\n\t * The last argument is an optional ramp time which \n\t * will ramp any signal values to their destination value\n\t * over the duration of the rampTime.\n\t * @param {Object|string} params\n\t * @param {number=} value\n\t * @param {Time=} rampTime\n\t * @returns {Tone} this\n\t * @example\n\t * //set values using an object\n\t * filter.set({\n\t * \t\"frequency\" : 300,\n\t * \t\"type\" : highpass\n\t * });\n\t * @example\n\t * filter.set(\"type\", \"highpass\");\n\t * @example\n\t * //ramp to the value 220 over 3 seconds. \n\t * oscillator.set({\n\t * \t\"frequency\" : 220\n\t * }, 3);\n\t */\n\tTone.prototype.set = function(params, value, rampTime){\n\t\tif (this.isObject(params)){\n\t\t\trampTime = value;\n\t\t} else if (this.isString(params)){\n\t\t\tvar tmpObj = {};\n\t\t\ttmpObj[params] = value;\n\t\t\tparams = tmpObj;\n\t\t}\n\n\t\tparamLoop:\n\t\tfor (var attr in params){\n\t\t\tvalue = params[attr];\n\t\t\tvar parent = this;\n\t\t\tif (attr.indexOf(\".\") !== -1){\n\t\t\t\tvar attrSplit = attr.split(\".\");\n\t\t\t\tfor (var i = 0; i < attrSplit.length - 1; i++){\n\t\t\t\t\tparent = parent[attrSplit[i]];\n\t\t\t\t\tif (parent instanceof Tone) {\n\t\t\t\t\t\tattrSplit.splice(0,i+1);\n\t\t\t\t\t\tvar innerParam = attrSplit.join(\".\");\n\t\t\t\t\t\tparent.set(innerParam, value);\n\t\t\t\t\t\tcontinue paramLoop;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tattr = attrSplit[attrSplit.length - 1];\n\t\t\t}\n\t\t\tvar param = parent[attr];\n\t\t\tif (this.isUndef(param)){\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tif ((Tone.Signal && param instanceof Tone.Signal) || \n\t\t\t\t\t(Tone.Param && param instanceof Tone.Param)){\n\t\t\t\tif (param.value !== value){\n\t\t\t\t\tif (this.isUndef(rampTime)){\n\t\t\t\t\t\tparam.value = value;\n\t\t\t\t\t} else {\n\t\t\t\t\t\tparam.rampTo(value, rampTime);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} else if (param instanceof AudioParam){\n\t\t\t\tif (param.value !== value){\n\t\t\t\t\tparam.value = value;\n\t\t\t\t}\t\t\t\t\n\t\t\t} else if (param instanceof Tone){\n\t\t\t\tparam.set(value);\n\t\t\t} else if (param !== value){\n\t\t\t\tparent[attr] = value;\n\t\t\t}\n\t\t}\n\t\treturn this;\n\t};\n\n\t/**\n\t * Get the object's attributes. Given no arguments get\n\t * will return all available object properties and their corresponding\n\t * values. Pass in a single attribute to retrieve or an array\n\t * of attributes. The attribute strings can also include a \".\"\n\t * to access deeper properties.\n\t * @example\n\t * osc.get();\n\t * //returns {\"type\" : \"sine\", \"frequency\" : 440, ...etc}\n\t * @example\n\t * osc.get(\"type\");\n\t * //returns { \"type\" : \"sine\"}\n\t * @example\n\t * //use dot notation to access deep properties\n\t * synth.get([\"envelope.attack\", \"envelope.release\"]);\n\t * //returns {\"envelope\" : {\"attack\" : 0.2, \"release\" : 0.4}}\n\t * @param {Array=|string|undefined} params the parameters to get, otherwise will return \n\t * \t\t\t\t\t all available.\n\t * @returns {Object}\n\t */\n\tTone.prototype.get = function(params){\n\t\tif (this.isUndef(params)){\n\t\t\tparams = this._collectDefaults(this.constructor);\n\t\t} else if (this.isString(params)){\n\t\t\tparams = [params];\n\t\t} \n\t\tvar ret = {};\n\t\tfor (var i = 0; i < params.length; i++){\n\t\t\tvar attr = params[i];\n\t\t\tvar parent = this;\n\t\t\tvar subRet = ret;\n\t\t\tif (attr.indexOf(\".\") !== -1){\n\t\t\t\tvar attrSplit = attr.split(\".\");\n\t\t\t\tfor (var j = 0; j < attrSplit.length - 1; j++){\n\t\t\t\t\tvar subAttr = attrSplit[j];\n\t\t\t\t\tsubRet[subAttr] = subRet[subAttr] || {};\n\t\t\t\t\tsubRet = subRet[subAttr];\n\t\t\t\t\tparent = parent[subAttr];\n\t\t\t\t}\n\t\t\t\tattr = attrSplit[attrSplit.length - 1];\n\t\t\t}\n\t\t\tvar param = parent[attr];\n\t\t\tif (this.isObject(params[attr])){\n\t\t\t\tsubRet[attr] = param.get();\n\t\t\t} else if (Tone.Signal && param instanceof Tone.Signal){\n\t\t\t\tsubRet[attr] = param.value;\n\t\t\t} else if (Tone.Param && param instanceof Tone.Param){\n\t\t\t\tsubRet[attr] = param.value;\n\t\t\t} else if (param instanceof AudioParam){\n\t\t\t\tsubRet[attr] = param.value;\n\t\t\t} else if (param instanceof Tone){\n\t\t\t\tsubRet[attr] = param.get();\n\t\t\t} else if (!this.isFunction(param) && !this.isUndef(param)){\n\t\t\t\tsubRet[attr] = param;\n\t\t\t} \n\t\t}\n\t\treturn ret;\n\t};\n\n\t/**\n\t * collect all of the default attributes in one\n\t * @private\n\t * @param {function} constr the constructor to find the defaults from\n\t * @return {Array} all of the attributes which belong to the class\n\t */\n\tTone.prototype._collectDefaults = function(constr){\n\t\tvar ret = [];\n\t\tif (!this.isUndef(constr.defaults)){\n\t\t\tret = Object.keys(constr.defaults);\n\t\t}\n\t\tif (!this.isUndef(constr._super)){\n\t\t\tvar superDefs = this._collectDefaults(constr._super);\n\t\t\t//filter out repeats\n\t\t\tfor (var i = 0; i < superDefs.length; i++){\n\t\t\t\tif (ret.indexOf(superDefs[i]) === -1){\n\t\t\t\t\tret.push(superDefs[i]);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\treturn ret;\n\t};\n\n\t/**\n\t * @returns {string} returns the name of the class as a string\n\t */\n\tTone.prototype.toString = function(){\n\t\tfor (var className in Tone){\n\t\t\tvar isLetter = className[0].match(/^[A-Z]$/);\n\t\t\tvar sameConstructor = Tone[className] === this.constructor;\n\t\t\tif (this.isFunction(Tone[className]) && isLetter && sameConstructor){\n\t\t\t\treturn className;\n\t\t\t}\n\t\t}\n\t\treturn \"Tone\";\n\t};\n\n\t///////////////////////////////////////////////////////////////////////////\n\t//\tCLASS VARS\n\t///////////////////////////////////////////////////////////////////////////\n\n\t/**\n\t * The number of inputs feeding into the AudioNode. \n\t * For source nodes, this will be 0.\n\t * @memberOf Tone#\n\t * @name numberOfInputs\n\t * @readOnly\n\t */\n\tObject.defineProperty(Tone.prototype, \"numberOfInputs\", {\n\t\tget : function(){\n\t\t\tif (this.input){\n\t\t\t\tif (this.isArray(this.input)){\n\t\t\t\t\treturn this.input.length;\n\t\t\t\t} else {\n\t\t\t\t\treturn 1;\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\treturn 0;\n\t\t\t}\n\t\t}\n\t});\n\n\t/**\n\t * The number of outputs coming out of the AudioNode. \n\t * For source nodes, this will be 0.\n\t * @memberOf Tone#\n\t * @name numberOfInputs\n\t * @readOnly\n\t */\n\tObject.defineProperty(Tone.prototype, \"numberOfOutputs\", {\n\t\tget : function(){\n\t\t\tif (this.output){\n\t\t\t\tif (this.isArray(this.output)){\n\t\t\t\t\treturn this.output.length;\n\t\t\t\t} else {\n\t\t\t\t\treturn 1;\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\treturn 0;\n\t\t\t}\n\t\t}\n\t});\n\t\n\t///////////////////////////////////////////////////////////////////////////\n\t//\tCONNECTIONS\n\t///////////////////////////////////////////////////////////////////////////\n\n\t/**\n\t * disconnect and dispose\n\t * @returns {Tone} this\n\t */\n\tTone.prototype.dispose = function(){\n\t\tif (!this.isUndef(this.input)){\n\t\t\tif (this.input instanceof AudioNode){\n\t\t\t\tthis.input.disconnect();\n\t\t\t} \n\t\t\tthis.input = null;\n\t\t}\n\t\tif (!this.isUndef(this.output)){\n\t\t\tif (this.output instanceof AudioNode){\n\t\t\t\tthis.output.disconnect();\n\t\t\t} \n\t\t\tthis.output = null;\n\t\t}\n\t\treturn this;\n\t};\n\n\t/**\n\t * connect the output of a ToneNode to an AudioParam, AudioNode, or ToneNode\n\t * @param {Tone | AudioParam | AudioNode} unit \n\t * @param {number} [outputNum=0] optionally which output to connect from\n\t * @param {number} [inputNum=0] optionally which input to connect to\n\t * @returns {Tone} this\n\t */\n\tTone.prototype.connect = function(unit, outputNum, inputNum){\n\t\tif (Array.isArray(this.output)){\n\t\t\toutputNum = this.defaultArg(outputNum, 0);\n\t\t\tthis.output[outputNum].connect(unit, 0, inputNum);\n\t\t} else {\n\t\t\tthis.output.connect(unit, outputNum, inputNum);\n\t\t}\n\t\treturn this;\n\t};\n\n\t/**\n\t * disconnect the output\n\t * @param {Number|AudioNode} output Either the output index to disconnect\n\t * if the output is an array, or the\n\t * node to disconnect from.\n\t * @returns {Tone} this\n\t */\n\tTone.prototype.disconnect = function(destination, outputNum, inputNum){\n\t\tif (this.isArray(this.output)){\n\t\t\tif (this.isNumber(destination)){\n\t\t\t\tthis.output[destination].disconnect();\n\t\t\t} else {\n\t\t\t\toutputNum = this.defaultArg(outputNum, 0);\n\t\t\t\tthis.output[outputNum].disconnect(destination, 0, inputNum);\n\t\t\t}\n\t\t} else {\n\t\t\tthis.output.disconnect.apply(this.output, arguments);\n\t\t}\n\t};\n\n\t/**\n\t * connect together all of the arguments in series\n\t * @param {...AudioParam|Tone|AudioNode} nodes\n\t * @returns {Tone} this\n\t */\n\tTone.prototype.connectSeries = function(){\n\t\tif (arguments.length > 1){\n\t\t\tvar currentUnit = arguments[0];\n\t\t\tfor (var i = 1; i < arguments.length; i++){\n\t\t\t\tvar toUnit = arguments[i];\n\t\t\t\tcurrentUnit.connect(toUnit);\n\t\t\t\tcurrentUnit = toUnit;\n\t\t\t}\n\t\t}\n\t\treturn this;\n\t};\n\n\t/**\n\t * Connect the output of this node to the rest of the nodes in series.\n\t * @example\n\t * //connect a node to an effect, panVol and then to the master output\n\t * node.chain(effect, panVol, Tone.Master);\n\t * @param {...AudioParam|Tone|AudioNode} nodes\n\t * @returns {Tone} this\n\t */\n\tTone.prototype.chain = function(){\n\t\tif (arguments.length > 0){\n\t\t\tvar currentUnit = this;\n\t\t\tfor (var i = 0; i < arguments.length; i++){\n\t\t\t\tvar toUnit = arguments[i];\n\t\t\t\tcurrentUnit.connect(toUnit);\n\t\t\t\tcurrentUnit = toUnit;\n\t\t\t}\n\t\t}\n\t\treturn this;\n\t};\n\n\t/**\n\t * connect the output of this node to the rest of the nodes in parallel.\n\t * @param {...AudioParam|Tone|AudioNode} nodes\n\t * @returns {Tone} this\n\t */\n\tTone.prototype.fan = function(){\n\t\tif (arguments.length > 0){\n\t\t\tfor (var i = 0; i < arguments.length; i++){\n\t\t\t\tthis.connect(arguments[i]);\n\t\t\t}\n\t\t}\n\t\treturn this;\n\t};\n\n\t//give native nodes chain and fan methods\n\tAudioNode.prototype.chain = Tone.prototype.chain;\n\tAudioNode.prototype.fan = Tone.prototype.fan;\n\n\t///////////////////////////////////////////////////////////////////////////\n\t//\tUTILITIES / HELPERS / MATHS\n\t///////////////////////////////////////////////////////////////////////////\n\n\t/**\n\t * If the `given` parameter is undefined, use the `fallback`. \n\t * If both `given` and `fallback` are object literals, it will\n\t * return a deep copy which includes all of the parameters from both \n\t * objects. If a parameter is undefined in given, it will return\n\t * the fallback property. \n\t *
\n\t * WARNING: if object is self referential, it will go into an an \n\t * infinite recursive loop.\n\t * \n\t * @param {*} given \n\t * @param {*} fallback \n\t * @return {*} \n\t */\n\tTone.prototype.defaultArg = function(given, fallback){\n\t\tif (this.isObject(given) && this.isObject(fallback)){\n\t\t\tvar ret = {};\n\t\t\t//make a deep copy of the given object\n\t\t\tfor (var givenProp in given) {\n\t\t\t\tret[givenProp] = this.defaultArg(fallback[givenProp], given[givenProp]);\n\t\t\t}\n\t\t\tfor (var fallbackProp in fallback) {\n\t\t\t\tret[fallbackProp] = this.defaultArg(given[fallbackProp], fallback[fallbackProp]);\n\t\t\t}\n\t\t\treturn ret;\n\t\t} else {\n\t\t\treturn this.isUndef(given) ? fallback : given;\n\t\t}\n\t};\n\n\t/**\n\t * returns the args as an options object with given arguments\n\t * mapped to the names provided. \n\t *\n\t * if the args given is an array containing only one object, it is assumed\n\t * that that's already the options object and will just return it. \n\t * \n\t * @param {Array} values the 'arguments' object of the function\n\t * @param {Array} keys the names of the arguments as they\n\t * should appear in the options object\n\t * @param {Object=} defaults optional defaults to mixin to the returned \n\t * options object \n\t * @return {Object} the options object with the names mapped to the arguments\n\t */\n\tTone.prototype.optionsObject = function(values, keys, defaults){\n\t\tvar options = {};\n\t\tif (values.length === 1 && this.isObject(values[0])){\n\t\t\toptions = values[0];\n\t\t} else {\n\t\t\tfor (var i = 0; i < keys.length; i++){\n\t\t\t\toptions[keys[i]] = values[i];\n\t\t\t}\n\t\t}\n\t\tif (!this.isUndef(defaults)){\n\t\t\treturn this.defaultArg(options, defaults);\n\t\t} else {\n\t\t\treturn options;\n\t\t}\n\t};\n\n\t///////////////////////////////////////////////////////////////////////////\n\t// TYPE CHECKING\n\t///////////////////////////////////////////////////////////////////////////\n\n\t/**\n\t * test if the arg is undefined\n\t * @param {*} arg the argument to test\n\t * @returns {boolean} true if the arg is undefined\n\t * @function\n\t */\n\tTone.prototype.isUndef = function(val){\n\t\treturn typeof val === \"undefined\";\n\t};\n\n\t/**\n\t * test if the arg is a function\n\t * @param {*} arg the argument to test\n\t * @returns {boolean} true if the arg is a function\n\t * @function\n\t */\n\tTone.prototype.isFunction = function(val){\n\t\treturn typeof val === \"function\";\n\t};\n\n\t/**\n\t * Test if the argument is a number.\n\t * @param {*} arg the argument to test\n\t * @returns {boolean} true if the arg is a number\n\t */\n\tTone.prototype.isNumber = function(arg){\n\t\treturn (typeof arg === \"number\");\n\t};\n\n\t/**\n\t * Test if the given argument is an object literal (i.e. `{}`);\n\t * @param {*} arg the argument to test\n\t * @returns {boolean} true if the arg is an object literal.\n\t */\n\tTone.prototype.isObject = function(arg){\n\t\treturn (Object.prototype.toString.call(arg) === \"[object Object]\" && arg.constructor === Object);\n\t};\n\n\t/**\n\t * Test if the argument is a boolean.\n\t * @param {*} arg the argument to test\n\t * @returns {boolean} true if the arg is a boolean\n\t */\n\tTone.prototype.isBoolean = function(arg){\n\t\treturn (typeof arg === \"boolean\");\n\t};\n\n\t/**\n\t * Test if the argument is an Array\n\t * @param {*} arg the argument to test\n\t * @returns {boolean} true if the arg is an array\n\t */\n\tTone.prototype.isArray = function(arg){\n\t\treturn (Array.isArray(arg));\n\t};\n\n\t/**\n\t * Test if the argument is a string.\n\t * @param {*} arg the argument to test\n\t * @returns {boolean} true if the arg is a string\n\t */\n\tTone.prototype.isString = function(arg){\n\t\treturn (typeof arg === \"string\");\n\t};\n\n \t/**\n\t * An empty function.\n\t * @static\n\t */\n\tTone.noOp = function(){};\n\n\t/**\n\t * Make the property not writable. Internal use only. \n\t * @private\n\t * @param {string} property the property to make not writable\n\t */\n\tTone.prototype._readOnly = function(property){\n\t\tif (Array.isArray(property)){\n\t\t\tfor (var i = 0; i < property.length; i++){\n\t\t\t\tthis._readOnly(property[i]);\n\t\t\t}\n\t\t} else {\n\t\t\tObject.defineProperty(this, property, { \n\t\t\t\twritable: false,\n\t\t\t\tenumerable : true,\n\t\t\t});\n\t\t}\n\t};\n\n\t/**\n\t * Make an attribute writeable. Interal use only. \n\t * @private\n\t * @param {string} property the property to make writable\n\t */\n\tTone.prototype._writable = function(property){\n\t\tif (Array.isArray(property)){\n\t\t\tfor (var i = 0; i < property.length; i++){\n\t\t\t\tthis._writable(property[i]);\n\t\t\t}\n\t\t} else {\n\t\t\tObject.defineProperty(this, property, { \n\t\t\t\twritable: true,\n\t\t\t});\n\t\t}\n\t};\n\n\t/**\n\t * Possible play states. \n\t * @enum {string}\n\t */\n\tTone.State = {\n\t\tStarted : \"started\",\n\t\tStopped : \"stopped\",\n\t\tPaused : \"paused\",\n \t};\n\n\t///////////////////////////////////////////////////////////////////////////\n\t// CONVERSIONS\n\t///////////////////////////////////////////////////////////////////////////\n\n\t/**\n\t * Equal power gain scale. Good for cross-fading.\n\t * @param {NormalRange} percent (0-1)\n\t * @return {Number} output gain (0-1)\n\t */\n\tTone.prototype.equalPowerScale = function(percent){\n\t\tvar piFactor = 0.5 * Math.PI;\n\t\treturn Math.sin(percent * piFactor);\n\t};\n\n\t/**\n\t * Convert decibels into gain.\n\t * @param {Decibels} db\n\t * @return {Number} \n\t */\n\tTone.prototype.dbToGain = function(db) {\n\t\treturn Math.pow(2, db / 6);\n\t};\n\n\t/**\n\t * Convert gain to decibels.\n\t * @param {Number} gain (0-1)\n\t * @return {Decibels} \n\t */\n\tTone.prototype.gainToDb = function(gain) {\n\t\treturn 20 * (Math.log(gain) / Math.LN10);\n\t};\n\n\t/**\n\t * Convert an interval (in semitones) to a frequency ratio.\n\t * @param {Interval} interval the number of semitones above the base note\n\t * @return {number} the frequency ratio\n\t * @example\n\t * tone.intervalToFrequencyRatio(0); // 1\n\t * tone.intervalToFrequencyRatio(12); // 2\n\t * tone.intervalToFrequencyRatio(-12); // 0.5\n\t */\n\tTone.prototype.intervalToFrequencyRatio = function(interval){\n\t\treturn Math.pow(2,(interval/12));\n\t};\n\n\t///////////////////////////////////////////////////////////////////////////\n\t//\tTIMING\n\t///////////////////////////////////////////////////////////////////////////\n\n\t/**\n\t * Return the current time of the AudioContext clock.\n\t * @return {Number} the currentTime from the AudioContext\n\t */\n\tTone.prototype.now = function(){\n\t\treturn Tone.context.now();\n\t};\n\n\t/**\n\t * Return the current time of the AudioContext clock.\n\t * @return {Number} the currentTime from the AudioContext\n\t * @static\n\t */\n\tTone.now = function(){\n\t\treturn Tone.context.now();\n\t};\n\n\t///////////////////////////////////////////////////////////////////////////\n\t//\tINHERITANCE\n\t///////////////////////////////////////////////////////////////////////////\n\n\t/**\n\t * have a child inherit all of Tone's (or a parent's) prototype\n\t * to inherit the parent's properties, make sure to call \n\t * Parent.call(this) in the child's constructor\n\t *\n\t * based on closure library's inherit function\n\t *\n\t * @static\n\t * @param {function} \tchild \n\t * @param {function=} parent (optional) parent to inherit from\n\t * if no parent is supplied, the child\n\t * will inherit from Tone\n\t */\n\tTone.extend = function(child, parent){\n\t\tif (Tone.prototype.isUndef(parent)){\n\t\t\tparent = Tone;\n\t\t}\n\t\tfunction TempConstructor(){}\n\t\tTempConstructor.prototype = parent.prototype;\n\t\tchild.prototype = new TempConstructor();\n\t\t/** @override */\n\t\tchild.prototype.constructor = child;\n\t\tchild._super = parent;\n\t};\n\n\t///////////////////////////////////////////////////////////////////////////\n\t//\tCONTEXT\n\t///////////////////////////////////////////////////////////////////////////\n\n\t/**\n\t * The private audio context shared by all Tone Nodes. \n\t * @private\n\t * @type {Tone.Context|undefined}\n\t */\n\tvar audioContext;\n\n\t/**\n\t * A static pointer to the audio context accessible as Tone.context. \n\t * @type {Tone.Context}\n\t * @name context\n\t * @memberOf Tone\n\t */\n\tObject.defineProperty(Tone, \"context\", {\n\t\tget : function(){\n\t\t\treturn audioContext;\n\t\t},\n\t\tset : function(context){\n\t\t\tif (Tone.Context && context instanceof Tone.Context){\n\t\t\t\taudioContext = context;\n\t\t\t} else {\n\t\t\t\taudioContext = new Tone.Context(context);\n\t\t\t}\n\t\t\t//initialize the new audio context\n\t\t\tif (Tone.Context){\n\t\t\t\tTone.Context.emit(\"init\", audioContext);\n\t\t\t}\n\t\t}\n\t});\n\n\t/**\n\t * The AudioContext\n\t * @type {Tone.Context}\n\t * @name context\n\t * @memberOf Tone#\n\t * @readOnly\n\t */\n\tObject.defineProperty(Tone.prototype, \"context\", {\n\t\tget : function(){\n\t\t\treturn Tone.context;\n\t\t}\n\t});\n\n\t/**\n\t * Tone automatically creates a context on init, but if you are working\n\t * with other libraries which also create an AudioContext, it can be\n\t * useful to set your own. If you are going to set your own context, \n\t * be sure to do it at the start of your code, before creating any objects.\n\t * @static\n\t * @param {AudioContext} ctx The new audio context to set\n\t */\n\tTone.setContext = function(ctx){\n\t\tTone.context = ctx;\n\t};\n\n\t/**\n\t * The number of seconds of 1 processing block (128 samples)\n\t * @type {Number}\n\t * @name blockTime\n\t * @memberOf Tone#\n\t * @readOnly\n\t */\n\tObject.defineProperty(Tone.prototype, \"blockTime\", {\n\t\tget : function(){\n\t\t\treturn 128 / this.context.sampleRate;\n\t\t}\n\t});\n\n\t/**\n\t * The duration in seconds of one sample.\n\t * @type {Number}\n\t * @name sampleTime\n\t * @memberOf Tone#\n\t * @readOnly\n\t */\n\tObject.defineProperty(Tone.prototype, \"sampleTime\", {\n\t\tget : function(){\n\t\t\treturn 1 / this.context.sampleRate;\n\t\t}\n\t});\n\n\t/**\n\t * Whether or not all the technologies that Tone.js relies on are supported by the current browser. \n\t * @type {Boolean}\n\t * @name supported\n\t * @memberOf Tone\n\t * @readOnly\n\t */\n\tObject.defineProperty(Tone, \"supported\", {\n\t\tget : function(){\n\t\t\tvar hasAudioContext = window.hasOwnProperty(\"AudioContext\") || window.hasOwnProperty(\"webkitAudioContext\");\n\t\t\tvar hasPromises = window.hasOwnProperty(\"Promise\");\n\t\t\tvar hasWorkers = window.hasOwnProperty(\"Worker\");\n\t\t\treturn hasAudioContext && hasPromises && hasWorkers;\n\t\t}\n\t});\n\n\tTone.version = \"r10\";\n\n\t// allow optional silencing of this log\n\tif (!window.TONE_SILENCE_VERSION_LOGGING) {\n\t\tconsole.log(\"%c * Tone.js \" + Tone.version + \" * \", \"background: #000; color: #fff\");\n\t}\n\n\treturn Tone;\n});\n","'use strict';\n\n\ndefine(['audiocontext'], function (audiocontext) {\n /**\n * Master contains AudioContext and the master sound output.\n * @for p5\n */\n var Master = function() {\n this.input = audiocontext.createGain();\n this.output = audiocontext.createGain();\n\n //put a hard limiter on the output\n this.limiter = audiocontext.createDynamicsCompressor();\n this.limiter.threshold.value = -3;\n this.limiter.ratio.value = 20;\n this.limiter.knee.value = 1;\n\n this.audiocontext = audiocontext;\n\n this.output.disconnect();\n\n // connect input to limiter\n this.input.connect(this.limiter);\n\n // connect limiter to output\n this.limiter.connect(this.output);\n\n // meter is just for global Amplitude / FFT analysis\n this.meter = audiocontext.createGain();\n this.fftMeter = audiocontext.createGain();\n this.output.connect(this.meter);\n this.output.connect(this.fftMeter);\n\n // connect output to destination\n this.output.connect(this.audiocontext.destination);\n\n // an array of all sounds in the sketch\n this.soundArray = [];\n // an array of all musical parts in the sketch\n this.parts = [];\n\n // file extensions to search for\n this.extensions = [];\n };\n\n // create a single instance of the p5Sound / master output for use within this sketch\n var p5sound = new Master();\n\n /**\n * Returns a number representing the master amplitude (volume) for sound\n * in this sketch.\n *\n * @method getMasterVolume\n * @return {Number} Master amplitude (volume) for sound in this sketch.\n * Should be between 0.0 (silence) and 1.0.\n */\n p5.prototype.getMasterVolume = function() {\n return p5sound.output.gain.value;\n };\n\n /**\n *
Scale the output of all sound in this sketch
\n * Scaled between 0.0 (silence) and 1.0 (full volume).\n * 1.0 is the maximum amplitude of a digital sound, so multiplying\n * by greater than 1.0 may cause digital distortion. To\n * fade, provide a rampTime parameter. For more\n * complex fades, see the Envelope class.\n *\n * Alternately, you can pass in a signal source such as an\n * oscillator to modulate the amplitude with an audio signal.\n *\n *
How This Works: When you load the p5.sound module, it\n * creates a single instance of p5sound. All sound objects in this\n * module output to p5sound before reaching your computer's output.\n * So if you change the amplitude of p5sound, it impacts all of the\n * sound in this module.
\n *\n *
If no value is provided, returns a Web Audio API Gain Node
\n *\n * @method masterVolume\n * @param {Number|Object} volume Volume (amplitude) between 0.0\n * and 1.0 or modulating signal/oscillator\n * @param {Number} [rampTime] Fade for t seconds\n * @param {Number} [timeFromNow] Schedule this event to happen at\n * t seconds in the future\n */\n p5.prototype.masterVolume = function(vol, rampTime, tFromNow) {\n if (typeof vol === 'number') {\n var rampTime = rampTime || 0;\n var tFromNow = tFromNow || 0;\n var now = p5sound.audiocontext.currentTime;\n var currentVol = p5sound.output.gain.value;\n p5sound.output.gain.cancelScheduledValues(now + tFromNow);\n p5sound.output.gain.linearRampToValueAtTime(currentVol, now + tFromNow);\n p5sound.output.gain.linearRampToValueAtTime(vol, now + tFromNow + rampTime);\n }\n else if (vol) {\n vol.connect(p5sound.output.gain);\n } else {\n // return the Gain Node\n return p5sound.output.gain;\n }\n };\n\n /**\n * `p5.soundOut` is the p5.sound master output. It sends output to\n * the destination of this window's web audio context. It contains\n * Web Audio API nodes including a dyanmicsCompressor (.limiter),\n * and Gain Nodes for .input and .output.\n *\n * @property {Object} soundOut\n */\n p5.prototype.soundOut = p5.soundOut = p5sound;\n\n /**\n * a silent connection to the DesinationNode\n * which will ensure that anything connected to it\n * will not be garbage collected\n *\n * @private\n */\n p5.soundOut._silentNode = p5sound.audiocontext.createGain();\n p5.soundOut._silentNode.gain.value = 0;\n p5.soundOut._silentNode.connect(p5sound.audiocontext.destination);\n\n\n return p5sound;\n});\n","define([\"Tone/core/Tone\", \"Tone/signal/WaveShaper\", \"Tone/type/Type\", \"Tone/core/Param\", \"Tone/core/Gain\"], function(Tone){\n\n\t\"use strict\";\n\n\t/**\n\t * @class A signal is an audio-rate value. Tone.Signal is a core component of the library.\n\t * Unlike a number, Signals can be scheduled with sample-level accuracy. Tone.Signal\n\t * has all of the methods available to native Web Audio \n\t * [AudioParam](http://webaudio.github.io/web-audio-api/#the-audioparam-interface)\n\t * as well as additional conveniences. Read more about working with signals \n\t * [here](https://github.com/Tonejs/Tone.js/wiki/Signals).\n\t *\n\t * @constructor\n\t * @extends {Tone.Param}\n\t * @param {Number|AudioParam} [value] Initial value of the signal. If an AudioParam\n\t * is passed in, that parameter will be wrapped\n\t * and controlled by the Signal. \n\t * @param {string} [units=Number] unit The units the signal is in. \n\t * @example\n\t * var signal = new Tone.Signal(10);\n\t */\n\tTone.Signal = function(){\n\n\t\tvar options = this.optionsObject(arguments, [\"value\", \"units\"], Tone.Signal.defaults);\n\n\t\t/**\n\t\t * The node where the constant signal value is scaled.\n\t\t * @type {GainNode}\n\t\t * @private\n\t\t */\n\t\tthis.output = this._gain = this.context.createGain();\n\n\t\toptions.param = this._gain.gain;\n\t\tTone.Param.call(this, options);\n\n\t\t/**\n\t\t * The node where the value is set.\n\t\t * @type {Tone.Param}\n\t\t * @private\n\t\t */\n\t\tthis.input = this._param = this._gain.gain;\n\n\t\t//connect the const output to the node output\n\t\tthis.context.getConstant(1).chain(this._gain);\n\t};\n\n\tTone.extend(Tone.Signal, Tone.Param);\n\n\t/**\n\t * The default values\n\t * @type {Object}\n\t * @static\n\t * @const\n\t */\n\tTone.Signal.defaults = {\n\t\t\"value\" : 0,\n\t\t\"units\" : Tone.Type.Default,\n\t\t\"convert\" : true,\n\t};\n\n\t/**\n\t * When signals connect to other signals or AudioParams, \n\t * they take over the output value of that signal or AudioParam. \n\t * For all other nodes, the behavior is the same as a default connect. \n\t *\n\t * @override\n\t * @param {AudioParam|AudioNode|Tone.Signal|Tone} node \n\t * @param {number} [outputNumber=0] The output number to connect from.\n\t * @param {number} [inputNumber=0] The input number to connect to.\n\t * @returns {Tone.SignalBase} this\n\t * @method\n\t */\n\tTone.Signal.prototype.connect = Tone.SignalBase.prototype.connect;\n\n\t/**\n\t * dispose and disconnect\n\t * @returns {Tone.Signal} this\n\t */\n\tTone.Signal.prototype.dispose = function(){\n\t\tTone.Param.prototype.dispose.call(this);\n\t\tthis._param = null;\n\t\tthis._gain.disconnect();\n\t\tthis._gain = null;\n\t\treturn this;\n\t};\n\n\treturn Tone.Signal;\n});","define([\"Tone/core/Tone\", \"Tone/signal/Signal\", \"Tone/core/Gain\"], function(Tone){\n\n\t\"use strict\";\n\n\t/**\n\t * @class Multiply two incoming signals. Or, if a number is given in the constructor, \n\t * multiplies the incoming signal by that value. \n\t *\n\t * @constructor\n\t * @extends {Tone.Signal}\n\t * @param {number=} value Constant value to multiple. If no value is provided,\n\t * it will return the product of the first and second inputs\n\t * @example\n\t * var mult = new Tone.Multiply();\n\t * var sigA = new Tone.Signal(3);\n\t * var sigB = new Tone.Signal(4);\n\t * sigA.connect(mult, 0, 0);\n\t * sigB.connect(mult, 0, 1);\n\t * //output of mult is 12.\n\t * @example\n\t * var mult = new Tone.Multiply(10);\n\t * var sig = new Tone.Signal(2).connect(mult);\n\t * //the output of mult is 20. \n\t */\n\tTone.Multiply = function(value){\n\n\t\tthis.createInsOuts(2, 0);\n\n\t\t/**\n\t\t * the input node is the same as the output node\n\t\t * it is also the GainNode which handles the scaling of incoming signal\n\t\t * \n\t\t * @type {GainNode}\n\t\t * @private\n\t\t */\n\t\tthis._mult = this.input[0] = this.output = new Tone.Gain();\n\n\t\t/**\n\t\t * the scaling parameter\n\t\t * @type {AudioParam}\n\t\t * @private\n\t\t */\n\t\tthis._param = this.input[1] = this.output.gain;\n\t\t\n\t\tthis._param.value = this.defaultArg(value, 0);\n\t};\n\n\tTone.extend(Tone.Multiply, Tone.Signal);\n\n\t/**\n\t * clean up\n\t * @returns {Tone.Multiply} this\n\t */\n\tTone.Multiply.prototype.dispose = function(){\n\t\tTone.prototype.dispose.call(this);\n\t\tthis._mult.dispose();\n\t\tthis._mult = null;\n\t\tthis._param = null;\n\t\treturn this;\n\t}; \n\n\treturn Tone.Multiply;\n});\n","'use strict';\ndefine(function (require) {\n\n var p5sound = require('master');\n var CrossFade = require('Tone/component/CrossFade');\n\n /**\n * Effect is a base class for audio effects in p5. \n * This module handles the nodes and methods that are\n * common and useful for current and future effects.\n *\n *\n * This class is extended by p5.Distortion,\n * p5.Compressor,\n * p5.Delay,\n * p5.Filter,\n * p5.Reverb.\n *\n * @class p5.Effect\n * @constructor\n *\n * @param {Object} [ac] Reference to the audio context of the p5 object\n * @param {AudioNode} [input] Gain Node effect wrapper\n * @param {AudioNode} [output] Gain Node effect wrapper\n * @param {Object} [_drywet] Tone.JS CrossFade node (defaults to value: 1)\n * @param {AudioNode} [wet] Effects that extend this class should connect\n * to the wet signal to this gain node, so that dry and wet\n * signals are mixed properly.\n */\n p5.Effect = function() {\n this.ac = p5sound.audiocontext;\n\n this.input = this.ac.createGain();\n this.output = this.ac.createGain();\n\n /**\n *\tThe p5.Effect class is built\n * \tusing Tone.js CrossFade\n * \t@private\n */\n\n this._drywet = new CrossFade(1);\n\n /**\n *\tIn classes that extend\n *\tp5.Effect, connect effect nodes\n *\tto the wet parameter\n */\n this.wet = this.ac.createGain();\n\n this.input.connect(this._drywet.a);\n this.wet.connect(this._drywet.b);\n this._drywet.connect(this.output);\n\n this.connect();\n\n //Add to the soundArray\n p5sound.soundArray.push(this);\n };\n\n /**\n * Set the output volume of the filter.\n *\n * @method amp\n * @for p5.Effect\n * @param {Number} [vol] amplitude between 0 and 1.0\n * @param {Number} [rampTime] create a fade that lasts until rampTime\n * @param {Number} [tFromNow] schedule this event to happen in tFromNow seconds\n */\n p5.Effect.prototype.amp = function(vol, rampTime, tFromNow){\n var rampTime = rampTime || 0;\n var tFromNow = tFromNow || 0;\n var now = p5sound.audiocontext.currentTime;\n var currentVol = this.output.gain.value;\n this.output.gain.cancelScheduledValues(now);\n this.output.gain.linearRampToValueAtTime(currentVol, now + tFromNow + .001);\n this.output.gain.linearRampToValueAtTime(vol, now + tFromNow + rampTime + .001);\n };\n\n /**\n * Link effects together in a chain\n * Example usage: filter.chain(reverb, delay, panner);\n * May be used with an open-ended number of arguments\n *\n * @method chain\n * @for p5.Effect\n * @param {Object} [arguments] Chain together multiple sound objects\n */\n p5.Effect.prototype.chain = function(){\n if (arguments.length>0){\n this.connect(arguments[0]);\n for(var i=1;i\n * var notes = [60, 64, 67, 72];\n * var i = 0;\n *\n * function setup() {\n * osc = new p5.Oscillator('Triangle');\n * osc.start();\n * frameRate(1);\n * }\n *\n * function draw() {\n * var freq = midiToFreq(notes[i]);\n * osc.freq(freq);\n * i++;\n * if (i >= notes.length){\n * i = 0;\n * }\n * }\n * \n */\n var midiToFreq = p5.prototype.midiToFreq = function(m) {\n return 440 * Math.pow(2, (m-69)/12.0);\n };\n\n // This method converts ANSI notes specified as a string \"C4\", \"Eb3\" to a frequency\n var noteToFreq = function(note) {\n if (typeof note !== 'string') {\n return note;\n }\n var wholeNotes = {A:21, B:23, C:24, D:26, E:28, F:29, G:31};\n var value = wholeNotes[ note[0].toUpperCase() ];\n var octave = ~~note.slice(-1);\n value += 12 * (octave -1);\n\n switch(note[1]) {\n case '#':\n value += 1;\n break;\n case 'b':\n value -= 1;\n break;\n default:\n break;\n }\n return midiToFreq(value);\n };\n\n /**\n * List the SoundFile formats that you will include. LoadSound\n * will search your directory for these extensions, and will pick\n * a format that is compatable with the client's web browser.\n * Here is a free online file\n * converter.\n *\n * @method soundFormats\n * @param {String} [...formats] i.e. 'mp3', 'wav', 'ogg'\n * @example\n *
\n * function preload() {\n * // set the global sound formats\n * soundFormats('mp3', 'ogg');\n *\n * // load either beatbox.mp3, or .ogg, depending on browser\n * mySound = loadSound('assets/beatbox.mp3');\n * }\n *\n * function setup() {\n * mySound.play();\n * }\n *
\n */\n p5.prototype.soundFormats = function() {\n // reset extensions array\n p5sound.extensions = [];\n // add extensions\n for (var i = 0; i < arguments.length; i++) {\n arguments[i] = arguments[i].toLowerCase();\n if (['mp3','wav','ogg', 'm4a', 'aac'].indexOf(arguments[i]) > -1) {\n p5sound.extensions.push(arguments[i]);\n } else {\n throw arguments[i] + ' is not a valid sound format!';\n }\n }\n };\n\n p5.prototype.disposeSound = function() {\n for (var i = 0; i < p5sound.soundArray.length; i++) {\n p5sound.soundArray[i].dispose();\n }\n };\n\n // register removeSound to dispose of p5sound SoundFiles, Convolvers,\n // Oscillators etc when sketch ends\n p5.prototype.registerMethod('remove', p5.prototype.disposeSound);\n\n p5.prototype._checkFileFormats = function(paths) {\n var path;\n // if path is a single string, check to see if extension is provided\n if (typeof paths === 'string') {\n path = paths;\n // see if extension is provided\n var extTest = path.split('.').pop();\n // if an extension is provided...\n if (['mp3','wav','ogg', 'm4a', 'aac'].indexOf(extTest) > -1) {\n if (p5.prototype.isFileSupported(extTest)) {\n path = path;\n }\n else {\n var pathSplit = path.split('.');\n var pathCore = pathSplit[pathSplit.length - 1];\n for (var i = 0; i 1) {\n rightChannel = audioBuffer.getChannelData(1);\n } else {\n rightChannel = leftChannel;\n }\n\n var interleaved = interleave(leftChannel, rightChannel);\n\n // create the buffer and view to create the .WAV file\n var buffer = new window.ArrayBuffer(44 + interleaved.length * 2);\n var view = new window.DataView(buffer);\n\n // write the WAV container,\n // check spec at: https://web.archive.org/web/20171215131933/http://tiny.systems/software/soundProgrammer/WavFormatDocs.pdf\n\n // RIFF chunk descriptor\n writeUTFBytes(view, 0, 'RIFF');\n view.setUint32(4, 36 + interleaved.length * 2, true);\n writeUTFBytes(view, 8, 'WAVE');\n // FMT sub-chunk\n writeUTFBytes(view, 12, 'fmt ');\n view.setUint32(16, 16, true);\n view.setUint16(20, 1, true);\n // stereo (2 channels)\n view.setUint16(22, 2, true);\n view.setUint32(24, p5sound.audiocontext.sampleRate, true);\n view.setUint32(28, p5sound.audiocontext.sampleRate * 4, true);\n view.setUint16(32, 4, true);\n view.setUint16(34, 16, true);\n // data sub-chunk\n writeUTFBytes(view, 36, 'data');\n view.setUint32(40, interleaved.length * 2, true);\n\n // write the PCM samples\n var lng = interleaved.length;\n var index = 44;\n var volume = 1;\n for (var i = 0; i < lng; i++) {\n view.setInt16(index, interleaved[i] * (0x7FFF * volume), true);\n index += 2;\n }\n\n return view;\n }\n\n // helper methods to save waves\n function interleave(leftChannel, rightChannel) {\n var length = leftChannel.length + rightChannel.length;\n var result = new Float32Array(length);\n\n var inputIndex = 0;\n\n for (var index = 0; index < length;) {\n result[index++] = leftChannel[inputIndex];\n result[index++] = rightChannel[inputIndex];\n inputIndex++;\n }\n return result;\n }\n\n function writeUTFBytes(view, offset, string) {\n var lng = string.length;\n for (var i = 0; i < lng; i++) {\n view.setUint8(offset + i, string.charCodeAt(i));\n }\n }\n\n return {\n convertToWav: convertToWav,\n midiToFreq: midiToFreq,\n noteToFreq: noteToFreq\n };\n\n});\n","define([\"Tone/core/Tone\", \"Tone/signal/Signal\", \"Tone/core/Gain\"], function(Tone){\n\n\t\"use strict\";\n\n\t/**\n\t * @class Add a signal and a number or two signals. When no value is\n\t * passed into the constructor, Tone.Add will sum input[0]\n\t * and input[1]. If a value is passed into the constructor, \n\t * the it will be added to the input.\n\t * \n\t * @constructor\n\t * @extends {Tone.Signal}\n\t * @param {number=} value If no value is provided, Tone.Add will sum the first\n\t * and second inputs. \n\t * @example\n\t * var signal = new Tone.Signal(2);\n\t * var add = new Tone.Add(2);\n\t * signal.connect(add);\n\t * //the output of add equals 4\n\t * @example\n\t * //if constructed with no arguments\n\t * //it will add the first and second inputs\n\t * var add = new Tone.Add();\n\t * var sig0 = new Tone.Signal(3).connect(add, 0, 0);\n\t * var sig1 = new Tone.Signal(4).connect(add, 0, 1);\n\t * //the output of add equals 7. \n\t */\n\tTone.Add = function(value){\n\n\t\tthis.createInsOuts(2, 0);\n\n\t\t/**\n\t\t * the summing node\n\t\t * @type {GainNode}\n\t\t * @private\n\t\t */\n\t\tthis._sum = this.input[0] = this.input[1] = this.output = new Tone.Gain();\n\n\t\t/**\n\t\t * @private\n\t\t * @type {Tone.Signal}\n\t\t */\n\t\tthis._param = this.input[1] = new Tone.Signal(value);\n\n\t\tthis._param.connect(this._sum);\n\t};\n\n\tTone.extend(Tone.Add, Tone.Signal);\n\t\n\t/**\n\t * Clean up.\n\t * @returns {Tone.Add} this\n\t */\n\tTone.Add.prototype.dispose = function(){\n\t\tTone.prototype.dispose.call(this);\n\t\tthis._sum.dispose();\n\t\tthis._sum = null;\n\t\tthis._param.dispose();\n\t\tthis._param = null;\n\t\treturn this;\n\t}; \n\n\treturn Tone.Add;\n});","define([\"Tone/core/Tone\", \"Tone/type/Time\", \"Tone/type/Frequency\", \"Tone/type/TransportTime\", \"Tone/core/Context\"],\nfunction (Tone) {\t\n\n\t///////////////////////////////////////////////////////////////////////////\n\t//\tTYPES\n\t///////////////////////////////////////////////////////////////////////////\n\n\t/**\n\t * Units which a value can take on.\n\t * @enum {String}\n\t */\n\tTone.Type = {\n\t\t/** \n\t\t * Default units\n\t\t * @typedef {Default}\n\t\t */\n\t\tDefault : \"number\",\n\t\t/**\n\t\t * Time can be described in a number of ways. Read more [Time](https://github.com/Tonejs/Tone.js/wiki/Time).\n\t\t *\n\t\t *
\n\t\t *
Numbers, which will be taken literally as the time (in seconds).
\n\t\t *
Notation, (\"4n\", \"8t\") describes time in BPM and time signature relative values.
\n\t\t *
TransportTime, (\"4:3:2\") will also provide tempo and time signature relative times \n\t\t * in the form BARS:QUARTERS:SIXTEENTHS.
\n\t\t *
Frequency, (\"8hz\") is converted to the length of the cycle in seconds.
\n\t\t *
Now-Relative, (\"+1\") prefix any of the above with \"+\" and it will be interpreted as \n\t\t * \"the current time plus whatever expression follows\".
\n\t\t *
Expressions, (\"3:0 + 2 - (1m / 7)\") any of the above can also be combined \n\t\t * into a mathematical expression which will be evaluated to compute the desired time.
\n\t\t *
No Argument, for methods which accept time, no argument will be interpreted as \n\t\t * \"now\" (i.e. the currentTime).
\n\t\t *
\n\t\t * \n\t\t * @typedef {Time}\n\t\t */\n\t\tTime : \"time\",\n\t\t/**\n\t\t * Frequency can be described similar to time, except ultimately the\n\t\t * values are converted to frequency instead of seconds. A number\n\t\t * is taken literally as the value in hertz. Additionally any of the \n\t\t * Time encodings can be used. Note names in the form\n\t\t * of NOTE OCTAVE (i.e. C4) are also accepted and converted to their\n\t\t * frequency value. \n\t\t * @typedef {Frequency}\n\t\t */\n\t\tFrequency : \"frequency\",\n\t\t/**\n\t\t * TransportTime describes a position along the Transport's timeline. It is\n\t\t * similar to Time in that it uses all the same encodings, but TransportTime specifically\n\t\t * pertains to the Transport's timeline, which is startable, stoppable, loopable, and seekable. \n\t\t * [Read more](https://github.com/Tonejs/Tone.js/wiki/TransportTime)\n\t\t * @typedef {TransportTime}\n\t\t */\n\t\tTransportTime : \"transportTime\",\n\t\t/** \n\t\t * Ticks are the basic subunit of the Transport. They are\n\t\t * the smallest unit of time that the Transport supports.\n\t\t * @typedef {Ticks}\n\t\t */\n\t\tTicks : \"ticks\",\n\t\t/** \n\t\t * Normal values are within the range [0, 1].\n\t\t * @typedef {NormalRange}\n\t\t */\n\t\tNormalRange : \"normalRange\",\n\t\t/** \n\t\t * AudioRange values are between [-1, 1].\n\t\t * @typedef {AudioRange}\n\t\t */\n\t\tAudioRange : \"audioRange\",\n\t\t/** \n\t\t * Decibels are a logarithmic unit of measurement which is useful for volume\n\t\t * because of the logarithmic way that we perceive loudness. 0 decibels \n\t\t * means no change in volume. -10db is approximately half as loud and 10db \n\t\t * is twice is loud. \n\t\t * @typedef {Decibels}\n\t\t */\n\t\tDecibels : \"db\",\n\t\t/** \n\t\t * Half-step note increments, i.e. 12 is an octave above the root. and 1 is a half-step up.\n\t\t * @typedef {Interval}\n\t\t */\n\t\tInterval : \"interval\",\n\t\t/** \n\t\t * Beats per minute. \n\t\t * @typedef {BPM}\n\t\t */\n\t\tBPM : \"bpm\",\n\t\t/** \n\t\t * The value must be greater than or equal to 0.\n\t\t * @typedef {Positive}\n\t\t */\n\t\tPositive : \"positive\",\n\t\t/** \n\t\t * A cent is a hundredth of a semitone. \n\t\t * @typedef {Cents}\n\t\t */\n\t\tCents : \"cents\",\n\t\t/** \n\t\t * Angle between 0 and 360. \n\t\t * @typedef {Degrees}\n\t\t */\n\t\tDegrees : \"degrees\",\n\t\t/** \n\t\t * A number representing a midi note.\n\t\t * @typedef {MIDI}\n\t\t */\n\t\tMIDI : \"midi\",\n\t\t/** \n\t\t * A colon-separated representation of time in the form of\n\t\t * Bars:Beats:Sixteenths. \n\t\t * @typedef {BarsBeatsSixteenths}\n\t\t */\n\t\tBarsBeatsSixteenths : \"barsBeatsSixteenths\",\n\t\t/** \n\t\t * Sampling is the reduction of a continuous signal to a discrete signal.\n\t\t * Audio is typically sampled 44100 times per second. \n\t\t * @typedef {Samples}\n\t\t */\n\t\tSamples : \"samples\",\n\t\t/** \n\t\t * Hertz are a frequency representation defined as one cycle per second.\n\t\t * @typedef {Hertz}\n\t\t */\n\t\tHertz : \"hertz\",\n\t\t/** \n\t\t * A frequency represented by a letter name, \n\t\t * accidental and octave. This system is known as\n\t\t * [Scientific Pitch Notation](https://en.wikipedia.org/wiki/Scientific_pitch_notation).\n\t\t * @typedef {Note}\n\t\t */\n\t\tNote : \"note\",\n\t\t/** \n\t\t * One millisecond is a thousandth of a second. \n\t\t * @typedef {Milliseconds}\n\t\t */\n\t\tMilliseconds : \"milliseconds\",\n\t\t/** \n\t\t * Seconds are the time unit of the AudioContext. In the end, \n\t\t * all values need to be evaluated to seconds. \n\t\t * @typedef {Seconds}\n\t\t */\n\t\tSeconds : \"seconds\",\n\t\t/** \n\t\t * A string representing a duration relative to a measure. \n\t\t *
\n\t\t * \t
\"4n\" = quarter note
\n\t\t * \t
\"2m\" = two measures
\n\t\t * \t
\"8t\" = eighth-note triplet
\n\t\t *
\n\t\t * @typedef {Notation}\n\t\t */\n\t\tNotation : \"notation\",\n\t};\n\n\t///////////////////////////////////////////////////////////////////////////\n\t// AUGMENT TONE's PROTOTYPE\n\t///////////////////////////////////////////////////////////////////////////\n\n\t/**\n\t * Convert Time into seconds.\n\t * \n\t * Unlike the method which it overrides, this takes into account \n\t * transporttime and musical notation.\n\t *\n\t * Time : 1.40\n\t * Notation: 4n|1m|2t\n\t * Now Relative: +3n\n\t * Math: 3n+16n or even complicated expressions ((3n*2)/6 + 1)\n\t *\n\t * @param {Time} time \n\t * @return {Seconds} \n\t */\n\tTone.prototype.toSeconds = function(time){\n\t\tif (this.isNumber(time)){\n\t\t\treturn time;\n\t\t} else if (this.isUndef(time)){\n\t\t\treturn this.now();\t\t\t\n\t\t} else if (this.isString(time)){\n\t\t\treturn (new Tone.Time(time)).toSeconds();\n\t\t} else if (time instanceof Tone.TimeBase){\n\t\t\treturn time.toSeconds();\n\t\t}\n\t};\n\n\t/**\n\t * Convert a frequency representation into a number.\n\t * @param {Frequency} freq \n\t * @return {Hertz} the frequency in hertz\n\t */\n\tTone.prototype.toFrequency = function(freq){\n\t\tif (this.isNumber(freq)){\n\t\t\treturn freq;\n\t\t} else if (this.isString(freq) || this.isUndef(freq)){\n\t\t\treturn (new Tone.Frequency(freq)).valueOf();\n\t\t} else if (freq instanceof Tone.TimeBase){\n\t\t\treturn freq.toFrequency();\n\t\t}\n\t};\n\n\t/**\n\t * Convert a time representation into ticks.\n\t * @param {Time} time\n\t * @return {Ticks} the time in ticks\n\t */\n\tTone.prototype.toTicks = function(time){\n\t\tif (this.isNumber(time) || this.isString(time)){\n\t\t\treturn (new Tone.TransportTime(time)).toTicks();\n\t\t} else if (this.isUndef(time)){\n\t\t\treturn Tone.Transport.ticks;\t\t\t\n\t\t} else if (time instanceof Tone.TimeBase){\n\t\t\treturn time.toTicks();\n\t\t}\n\t};\n\n\treturn Tone;\n});","define([\"Tone/core/Tone\", \"Tone/core/Param\", \"Tone/type/Type\"], function (Tone) {\n\n\t\"use strict\";\n\n\t/**\n\t * createGain shim\n\t * @private\n\t */\n\tif (window.GainNode && !AudioContext.prototype.createGain){\n\t\tAudioContext.prototype.createGain = AudioContext.prototype.createGainNode;\n\t}\n\n\t/**\n\t * @class A thin wrapper around the Native Web Audio GainNode.\n\t * The GainNode is a basic building block of the Web Audio\n\t * API and is useful for routing audio and adjusting gains. \n\t * @extends {Tone}\n\t * @param {Number=} gain The initial gain of the GainNode\n\t * @param {Tone.Type=} units The units of the gain parameter. \n\t */\n\tTone.Gain = function(){\n\n\t\tvar options = this.optionsObject(arguments, [\"gain\", \"units\"], Tone.Gain.defaults);\n\n\t\t/**\n\t\t * The GainNode\n\t\t * @type {GainNode}\n\t\t * @private\n\t\t */\n\t\tthis.input = this.output = this._gainNode = this.context.createGain();\n\n\t\t/**\n\t\t * The gain parameter of the gain node.\n\t\t * @type {Tone.Param}\n\t\t * @signal\n\t\t */\n\t\tthis.gain = new Tone.Param({\n\t\t\t\"param\" : this._gainNode.gain, \n\t\t\t\"units\" : options.units,\n\t\t\t\"value\" : options.gain,\n\t\t\t\"convert\" : options.convert\n\t\t});\n\t\tthis._readOnly(\"gain\");\n\t};\n\n\tTone.extend(Tone.Gain);\n\n\t/**\n\t * The defaults\n\t * @const\n\t * @type {Object}\n\t */\n\tTone.Gain.defaults = {\n\t\t\"gain\" : 1,\n\t\t\"convert\" : true,\n\t};\n\n\t/**\n\t * Clean up.\n\t * @return {Tone.Gain} this\n\t */\n\tTone.Gain.prototype.dispose = function(){\n\t\tTone.Param.prototype.dispose.call(this);\n\t\tthis._gainNode.disconnect();\n\t\tthis._gainNode = null;\n\t\tthis._writable(\"gain\");\n\t\tthis.gain.dispose();\n\t\tthis.gain = null;\n\t};\n\n\t//STATIC///////////////////////////////////////////////////////////////////\n\n\t/**\n\t * Create input and outputs for this object.\n\t * @param {Number} input The number of inputs\n\t * @param {Number=} outputs The number of outputs\n\t * @return {Tone} this\n\t * @internal\n\t */\n\tTone.prototype.createInsOuts = function(inputs, outputs){\n\n\t\tif (inputs === 1){\n\t\t\tthis.input = new Tone.Gain();\n\t\t} else if (inputs > 1){\n\t\t\tthis.input = new Array(inputs);\n\t\t}\n\n\t\tif (outputs === 1){\n\t\t\tthis.output = new Tone.Gain();\n\t\t} else if (outputs > 1){\n\t\t\tthis.output = new Array(inputs);\n\t\t}\n\t};\n\n\t///////////////////////////////////////////////////////////////////////////\n\n\treturn Tone.Gain;\n});","'use strict';\n\ndefine(function () {\n /*\n Helper function to generate an error\n with a custom stack trace that points to the sketch\n and removes other parts of the stack trace.\n\n @private\n @class customError\n @constructor\n @param {String} name custom error name\n @param {String} errorTrace custom error trace\n @param {String} failedPath path to the file that failed to load\n @property {String} name custom error name\n @property {String} message custom error message\n @property {String} stack trace the error back to a line in the user's sketch.\n Note: this edits out stack trace within p5.js and p5.sound.\n @property {String} originalStack unedited, original stack trace\n @property {String} failedPath path to the file that failed to load\n @return {Error} returns a custom Error object\n */\n var CustomError = function(name, errorTrace, failedPath) {\n var err = new Error();\n var tempStack, splitStack;\n\n err.name = name;\n err.originalStack = err.stack + errorTrace;\n tempStack = err.stack + errorTrace;\n err.failedPath = failedPath;\n\n // only print the part of the stack trace that refers to the user code:\n var splitStack = tempStack.split('\\n');\n splitStack = splitStack.filter(function(ln) {\n return !ln.match(/(p5.|native code|globalInit)/g);\n });\n err.stack = splitStack.join('\\n');\n\n return err; // TODO: is this really a constructor?\n };\n\n return CustomError;\n});\n","define([\"Tone/core/Tone\", \"Tone/core/Emitter\"], function (Tone) {\n\n\t/**\n\t * shim\n\t * @private\n\t */\n\tif (!window.hasOwnProperty(\"AudioContext\") && window.hasOwnProperty(\"webkitAudioContext\")){\n\t\twindow.AudioContext = window.webkitAudioContext;\n\t}\n\n\t/**\n\t * @class Wrapper around the native AudioContext.\n\t * @extends {Tone.Emitter}\n\t * @param {AudioContext=} context optionally pass in a context\n\t */\n\tTone.Context = function(context){\n\n\t\tTone.Emitter.call(this);\n\n\t\tif (!context){\n\t\t\tcontext = new window.AudioContext();\n\t\t}\n\t\tthis._context = context;\n\t\t// extend all of the methods\n\t\tfor (var prop in this._context){\n\t\t\tthis._defineProperty(this._context, prop);\n\t\t}\n\n\t\t///////////////////////////////////////////////////////////////////////\n\t\t// WORKER\n\t\t///////////////////////////////////////////////////////////////////////\n\n\t\t/**\n\t\t * The default latency hint\n\t\t * @type {String}\n\t\t * @private\n\t\t */\n\t\tthis._latencyHint = \"interactive\";\n\n\t\t/**\n\t\t * The amount of time events are scheduled\n\t\t * into the future\n\t\t * @type {Number}\n\t\t * @private\n\t\t */\n\t\tthis._lookAhead = 0.1;\n\n\t\t/**\n\t\t * How often the update look runs\n\t\t * @type {Number}\n\t\t * @private\n\t\t */\n\t\tthis._updateInterval = this._lookAhead/3;\n\n\t\t/**\n\t\t * A reference to the actual computed update interval\n\t\t * @type {Number}\n\t\t * @private\n\t\t */\n\t\tthis._computedUpdateInterval = 0;\n\n\t\t/**\n\t\t * The web worker which is used to update Tone.Clock\n\t\t * @private\n\t\t * @type {WebWorker}\n\t\t */\n\t\tthis._worker = this._createWorker();\n\n\t\t/**\n\t\t * An object containing all of the constants AudioBufferSourceNodes\n\t\t * @type {Object}\n\t\t * @private\n\t\t */\n\t\tthis._constants = {};\n\n\t};\n\n\tTone.extend(Tone.Context, Tone.Emitter);\n\tTone.Emitter.mixin(Tone.Context);\n\n\t/**\n\t * Define a property on this Tone.Context. \n\t * This is used to extend the native AudioContext\n\t * @param {AudioContext} context\n\t * @param {String} prop \n\t * @private\n\t */\n\tTone.Context.prototype._defineProperty = function(context, prop){\n\t\tif (this.isUndef(this[prop])){\n\t\t\tObject.defineProperty(this, prop, {\n\t\t\t\tget : function(){\n\t\t\t\t\tif (typeof context[prop] === \"function\"){\n\t\t\t\t\t\treturn context[prop].bind(context);\n\t\t\t\t\t} else {\n\t\t\t\t\t\treturn context[prop];\n\t\t\t\t\t}\n\t\t\t\t},\n\t\t\t\tset : function(val){\n\t\t\t\t\tcontext[prop] = val;\n\t\t\t\t}\n\t\t\t});\n\t\t}\n\t};\n\n\t/**\n\t * The current audio context time\n\t * @return {Number}\n\t */\n\tTone.Context.prototype.now = function(){\n\t\treturn this._context.currentTime;\n\t};\n\n\t/**\n\t * Generate a web worker\n\t * @return {WebWorker}\n\t * @private\n\t */\n\tTone.Context.prototype._createWorker = function(){\n\t\t\n\t\t//URL Shim\n\t\twindow.URL = window.URL || window.webkitURL;\n\n\t\tvar blob = new Blob([\n\t\t\t//the initial timeout time\n\t\t\t\"var timeoutTime = \"+(this._updateInterval * 1000).toFixed(1)+\";\" +\n\t\t\t//onmessage callback\n\t\t\t\"self.onmessage = function(msg){\" +\n\t\t\t\"\ttimeoutTime = parseInt(msg.data);\" + \n\t\t\t\"};\" + \n\t\t\t//the tick function which posts a message\n\t\t\t//and schedules a new tick\n\t\t\t\"function tick(){\" +\n\t\t\t\"\tsetTimeout(tick, timeoutTime);\" +\n\t\t\t\"\tself.postMessage('tick');\" +\n\t\t\t\"}\" +\n\t\t\t//call tick initially\n\t\t\t\"tick();\"\n\t\t]);\n\t\tvar blobUrl = URL.createObjectURL(blob);\n\t\tvar worker = new Worker(blobUrl);\n\n\t\tworker.addEventListener(\"message\", function(){\n\t\t\t// tick the clock\n\t\t\tthis.emit(\"tick\");\n\t\t}.bind(this));\n\n\t\t//lag compensation\n\t\tworker.addEventListener(\"message\", function(){\n\t\t\tvar now = this.now();\n\t\t\tif (this.isNumber(this._lastUpdate)){\n\t\t\t\tvar diff = now - this._lastUpdate;\n\t\t\t\tthis._computedUpdateInterval = Math.max(diff, this._computedUpdateInterval * 0.97);\n\t\t\t}\n\t\t\tthis._lastUpdate = now;\n\t\t}.bind(this));\n\n\t\treturn worker;\n\t};\n\n\t/**\n\t * Generate a looped buffer at some constant value.\n\t * @param {Number} val\n\t * @return {BufferSourceNode}\n\t */\n\tTone.Context.prototype.getConstant = function(val){\n\t\tif (this._constants[val]){\n\t\t\treturn this._constants[val];\n\t\t} else {\n\t\t\tvar buffer = this._context.createBuffer(1, 128, this._context.sampleRate);\n\t\t\tvar arr = buffer.getChannelData(0);\n\t\t\tfor (var i = 0; i < arr.length; i++){\n\t\t\t\tarr[i] = val;\n\t\t\t}\n\t\t\tvar constant = this._context.createBufferSource();\n\t\t\tconstant.channelCount = 1;\n\t\t\tconstant.channelCountMode = \"explicit\";\n\t\t\tconstant.buffer = buffer;\n\t\t\tconstant.loop = true;\n\t\t\tconstant.start(0);\n\t\t\tthis._constants[val] = constant;\n\t\t\treturn constant;\n\t\t}\n\t};\n\n\t/**\n\t * This is the time that the clock is falling behind\n\t * the scheduled update interval. The Context automatically\n\t * adjusts for the lag and schedules further in advance.\n\t * @type {Number}\n\t * @memberOf Tone.Context\n\t * @name lag\n\t * @static\n\t * @readOnly\n\t */\n\tObject.defineProperty(Tone.Context.prototype, \"lag\", {\n\t\tget : function(){\n\t\t\tvar diff = this._computedUpdateInterval - this._updateInterval;\n\t\t\tdiff = Math.max(diff, 0);\n\t\t\treturn diff;\n\t\t}\n\t});\n\n\t/**\n\t * The amount of time in advance that events are scheduled.\n\t * The lookAhead will adjust slightly in response to the \n\t * measured update time to try to avoid clicks.\n\t * @type {Number}\n\t * @memberOf Tone.Context\n\t * @name lookAhead\n\t * @static\n\t */\n\tObject.defineProperty(Tone.Context.prototype, \"lookAhead\", {\n\t\tget : function(){\n\t\t\treturn this._lookAhead;\n\t\t},\n\t\tset : function(lA){\n\t\t\tthis._lookAhead = lA;\n\t\t}\n\t});\n\n\t/**\n\t * How often the Web Worker callback is invoked.\n\t * This number corresponds to how responsive the scheduling\n\t * can be. Context.updateInterval + Context.lookAhead gives you the\n\t * total latency between scheduling an event and hearing it.\n\t * @type {Number}\n\t * @memberOf Tone.Context\n\t * @name updateInterval\n\t * @static\n\t */\n\tObject.defineProperty(Tone.Context.prototype, \"updateInterval\", {\n\t\tget : function(){\n\t\t\treturn this._updateInterval;\n\t\t},\n\t\tset : function(interval){\n\t\t\tthis._updateInterval = Math.max(interval, Tone.prototype.blockTime);\n\t\t\tthis._worker.postMessage(Math.max(interval * 1000, 1));\n\t\t}\n\t});\n\n\t/**\n\t * The type of playback, which affects tradeoffs between audio \n\t * output latency and responsiveness. \n\t * \n\t * In addition to setting the value in seconds, the latencyHint also\n\t * accepts the strings \"interactive\" (prioritizes low latency), \n\t * \"playback\" (prioritizes sustained playback), \"balanced\" (balances\n\t * latency and performance), and \"fastest\" (lowest latency, might glitch more often). \n\t * @type {String|Seconds}\n\t * @memberOf Tone.Context#\n\t * @name latencyHint\n\t * @static\n\t * @example\n\t * //set the lookAhead to 0.3 seconds\n\t * Tone.context.latencyHint = 0.3;\n\t */\n\tObject.defineProperty(Tone.Context.prototype, \"latencyHint\", {\n\t\tget : function(){\n\t\t\treturn this._latencyHint;\n\t\t},\n\t\tset : function(hint){\n\t\t\tvar lookAhead = hint;\n\t\t\tthis._latencyHint = hint;\n\t\t\tif (this.isString(hint)){\n\t\t\t\tswitch(hint){\n\t\t\t\t\tcase \"interactive\" :\n\t\t\t\t\t\tlookAhead = 0.1;\n\t\t\t\t\t\tthis._context.latencyHint = hint;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase \"playback\" :\n\t\t\t\t\t\tlookAhead = 0.8;\n\t\t\t\t\t\tthis._context.latencyHint = hint;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase \"balanced\" :\n\t\t\t\t\t\tlookAhead = 0.25;\n\t\t\t\t\t\tthis._context.latencyHint = hint;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase \"fastest\" :\n\t\t\t\t\t\tlookAhead = 0.01;\n\t\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t\tthis.lookAhead = lookAhead;\n\t\t\tthis.updateInterval = lookAhead/3;\n\t\t}\n\t});\n\n\t/**\n\t * Shim all connect/disconnect and some deprecated methods which are still in\n\t * some older implementations.\n\t * @private\n\t */\n\tfunction shimConnect(){\n\n\t\tvar nativeConnect = AudioNode.prototype.connect;\n\t\tvar nativeDisconnect = AudioNode.prototype.disconnect;\n\n\t\t//replace the old connect method\n\t\tfunction toneConnect(B, outNum, inNum){\n\t\t\tif (B.input){\n\t\t\t\tif (Array.isArray(B.input)){\n\t\t\t\t\tif (Tone.prototype.isUndef(inNum)){\n\t\t\t\t\t\tinNum = 0;\n\t\t\t\t\t}\n\t\t\t\t\tthis.connect(B.input[inNum]);\n\t\t\t\t} else {\n\t\t\t\t\tthis.connect(B.input, outNum, inNum);\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\ttry {\n\t\t\t\t\tif (B instanceof AudioNode){\n\t\t\t\t\t\tnativeConnect.call(this, B, outNum, inNum);\n\t\t\t\t\t} else {\n\t\t\t\t\t\tnativeConnect.call(this, B, outNum);\n\t\t\t\t\t}\n\t\t\t\t} catch (e) {\n\t\t\t\t\tthrow new Error(\"error connecting to node: \"+B+\"\\n\"+e);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t//replace the old disconnect method\n\t\tfunction toneDisconnect(B, outNum, inNum){\n\t\t\tif (B && B.input && Array.isArray(B.input)){\n\t\t\t\tif (Tone.prototype.isUndef(inNum)){\n\t\t\t\t\tinNum = 0;\n\t\t\t\t}\n\t\t\t\tthis.disconnect(B.input[inNum], outNum, inNum);\n\t\t\t} else if (B && B.input){\n\t\t\t\tthis.disconnect(B.input, outNum, inNum);\n\t\t\t} else {\n\t\t\t\ttry {\n\t\t\t\t\tnativeDisconnect.apply(this, arguments);\n\t\t\t\t} catch (e) {\n\t\t\t\t\tthrow new Error(\"error disconnecting node: \"+B+\"\\n\"+e);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tif (AudioNode.prototype.connect !== toneConnect){\n\t\t\tAudioNode.prototype.connect = toneConnect;\n\t\t\tAudioNode.prototype.disconnect = toneDisconnect;\n\t\t}\n\t}\n\n\t// set the audio context initially\n\tif (Tone.supported){\n\t\tshimConnect();\n\t\tTone.context = new Tone.Context();\n\t} else {\n\t\tconsole.warn(\"This browser does not support Tone.js\");\n\t}\n\n\treturn Tone.Context;\n});","module.exports = {\n recorderProcessor: 'recorder-processor',\n soundFileProcessor: 'sound-file-processor',\n amplitudeProcessor: 'amplitude-processor'\n};\n","define([\"Tone/core/Tone\", \"Tone/signal/Add\", \"Tone/signal/Multiply\", \"Tone/signal/Signal\"], function(Tone){\n\n\t\"use strict\";\n\t\n\t/**\n\t * @class Performs a linear scaling on an input signal.\n\t * Scales a NormalRange input to between\n\t * outputMin and outputMax.\n\t *\n\t * @constructor\n\t * @extends {Tone.SignalBase}\n\t * @param {number} [outputMin=0] The output value when the input is 0. \n\t * @param {number} [outputMax=1]\tThe output value when the input is 1. \n\t * @example\n\t * var scale = new Tone.Scale(50, 100);\n\t * var signal = new Tone.Signal(0.5).connect(scale);\n\t * //the output of scale equals 75\n\t */\n\tTone.Scale = function(outputMin, outputMax){\n\n\t\t/** \n\t\t * @private\n\t\t * @type {number}\n\t\t */\n\t\tthis._outputMin = this.defaultArg(outputMin, 0);\n\n\t\t/** \n\t\t * @private\n\t\t * @type {number}\n\t\t */\n\t\tthis._outputMax = this.defaultArg(outputMax, 1);\n\n\n\t\t/** \n\t\t * @private\n\t\t * @type {Tone.Multiply}\n\t\t * @private\n\t\t */\n\t\tthis._scale = this.input = new Tone.Multiply(1);\n\t\t\n\t\t/** \n\t\t * @private\n\t\t * @type {Tone.Add}\n\t\t * @private\n\t\t */\n\t\tthis._add = this.output = new Tone.Add(0);\n\n\t\tthis._scale.connect(this._add);\n\t\tthis._setRange();\n\t};\n\n\tTone.extend(Tone.Scale, Tone.SignalBase);\n\n\t/**\n\t * The minimum output value. This number is output when \n\t * the value input value is 0. \n\t * @memberOf Tone.Scale#\n\t * @type {number}\n\t * @name min\n\t */\n\tObject.defineProperty(Tone.Scale.prototype, \"min\", {\n\t\tget : function(){\n\t\t\treturn this._outputMin;\n\t\t},\n\t\tset : function(min){\n\t\t\tthis._outputMin = min;\n\t\t\tthis._setRange();\n\t\t}\n\t});\n\n\t/**\n\t * The maximum output value. This number is output when \n\t * the value input value is 1. \n\t * @memberOf Tone.Scale#\n\t * @type {number}\n\t * @name max\n\t */\n\tObject.defineProperty(Tone.Scale.prototype, \"max\", {\n\t\tget : function(){\n\t\t\treturn this._outputMax;\n\t\t},\n\t\tset : function(max){\n\t\t\tthis._outputMax = max;\n\t\t\tthis._setRange();\n\t\t}\n\t});\n\n\t/**\n\t * set the values\n\t * @private\n\t */\n\tTone.Scale.prototype._setRange = function() {\n\t\tthis._add.value = this._outputMin;\n\t\tthis._scale.value = this._outputMax - this._outputMin;\n\t};\n\n\t/**\n\t * Clean up.\n\t * @returns {Tone.Scale} this\n\t */\n\tTone.Scale.prototype.dispose = function(){\n\t\tTone.prototype.dispose.call(this);\n\t\tthis._add.dispose();\n\t\tthis._add = null;\n\t\tthis._scale.dispose();\n\t\tthis._scale = null;\n\t\treturn this;\n\t}; \n\n\treturn Tone.Scale;\n});\n","define([\"Tone/core/Tone\", \"Tone/signal/Signal\", \"Tone/core/Timeline\"], function (Tone) {\n\n\t\"use strict\";\n\n\t/**\n\t * @class A signal which adds the method getValueAtTime. \n\t * Code and inspiration from https://github.com/jsantell/web-audio-automation-timeline\n\t * @extends {Tone.Param}\n\t * @param {Number=} value The initial value of the signal\n\t * @param {String=} units The conversion units of the signal.\n\t */\n\tTone.TimelineSignal = function(){\n\n\t\tvar options = this.optionsObject(arguments, [\"value\", \"units\"], Tone.Signal.defaults);\n\t\t\n\t\t/**\n\t\t * The scheduled events\n\t\t * @type {Tone.Timeline}\n\t\t * @private\n\t\t */\n\t\tthis._events = new Tone.Timeline(10);\n\n\t\t//constructors\n\t\tTone.Signal.apply(this, options);\n\t\toptions.param = this._param;\n\t\tTone.Param.call(this, options);\n\n\t\t/**\n\t\t * The initial scheduled value\n\t\t * @type {Number}\n\t\t * @private\n\t\t */\n\t\tthis._initial = this._fromUnits(this._param.value);\n\t};\n\n\tTone.extend(Tone.TimelineSignal, Tone.Param);\n\n\t/**\n\t * The event types of a schedulable signal.\n\t * @enum {String}\n\t * @private\n\t */\n\tTone.TimelineSignal.Type = {\n\t\tLinear : \"linear\",\n\t\tExponential : \"exponential\",\n\t\tTarget : \"target\",\n\t\tCurve : \"curve\",\n\t\tSet : \"set\"\n\t};\n\n\t/**\n\t * The current value of the signal. \n\t * @memberOf Tone.TimelineSignal#\n\t * @type {Number}\n\t * @name value\n\t */\n\tObject.defineProperty(Tone.TimelineSignal.prototype, \"value\", {\n\t\tget : function(){\n\t\t\tvar now = this.now();\n\t\t\tvar val = this.getValueAtTime(now);\n\t\t\treturn this._toUnits(val);\n\t\t},\n\t\tset : function(value){\n\t\t\tvar convertedVal = this._fromUnits(value);\n\t\t\tthis._initial = convertedVal;\n\t\t\tthis.cancelScheduledValues();\n\t\t\tthis._param.value = convertedVal;\n\t\t}\n\t});\n\n\t///////////////////////////////////////////////////////////////////////////\n\t//\tSCHEDULING\n\t///////////////////////////////////////////////////////////////////////////\n\n\t/**\n\t * Schedules a parameter value change at the given time.\n\t * @param {*}\tvalue The value to set the signal.\n\t * @param {Time} time The time when the change should occur.\n\t * @returns {Tone.TimelineSignal} this\n\t * @example\n\t * //set the frequency to \"G4\" in exactly 1 second from now. \n\t * freq.setValueAtTime(\"G4\", \"+1\");\n\t */\n\tTone.TimelineSignal.prototype.setValueAtTime = function (value, startTime) {\n\t\tvalue = this._fromUnits(value);\n\t\tstartTime = this.toSeconds(startTime);\n\t\tthis._events.add({\n\t\t\t\"type\" : Tone.TimelineSignal.Type.Set,\n\t\t\t\"value\" : value,\n\t\t\t\"time\" : startTime\n\t\t});\n\t\t//invoke the original event\n\t\tthis._param.setValueAtTime(value, startTime);\n\t\treturn this;\n\t};\n\n\t/**\n\t * Schedules a linear continuous change in parameter value from the \n\t * previous scheduled parameter value to the given value.\n\t * \n\t * @param {number} value \n\t * @param {Time} endTime \n\t * @returns {Tone.TimelineSignal} this\n\t */\n\tTone.TimelineSignal.prototype.linearRampToValueAtTime = function (value, endTime) {\n\t\tvalue = this._fromUnits(value);\n\t\tendTime = this.toSeconds(endTime);\n\t\tthis._events.add({\n\t\t\t\"type\" : Tone.TimelineSignal.Type.Linear,\n\t\t\t\"value\" : value,\n\t\t\t\"time\" : endTime\n\t\t});\n\t\tthis._param.linearRampToValueAtTime(value, endTime);\n\t\treturn this;\n\t};\n\n\t/**\n\t * Schedules an exponential continuous change in parameter value from \n\t * the previous scheduled parameter value to the given value.\n\t * \n\t * @param {number} value \n\t * @param {Time} endTime \n\t * @returns {Tone.TimelineSignal} this\n\t */\n\tTone.TimelineSignal.prototype.exponentialRampToValueAtTime = function (value, endTime) {\n\t\t//get the previous event and make sure it's not starting from 0\n\t\tendTime = this.toSeconds(endTime);\n\t\tvar beforeEvent = this._searchBefore(endTime);\n\t\tif (beforeEvent && beforeEvent.value === 0){\n\t\t\t//reschedule that event\n\t\t\tthis.setValueAtTime(this._minOutput, beforeEvent.time);\n\t\t}\n\t\tvalue = this._fromUnits(value);\n\t\tvar setValue = Math.max(value, this._minOutput);\n\t\tthis._events.add({\n\t\t\t\"type\" : Tone.TimelineSignal.Type.Exponential,\n\t\t\t\"value\" : setValue,\n\t\t\t\"time\" : endTime\n\t\t});\n\t\t//if the ramped to value is 0, make it go to the min output, and then set to 0.\n\t\tif (value < this._minOutput){\n\t\t\tthis._param.exponentialRampToValueAtTime(this._minOutput, endTime - this.sampleTime);\n\t\t\tthis.setValueAtTime(0, endTime);\n\t\t} else {\n\t\t\tthis._param.exponentialRampToValueAtTime(value, endTime);\n\t\t}\n\t\treturn this;\n\t};\n\n\t/**\n\t * Start exponentially approaching the target value at the given time with\n\t * a rate having the given time constant.\n\t * @param {number} value \n\t * @param {Time} startTime \n\t * @param {number} timeConstant \n\t * @returns {Tone.TimelineSignal} this \n\t */\n\tTone.TimelineSignal.prototype.setTargetAtTime = function (value, startTime, timeConstant) {\n\t\tvalue = this._fromUnits(value);\n\t\tvalue = Math.max(this._minOutput, value);\n\t\ttimeConstant = Math.max(this._minOutput, timeConstant);\n\t\tstartTime = this.toSeconds(startTime);\n\t\tthis._events.add({\n\t\t\t\"type\" : Tone.TimelineSignal.Type.Target,\n\t\t\t\"value\" : value,\n\t\t\t\"time\" : startTime,\n\t\t\t\"constant\" : timeConstant\n\t\t});\n\t\tthis._param.setTargetAtTime(value, startTime, timeConstant);\n\t\treturn this;\n\t};\n\n\t/**\n\t * Set an array of arbitrary values starting at the given time for the given duration.\n\t * @param {Float32Array} values \n\t * @param {Time} startTime \n\t * @param {Time} duration\n\t * @param {NormalRange} [scaling=1] If the values in the curve should be scaled by some value\n\t * @returns {Tone.TimelineSignal} this \n\t */\n\tTone.TimelineSignal.prototype.setValueCurveAtTime = function (values, startTime, duration, scaling) {\n\t\tscaling = this.defaultArg(scaling, 1);\n\t\t//copy the array\n\t\tvar floats = new Array(values.length);\n\t\tfor (var i = 0; i < floats.length; i++){\n\t\t\tfloats[i] = this._fromUnits(values[i]) * scaling;\n\t\t}\n\t\tstartTime = this.toSeconds(startTime);\n\t\tduration = this.toSeconds(duration);\n\t\tthis._events.add({\n\t\t\t\"type\" : Tone.TimelineSignal.Type.Curve,\n\t\t\t\"value\" : floats,\n\t\t\t\"time\" : startTime,\n\t\t\t\"duration\" : duration\n\t\t});\n\t\t//set the first value\n\t\tthis._param.setValueAtTime(floats[0], startTime);\n\t\t//schedule a lienar ramp for each of the segments\n\t\tfor (var j = 1; j < floats.length; j++){\n\t\t\tvar segmentTime = startTime + (j / (floats.length - 1) * duration);\n\t\t\tthis._param.linearRampToValueAtTime(floats[j], segmentTime);\n\t\t}\n\t\treturn this;\n\t};\n\n\t/**\n\t * Cancels all scheduled parameter changes with times greater than or \n\t * equal to startTime.\n\t * \n\t * @param {Time} startTime\n\t * @returns {Tone.TimelineSignal} this\n\t */\n\tTone.TimelineSignal.prototype.cancelScheduledValues = function (after) {\n\t\tafter = this.toSeconds(after);\n\t\tthis._events.cancel(after);\n\t\tthis._param.cancelScheduledValues(after);\n\t\treturn this;\n\t};\n\n\t/**\n\t * Sets the computed value at the given time. This provides\n\t * a point from which a linear or exponential curve\n\t * can be scheduled after. Will cancel events after \n\t * the given time and shorten the currently scheduled\n\t * linear or exponential ramp so that it ends at `time` .\n\t * This is to avoid discontinuities and clicks in envelopes. \n\t * @param {Time} time When to set the ramp point\n\t * @returns {Tone.TimelineSignal} this\n\t */\n\tTone.TimelineSignal.prototype.setRampPoint = function (time) {\n\t\ttime = this.toSeconds(time);\n\t\t//get the value at the given time\n\t\tvar val = this._toUnits(this.getValueAtTime(time));\n\t\t//if there is an event at the given time\n\t\t//and that even is not a \"set\"\n\t\tvar before = this._searchBefore(time);\n\t\tif (before && before.time === time){\n\t\t\t//remove everything after\n\t\t\tthis.cancelScheduledValues(time + this.sampleTime);\n\t\t} else if (before && \n\t\t\t\t before.type === Tone.TimelineSignal.Type.Curve &&\n\t\t\t\t before.time + before.duration > time){\n\t\t\t//if the curve is still playing\n\t\t\t//cancel the curve\n\t\t\tthis.cancelScheduledValues(time);\n\t\t\tthis.linearRampToValueAtTime(val, time);\n\t\t} else {\n\t\t\t//reschedule the next event to end at the given time\n\t\t\tvar after = this._searchAfter(time);\n\t\t\tif (after){\n\t\t\t\t//cancel the next event(s)\n\t\t\t\tthis.cancelScheduledValues(time);\n\t\t\t\tif (after.type === Tone.TimelineSignal.Type.Linear){\n\t\t\t\t\tthis.linearRampToValueAtTime(val, time);\n\t\t\t\t} else if (after.type === Tone.TimelineSignal.Type.Exponential){\n\t\t\t\t\tthis.exponentialRampToValueAtTime(val, time);\n\t\t\t\t}\n\t\t\t}\n\t\t\tthis.setValueAtTime(val, time);\n\t\t}\n\t\treturn this;\n\t};\n\n\t/**\n\t * Do a linear ramp to the given value between the start and finish times.\n\t * @param {Number} value The value to ramp to.\n\t * @param {Time} start The beginning anchor point to do the linear ramp\n\t * @param {Time} finish The ending anchor point by which the value of\n\t * the signal will equal the given value.\n\t * @returns {Tone.TimelineSignal} this\n\t */\n\tTone.TimelineSignal.prototype.linearRampToValueBetween = function (value, start, finish) {\n\t\tthis.setRampPoint(start);\n\t\tthis.linearRampToValueAtTime(value, finish);\n\t\treturn this;\n\t};\n\n\t/**\n\t * Do a exponential ramp to the given value between the start and finish times.\n\t * @param {Number} value The value to ramp to.\n\t * @param {Time} start The beginning anchor point to do the exponential ramp\n\t * @param {Time} finish The ending anchor point by which the value of\n\t * the signal will equal the given value.\n\t * @returns {Tone.TimelineSignal} this\n\t */\n\tTone.TimelineSignal.prototype.exponentialRampToValueBetween = function (value, start, finish) {\n\t\tthis.setRampPoint(start);\n\t\tthis.exponentialRampToValueAtTime(value, finish);\n\t\treturn this;\n\t};\n\n\t///////////////////////////////////////////////////////////////////////////\n\t//\tGETTING SCHEDULED VALUES\n\t///////////////////////////////////////////////////////////////////////////\n\n\t/**\n\t * Returns the value before or equal to the given time\n\t * @param {Number} time The time to query\n\t * @return {Object} The event at or before the given time.\n\t * @private\n\t */\n\tTone.TimelineSignal.prototype._searchBefore = function(time){\n\t\treturn this._events.get(time);\n\t};\n\n\t/**\n\t * The event after the given time\n\t * @param {Number} time The time to query.\n\t * @return {Object} The next event after the given time\n\t * @private\n\t */\n\tTone.TimelineSignal.prototype._searchAfter = function(time){\n\t\treturn this._events.getAfter(time);\n\t};\n\n\t/**\n\t * Get the scheduled value at the given time. This will\n\t * return the unconverted (raw) value.\n\t * @param {Number} time The time in seconds.\n\t * @return {Number} The scheduled value at the given time.\n\t */\n\tTone.TimelineSignal.prototype.getValueAtTime = function(time){\n\t\ttime = this.toSeconds(time);\n\t\tvar after = this._searchAfter(time);\n\t\tvar before = this._searchBefore(time);\n\t\tvar value = this._initial;\n\t\t//if it was set by\n\t\tif (before === null){\n\t\t\tvalue = this._initial;\n\t\t} else if (before.type === Tone.TimelineSignal.Type.Target){\n\t\t\tvar previous = this._events.getBefore(before.time);\n\t\t\tvar previouVal;\n\t\t\tif (previous === null){\n\t\t\t\tpreviouVal = this._initial;\n\t\t\t} else {\n\t\t\t\tpreviouVal = previous.value;\n\t\t\t}\n\t\t\tvalue = this._exponentialApproach(before.time, previouVal, before.value, before.constant, time);\n\t\t} else if (before.type === Tone.TimelineSignal.Type.Curve){\n\t\t\tvalue = this._curveInterpolate(before.time, before.value, before.duration, time);\n\t\t} else if (after === null){\n\t\t\tvalue = before.value;\n\t\t} else if (after.type === Tone.TimelineSignal.Type.Linear){\n\t\t\tvalue = this._linearInterpolate(before.time, before.value, after.time, after.value, time);\n\t\t} else if (after.type === Tone.TimelineSignal.Type.Exponential){\n\t\t\tvalue = this._exponentialInterpolate(before.time, before.value, after.time, after.value, time);\n\t\t} else {\n\t\t\tvalue = before.value;\n\t\t}\n\t\treturn value;\n\t};\n\n\t/**\n\t * When signals connect to other signals or AudioParams, \n\t * they take over the output value of that signal or AudioParam. \n\t * For all other nodes, the behavior is the same as a default connect. \n\t *\n\t * @override\n\t * @param {AudioParam|AudioNode|Tone.Signal|Tone} node \n\t * @param {number} [outputNumber=0] The output number to connect from.\n\t * @param {number} [inputNumber=0] The input number to connect to.\n\t * @returns {Tone.TimelineSignal} this\n\t * @method\n\t */\n\tTone.TimelineSignal.prototype.connect = Tone.SignalBase.prototype.connect;\n\n\n\t///////////////////////////////////////////////////////////////////////////\n\t//\tAUTOMATION CURVE CALCULATIONS\n\t//\tMIT License, copyright (c) 2014 Jordan Santell\n\t///////////////////////////////////////////////////////////////////////////\n\n\t/**\n\t * Calculates the the value along the curve produced by setTargetAtTime\n\t * @private\n\t */\n\tTone.TimelineSignal.prototype._exponentialApproach = function (t0, v0, v1, timeConstant, t) {\n\t\treturn v1 + (v0 - v1) * Math.exp(-(t - t0) / timeConstant);\n\t};\n\n\t/**\n\t * Calculates the the value along the curve produced by linearRampToValueAtTime\n\t * @private\n\t */\n\tTone.TimelineSignal.prototype._linearInterpolate = function (t0, v0, t1, v1, t) {\n\t\treturn v0 + (v1 - v0) * ((t - t0) / (t1 - t0));\n\t};\n\n\t/**\n\t * Calculates the the value along the curve produced by exponentialRampToValueAtTime\n\t * @private\n\t */\n\tTone.TimelineSignal.prototype._exponentialInterpolate = function (t0, v0, t1, v1, t) {\n\t\tv0 = Math.max(this._minOutput, v0);\n\t\treturn v0 * Math.pow(v1 / v0, (t - t0) / (t1 - t0));\n\t};\n\n\t/**\n\t * Calculates the the value along the curve produced by setValueCurveAtTime\n\t * @private\n\t */\n\tTone.TimelineSignal.prototype._curveInterpolate = function (start, curve, duration, time) {\n\t\tvar len = curve.length;\n\t\t// If time is after duration, return the last curve value\n\t\tif (time >= start + duration) {\n\t\t\treturn curve[len - 1];\n\t\t} else if (time <= start){\n\t\t\treturn curve[0];\n\t\t} else {\n\t\t\tvar progress = (time - start) / duration;\n\t\t\tvar lowerIndex = Math.floor((len - 1) * progress);\n\t\t\tvar upperIndex = Math.ceil((len - 1) * progress);\n\t\t\tvar lowerVal = curve[lowerIndex];\n\t\t\tvar upperVal = curve[upperIndex];\n\t\t\tif (upperIndex === lowerIndex){\n\t\t\t\treturn lowerVal;\n\t\t\t} else {\n\t\t\t\treturn this._linearInterpolate(lowerIndex, lowerVal, upperIndex, upperVal, progress * (len - 1));\n\t\t\t}\n\t\t}\n\t};\n\n\t/**\n\t * Clean up.\n\t * @return {Tone.TimelineSignal} this\n\t */\n\tTone.TimelineSignal.prototype.dispose = function(){\n\t\tTone.Signal.prototype.dispose.call(this);\n\t\tTone.Param.prototype.dispose.call(this);\n\t\tthis._events.dispose();\n\t\tthis._events = null;\n\t};\n\n\treturn Tone.TimelineSignal;\n});","'use strict';\n\ndefine(function (require) {\n var Effect = require('effect');\n\n /**\n *
A p5.Filter uses a Web Audio Biquad Filter to filter\n * the frequency response of an input source. Subclasses\n * include:
\n * p5.LowPass:\n * Allows frequencies below the cutoff frequency to pass through,\n * and attenuates frequencies above the cutoff. \n * p5.HighPass:\n * The opposite of a lowpass filter. \n * p5.BandPass:\n * Allows a range of frequencies to pass through and attenuates\n * the frequencies below and above this frequency range. \n *\n * The .res() method controls either width of the\n * bandpass, or resonance of the low/highpass cutoff frequency.\n *\n * This class extends p5.Effect.\n * Methods amp(), chain(),\n * drywet(), connect(), and\n * disconnect() are available.\n *\n * @class p5.Filter\n * @extends p5.Effect\n * @constructor\n * @param {String} [type] 'lowpass' (default), 'highpass', 'bandpass'\n * @example\n *
\n * var fft, noise, filter;\n *\n * function setup() {\n * fill(255, 40, 255);\n *\n * filter = new p5.BandPass();\n *\n * noise = new p5.Noise();\n * // disconnect unfiltered noise,\n * // and connect to filter\n * noise.disconnect();\n * noise.connect(filter);\n * noise.start();\n *\n * fft = new p5.FFT();\n * }\n *\n * function draw() {\n * background(30);\n *\n * // set the BandPass frequency based on mouseX\n * var freq = map(mouseX, 0, width, 20, 10000);\n * filter.freq(freq);\n * // give the filter a narrow band (lower res = wider bandpass)\n * filter.res(50);\n *\n * // draw filtered spectrum\n * var spectrum = fft.analyze();\n * noStroke();\n * for (var i = 0; i < spectrum.length; i++) {\n * var x = map(i, 0, spectrum.length, 0, width);\n * var h = -height + map(spectrum[i], 0, 255, height, 0);\n * rect(x, height, width/spectrum.length, h);\n * }\n *\n * isMouseOverCanvas();\n * }\n *\n * function isMouseOverCanvas() {\n * var mX = mouseX, mY = mouseY;\n * if (mX > 0 && mX < width && mY < height && mY > 0) {\n * noise.amp(0.5, 0.2);\n * } else {\n * noise.amp(0, 0.2);\n * }\n * }\n *
\n */\n p5.Filter = function (type) {\n\n Effect.call(this);\n //add extend Effect by adding a Biquad Filter\n\n /**\n * The p5.Filter is built with a\n * \n * Web Audio BiquadFilter Node.\n *\n * @property {DelayNode} biquadFilter\n\t */\n\n this.biquad = this.ac.createBiquadFilter();\n\n this.input.connect(this.biquad);\n\n this.biquad.connect(this.wet);\n\n if (type) {\n this.setType(type);\n }\n\n //Properties useful for the toggle method.\n this._on = true;\n this._untoggledType = this.biquad.type;\n };\n p5.Filter.prototype = Object.create(Effect.prototype);\n\n\n /**\n * Filter an audio signal according to a set\n * of filter parameters.\n *\n * @method process\n * @param {Object} Signal An object that outputs audio\n * @param {Number} [freq] Frequency in Hz, from 10 to 22050\n * @param {Number} [res] Resonance/Width of the filter frequency\n * from 0.001 to 1000\n */\n p5.Filter.prototype.process = function(src, freq, res, time) {\n src.connect(this.input);\n this.set(freq, res, time);\n };\n\n\n /**\n * Set the frequency and the resonance of the filter.\n *\n * @method set\n * @param {Number} [freq] Frequency in Hz, from 10 to 22050\n * @param {Number} [res] Resonance (Q) from 0.001 to 1000\n * @param {Number} [timeFromNow] schedule this event to happen\n * seconds from now\n */\n p5.Filter.prototype.set = function(freq, res, time) {\n if (freq) {\n this.freq(freq, time);\n }\n if (res) {\n this.res(res, time);\n }\n };\n\n /**\n * Set the filter frequency, in Hz, from 10 to 22050 (the range of\n * human hearing, although in reality most people hear in a narrower\n * range).\n *\n * @method freq\n * @param {Number} freq Filter Frequency\n * @param {Number} [timeFromNow] schedule this event to happen\n * seconds from now\n * @return {Number} value Returns the current frequency value\n */\n p5.Filter.prototype.freq = function(freq, time) {\n var t = time || 0;\n if (freq <= 0) {\n freq = 1;\n }\n if (typeof freq === 'number') {\n this.biquad.frequency.cancelScheduledValues(this.ac.currentTime + 0.01 + t);\n this.biquad.frequency.exponentialRampToValueAtTime(freq, this.ac.currentTime + 0.02 + t);\n } else if (freq) {\n freq.connect(this.biquad.frequency);\n }\n return this.biquad.frequency.value;\n };\n\n /**\n * Controls either width of a bandpass frequency,\n * or the resonance of a low/highpass cutoff frequency.\n *\n * @method res\n * @param {Number} res Resonance/Width of filter freq\n * from 0.001 to 1000\n * @param {Number} [timeFromNow] schedule this event to happen\n * seconds from now\n * @return {Number} value Returns the current res value\n */\n p5.Filter.prototype.res = function(res, time) {\n var t = time || 0;\n if (typeof res === 'number') {\n this.biquad.Q.value = res;\n this.biquad.Q.cancelScheduledValues(this.ac.currentTime + 0.01 + t);\n this.biquad.Q.linearRampToValueAtTime(res, this.ac.currentTime + 0.02 + t);\n } else if (res) {\n res.connect(this.biquad.Q);\n }\n return this.biquad.Q.value;\n };\n\n /**\n * Controls the gain attribute of a Biquad Filter.\n * This is distinctly different from .amp() which is inherited from p5.Effect\n * .amp() controls the volume via the output gain node\n * p5.Filter.gain() controls the gain parameter of a Biquad Filter node.\n *\n * @method gain\n * @param {Number} gain\n * @return {Number} Returns the current or updated gain value\n */\n p5.Filter.prototype.gain = function(gain, time) {\n var t = time || 0;\n if (typeof gain === 'number') {\n this.biquad.gain.value = gain;\n this.biquad.gain.cancelScheduledValues(this.ac.currentTime + 0.01 + t);\n this.biquad.gain.linearRampToValueAtTime(gain, this.ac.currentTime + 0.02 + t);\n } else if (gain) {\n gain.connect(this.biquad.gain);\n }\n return this.biquad.gain.value;\n };\n\n\n /**\n * Toggle function. Switches between the specified type and allpass\n *\n * @method toggle\n * @return {boolean} [Toggle value]\n */\n p5.Filter.prototype.toggle = function() {\n this._on = !this._on;\n\n if (this._on === true) {\n this.biquad.type = this._untoggledType;\n } else if (this._on === false) {\n this.biquad.type = 'allpass';\n }\n\n return this._on;\n };\n\n /**\n * Set the type of a p5.Filter. Possible types include:\n * \"lowpass\" (default), \"highpass\", \"bandpass\",\n * \"lowshelf\", \"highshelf\", \"peaking\", \"notch\",\n * \"allpass\".\n *\n * @method setType\n * @param {String} t\n */\n p5.Filter.prototype.setType = function(t) {\n this.biquad.type = t;\n this._untoggledType = this.biquad.type;\n };\n\n p5.Filter.prototype.dispose = function() {\n // remove reference from soundArray\n Effect.prototype.dispose.apply(this);\n if (this.biquad) {\n this.biquad.disconnect();\n delete this.biquad;\n }\n };\n\n /**\n * Constructor: new p5.LowPass() Filter.\n * This is the same as creating a p5.Filter and then calling\n * its method setType('lowpass').\n * See p5.Filter for methods.\n *\n * @class p5.LowPass\n * @constructor\n * @extends p5.Filter\n */\n p5.LowPass = function() {\n p5.Filter.call(this, 'lowpass');\n };\n p5.LowPass.prototype = Object.create(p5.Filter.prototype);\n\n /**\n * Constructor: new p5.HighPass() Filter.\n * This is the same as creating a p5.Filter and then calling\n * its method setType('highpass').\n * See p5.Filter for methods.\n *\n * @class p5.HighPass\n * @constructor\n * @extends p5.Filter\n */\n p5.HighPass = function() {\n p5.Filter.call(this, 'highpass');\n };\n p5.HighPass.prototype = Object.create(p5.Filter.prototype);\n\n /**\n * Constructor: new p5.BandPass() Filter.\n * This is the same as creating a p5.Filter and then calling\n * its method setType('bandpass').\n * See p5.Filter for methods.\n *\n * @class p5.BandPass\n * @constructor\n * @extends p5.Filter\n */\n p5.BandPass = function() {\n p5.Filter.call(this, 'bandpass');\n };\n p5.BandPass.prototype = Object.create(p5.Filter.prototype);\n\n return p5.Filter;\n});\n","define([\"Tone/core/Tone\", \"Tone/signal/Add\", \"Tone/signal/Negate\", \"Tone/signal/Signal\", \"Tone/core/Gain\"], function(Tone){\n\n\t\"use strict\";\n\n\t/**\n\t * @class Subtract the signal connected to input[1] from the signal connected \n\t * to input[0]. If an argument is provided in the constructor, the \n\t * signals .value will be subtracted from the incoming signal.\n\t *\n\t * @extends {Tone.Signal}\n\t * @constructor\n\t * @param {number=} value The value to subtract from the incoming signal. If the value\n\t * is omitted, it will subtract the second signal from the first.\n\t * @example\n\t * var sub = new Tone.Subtract(1);\n\t * var sig = new Tone.Signal(4).connect(sub);\n\t * //the output of sub is 3. \n\t * @example\n\t * var sub = new Tone.Subtract();\n\t * var sigA = new Tone.Signal(10);\n\t * var sigB = new Tone.Signal(2.5);\n\t * sigA.connect(sub, 0, 0);\n\t * sigB.connect(sub, 0, 1);\n\t * //output of sub is 7.5\n\t */\n\tTone.Subtract = function(value){\n\n\t\tthis.createInsOuts(2, 0);\n\n\t\t/**\n\t\t * the summing node\n\t\t * @type {GainNode}\n\t\t * @private\n\t\t */\n\t\tthis._sum = this.input[0] = this.output = new Tone.Gain();\n\n\t\t/**\n\t\t * negate the input of the second input before connecting it\n\t\t * to the summing node.\n\t\t * @type {Tone.Negate}\n\t\t * @private\n\t\t */\n\t\tthis._neg = new Tone.Negate();\n\n\t\t/**\n\t\t * the node where the value is set\n\t\t * @private\n\t\t * @type {Tone.Signal}\n\t\t */\n\t\tthis._param = this.input[1] = new Tone.Signal(value);\n\n\t\tthis._param.chain(this._neg, this._sum);\n\t};\n\n\tTone.extend(Tone.Subtract, Tone.Signal);\n\n\t/**\n\t * Clean up.\n\t * @returns {Tone.SignalBase} this\n\t */\n\tTone.Subtract.prototype.dispose = function(){\n\t\tTone.prototype.dispose.call(this);\n\t\tthis._neg.dispose();\n\t\tthis._neg = null;\n\t\tthis._sum.disconnect();\n\t\tthis._sum = null;\n\t\tthis._param.dispose();\n\t\tthis._param = null;\n\t\treturn this;\n\t};\n\n\treturn Tone.Subtract;\n});","'use strict';\n\nglobal.TONE_SILENCE_VERSION_LOGGING = true;\n\ndefine(['startaudiocontext', 'Tone/core/Context', 'Tone/core/Tone'], function (StartAudioContext, Context, Tone) {\n // Create the Audio Context\n const audiocontext = new window.AudioContext();\n\n // Tone and p5.sound share the same audio context\n Tone.context.dispose();\n Tone.setContext(audiocontext);\n\n /**\n *
Returns the Audio Context for this sketch. Useful for users\n * who would like to dig deeper into the Web Audio API\n * .
\n *\n *
Some browsers require users to startAudioContext\n * with a user gesture, such as touchStarted in the example below.
\n *\n * @method getAudioContext\n * @return {Object} AudioContext for this sketch\n * @example\n *
\n * function draw() {\n * background(255);\n * textAlign(CENTER);\n *\n * if (getAudioContext().state !== 'running') {\n * text('click to start audio', width/2, height/2);\n * } else {\n * text('audio is enabled', width/2, height/2);\n * }\n * }\n *\n * function touchStarted() {\n * if (getAudioContext().state !== 'running') {\n * getAudioContext().resume();\n * }\n * var synth = new p5.MonoSynth();\n * synth.play('A4', 0.5, 0, 0.2);\n * }\n *\n *
It is a good practice to give users control over starting audio playback.\n * This practice is enforced by Google Chrome's autoplay policy as of r70\n * (info), iOS Safari, and other browsers.\n *
\n *\n *
\n * userStartAudio() starts the Audio Context on a user gesture. It utilizes\n * the StartAudioContext library by\n * Yotam Mann (MIT Licence, 2016). Read more at https://github.com/tambien/StartAudioContext.\n *
\n *\n *
Starting the audio context on a user gesture can be as simple as userStartAudio().\n * Optional parameters let you decide on a specific element that will start the audio context,\n * and/or call a function once the audio context is started.
\n * @param {Element|Array} [element(s)] This argument can be an Element,\n * Selector String, NodeList, p5.Element,\n * jQuery Element, or an Array of any of those.\n * @param {Function} [callback] Callback to invoke when the AudioContext has started\n * @return {Promise} Returns a Promise which is resolved when\n * the AudioContext state is 'running'\n * @method userStartAudio\n * @for p5\n * @example\n *
\n * function setup() {\n * var myDiv = createDiv('click to start audio');\n * myDiv.position(0, 0);\n *\n * var mySynth = new p5.MonoSynth();\n *\n * // This won't play until the context has started\n * mySynth.play('A6');\n *\n * // Start the audio context on a click/touch event\n * userStartAudio().then(function() {\n * myDiv.remove();\n * });\n * }\n *
\n */\n p5.prototype.userStartAudio = function(elements, callback) {\n var elt = elements;\n if (elements instanceof p5.Element) {\n elt = elements.elt;\n } else if (elements instanceof Array && elements[0] instanceof p5.Element ) {\n elt = elements.map(function(e) { return e.elt});\n }\n return StartAudioContext(audiocontext, elt, callback);\n };\n\n return audiocontext;\n});\n","define([\"Tone/core/Tone\"], function (Tone) {\n\n\t\"use strict\";\n\n\t/**\n\t * @class Tone.Emitter gives classes which extend it\n\t * the ability to listen for and emit events. \n\t * Inspiration and reference from Jerome Etienne's [MicroEvent](https://github.com/jeromeetienne/microevent.js).\n\t * MIT (c) 2011 Jerome Etienne.\n\t * \n\t * @extends {Tone}\n\t */\n\tTone.Emitter = function(){\n\t\t/**\n\t\t * Contains all of the events.\n\t\t * @private\n\t\t * @type {Object}\n\t\t */\n\t\tthis._events = {};\n\t};\n\n\tTone.extend(Tone.Emitter);\n\n\t/**\n\t * Bind a callback to a specific event.\n\t * @param {String} event The name of the event to listen for.\n\t * @param {Function} callback The callback to invoke when the\n\t * event is emitted\n\t * @return {Tone.Emitter} this\n\t */\n\tTone.Emitter.prototype.on = function(event, callback){\n\t\t//split the event\n\t\tvar events = event.split(/\\W+/);\n\t\tfor (var i = 0; i < events.length; i++){\n\t\t\tvar eventName = events[i];\n\t\t\tif (!this._events.hasOwnProperty(eventName)){\n\t\t\t\tthis._events[eventName] = [];\n\t\t\t}\n\t\t\tthis._events[eventName].push(callback);\n\t\t}\n\t\treturn this;\n\t};\n\n\t/**\n\t * Remove the event listener.\n\t * @param {String} event The event to stop listening to.\n\t * @param {Function=} callback The callback which was bound to \n\t * the event with Tone.Emitter.on.\n\t * If no callback is given, all callbacks\n\t * events are removed.\n\t * @return {Tone.Emitter} this\n\t */\n\tTone.Emitter.prototype.off = function(event, callback){\n\t\tvar events = event.split(/\\W+/);\n\t\tfor (var ev = 0; ev < events.length; ev++){\n\t\t\tevent = events[ev];\n\t\t\tif (this._events.hasOwnProperty(event)){\n\t\t\t\tif (Tone.prototype.isUndef(callback)){\n\t\t\t\t\tthis._events[event] = [];\n\t\t\t\t} else {\n\t\t\t\t\tvar eventList = this._events[event];\n\t\t\t\t\tfor (var i = 0; i < eventList.length; i++){\n\t\t\t\t\t\tif (eventList[i] === callback){\n\t\t\t\t\t\t\teventList.splice(i, 1);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\treturn this;\n\t};\n\n\t/**\n\t * Invoke all of the callbacks bound to the event\n\t * with any arguments passed in. \n\t * @param {String} event The name of the event.\n\t * @param {*...} args The arguments to pass to the functions listening.\n\t * @return {Tone.Emitter} this\n\t */\n\tTone.Emitter.prototype.emit = function(event){\n\t\tif (this._events){\n\t\t\tvar args = Array.apply(null, arguments).slice(1);\n\t\t\tif (this._events.hasOwnProperty(event)){\n\t\t\t\tvar eventList = this._events[event];\n\t\t\t\tfor (var i = 0, len = eventList.length; i < len; i++){\n\t\t\t\t\teventList[i].apply(this, args);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\treturn this;\n\t};\n\n\t/**\n\t * Add Emitter functions (on/off/emit) to the object\n\t * @param {Object|Function} object The object or class to extend.\n\t */\n\tTone.Emitter.mixin = function(object){\n\t\tvar functions = [\"on\", \"off\", \"emit\"];\n\t\tobject._events = {};\n\t\tfor (var i = 0; i < functions.length; i++){\n\t\t\tvar func = functions[i];\n\t\t\tvar emitterFunc = Tone.Emitter.prototype[func];\n\t\t\tobject[func] = emitterFunc;\n\t\t}\n\t};\n\n\t/**\n\t * Clean up\n\t * @return {Tone.Emitter} this\n\t */\n\tTone.Emitter.prototype.dispose = function(){\n\t\tTone.prototype.dispose.call(this);\n\t\tthis._events = null;\n\t\treturn this;\n\t};\n\n\treturn Tone.Emitter;\n});","define([\"Tone/core/Tone\"], function(Tone){\n\n\t\"use strict\";\n\n\t/**\n\t * @class Base class for all Signals. Used Internally. \n\t *\n\t * @constructor\n\t * @extends {Tone}\n\t */\n\tTone.SignalBase = function(){};\n\n\tTone.extend(Tone.SignalBase);\n\n\t/**\n\t * When signals connect to other signals or AudioParams, \n\t * they take over the output value of that signal or AudioParam. \n\t * For all other nodes, the behavior is the same as a default connect. \n\t *\n\t * @override\n\t * @param {AudioParam|AudioNode|Tone.Signal|Tone} node \n\t * @param {number} [outputNumber=0] The output number to connect from.\n\t * @param {number} [inputNumber=0] The input number to connect to.\n\t * @returns {Tone.SignalBase} this\n\t */\n\tTone.SignalBase.prototype.connect = function(node, outputNumber, inputNumber){\n\t\t//zero it out so that the signal can have full control\n\t\tif ((Tone.Signal && Tone.Signal === node.constructor) || \n\t\t\t\t(Tone.Param && Tone.Param === node.constructor) || \n\t\t\t\t(Tone.TimelineSignal && Tone.TimelineSignal === node.constructor)){\n\t\t\t//cancel changes\n\t\t\tnode._param.cancelScheduledValues(0);\n\t\t\t//reset the value\n\t\t\tnode._param.value = 0;\n\t\t\t//mark the value as overridden\n\t\t\tnode.overridden = true;\n\t\t} else if (node instanceof AudioParam){\n\t\t\tnode.cancelScheduledValues(0);\n\t\t\tnode.value = 0;\n\t\t} \n\t\tTone.prototype.connect.call(this, node, outputNumber, inputNumber);\n\t\treturn this;\n\t};\n\n\treturn Tone.SignalBase;\n});","define([\"Tone/core/Tone\", \"Tone/type/TimeBase\"], function (Tone) {\n\n\t/**\n\t * @class Tone.Time is a primitive type for encoding Time values. \n\t * Eventually all time values are evaluated to seconds\n\t * using the `eval` method. Tone.Time can be constructed\n\t * with or without the `new` keyword. Tone.Time can be passed\n\t * into the parameter of any method which takes time as an argument. \n\t * @constructor\n\t * @extends {Tone.TimeBase}\n\t * @param {String|Number} val The time value.\n\t * @param {String=} units The units of the value.\n\t * @example\n\t * var t = Tone.Time(\"4n\");//encodes a quarter note\n\t * t.mult(4); // multiply that value by 4\n\t * t.toNotation(); //returns \"1m\"\n\t */\n\tTone.Time = function(val, units){\n\t\tif (this instanceof Tone.Time){\n\n\t\t\t/**\n\t\t\t * If the current clock time should\n\t\t\t * be added to the output\n\t\t\t * @type {Boolean}\n\t\t\t * @private\n\t\t\t */\n\t\t\tthis._plusNow = false;\n\t\t\t\n\t\t\tTone.TimeBase.call(this, val, units);\n\n\t\t} else {\n\t\t\treturn new Tone.Time(val, units);\n\t\t}\n\t};\n\n\tTone.extend(Tone.Time, Tone.TimeBase);\n\n\t//clone the expressions so that \n\t//we can add more without modifying the original\n\tTone.Time.prototype._unaryExpressions = Object.create(Tone.TimeBase.prototype._unaryExpressions);\n\n\t/*\n\t * Adds an additional unary expression\n\t * which quantizes values to the next subdivision\n\t * @type {Object}\n\t * @private\n\t */\n\tTone.Time.prototype._unaryExpressions.quantize = {\n\t\tregexp : /^@/,\n\t\tmethod : function(rh){\n\t\t\treturn Tone.Transport.nextSubdivision(rh());\n\t\t}\n\t};\n\n\t/*\n\t * Adds an additional unary expression\n\t * which adds the current clock time.\n\t * @type {Object}\n\t * @private\n\t */\n\tTone.Time.prototype._unaryExpressions.now = {\n\t\tregexp : /^\\+/,\n\t\tmethod : function(lh){\n\t\t\tthis._plusNow = true;\n\t\t\treturn lh();\n\t\t}\n\t};\n\n\t/**\n\t * Quantize the time by the given subdivision. Optionally add a\n\t * percentage which will move the time value towards the ideal\n\t * quantized value by that percentage. \n\t * @param {Number|Time} val The subdivision to quantize to\n\t * @param {NormalRange} [percent=1] Move the time value\n\t * towards the quantized value by\n\t * a percentage.\n\t * @return {Tone.Time} this\n\t * @example\n\t * Tone.Time(21).quantize(2) //returns 22\n\t * Tone.Time(0.6).quantize(\"4n\", 0.5) //returns 0.55\n\t */\n\tTone.Time.prototype.quantize = function(subdiv, percent){\n\t\tpercent = this.defaultArg(percent, 1);\n\t\tthis._expr = function(expr, subdivision, percent){\n\t\t\texpr = expr();\n\t\t\tsubdivision = subdivision.toSeconds();\n\t\t\tvar multiple = Math.round(expr / subdivision);\n\t\t\tvar ideal = multiple * subdivision;\n\t\t\tvar diff = ideal - expr;\n\t\t\treturn expr + diff * percent;\n\t\t}.bind(this, this._expr, new this.constructor(subdiv), percent);\n\t\treturn this;\n\t};\n\n\t/**\n\t * Adds the clock time to the time expression at the \n\t * moment of evaluation. \n\t * @return {Tone.Time} this\n\t */\n\tTone.Time.prototype.addNow = function(){\n\t\tthis._plusNow = true;\n\t\treturn this;\n\t};\n\n\t/**\n\t * @override\n\t * Override the default value return when no arguments are passed in.\n\t * The default value is 'now'\n\t * @private\n\t */\n\tTone.Time.prototype._defaultExpr = function(){\n\t\tthis._plusNow = true;\n\t\treturn this._noOp;\n\t};\n\n\t/**\n\t * Copies the value of time to this Time\n\t * @param {Tone.Time} time\n\t * @return {Time}\n\t */\n\tTone.Time.prototype.copy = function(time){\n\t\tTone.TimeBase.prototype.copy.call(this, time);\n\t\tthis._plusNow = time._plusNow;\n\t\treturn this;\n\t};\n\n\t//CONVERSIONS//////////////////////////////////////////////////////////////\n\n\t/**\n\t * Convert a Time to Notation. Values will be thresholded to the nearest 128th note. \n\t * @return {Notation} \n\t * @example\n\t * //if the Transport is at 120bpm:\n\t * Tone.Time(2).toNotation();//returns \"1m\"\n\t */\n\tTone.Time.prototype.toNotation = function(){\n\t\tvar time = this.toSeconds();\n\t\tvar testNotations = [\"1m\", \"2n\", \"4n\", \"8n\", \"16n\", \"32n\", \"64n\", \"128n\"];\n\t\tvar retNotation = this._toNotationHelper(time, testNotations);\n\t\t//try the same thing but with tripelets\n\t\tvar testTripletNotations = [\"1m\", \"2n\", \"2t\", \"4n\", \"4t\", \"8n\", \"8t\", \"16n\", \"16t\", \"32n\", \"32t\", \"64n\", \"64t\", \"128n\"];\n\t\tvar retTripletNotation = this._toNotationHelper(time, testTripletNotations);\n\t\t//choose the simpler expression of the two\n\t\tif (retTripletNotation.split(\"+\").length < retNotation.split(\"+\").length){\n\t\t\treturn retTripletNotation;\n\t\t} else {\n\t\t\treturn retNotation;\n\t\t}\n\t};\n\n\t/**\n\t * Helper method for Tone.toNotation\n\t * @param {Number} units \n\t * @param {Array} testNotations\n\t * @return {String}\n\t * @private\n\t */\n\tTone.Time.prototype._toNotationHelper = function(units, testNotations){\n\t\t//the threshold is the last value in the array\n\t\tvar threshold = this._notationToUnits(testNotations[testNotations.length - 1]);\n\t\tvar retNotation = \"\";\n\t\tfor (var i = 0; i < testNotations.length; i++){\n\t\t\tvar notationTime = this._notationToUnits(testNotations[i]);\n\t\t\t//account for floating point errors (i.e. round up if the value is 0.999999)\n\t\t\tvar multiple = units / notationTime;\n\t\t\tvar floatingPointError = 0.000001;\n\t\t\tif (1 - multiple % 1 < floatingPointError){\n\t\t\t\tmultiple += floatingPointError;\n\t\t\t}\n\t\t\tmultiple = Math.floor(multiple);\n\t\t\tif (multiple > 0){\n\t\t\t\tif (multiple === 1){\n\t\t\t\t\tretNotation += testNotations[i];\n\t\t\t\t} else {\n\t\t\t\t\tretNotation += multiple.toString() + \"*\" + testNotations[i];\n\t\t\t\t}\n\t\t\t\tunits -= multiple * notationTime;\n\t\t\t\tif (units < threshold){\n\t\t\t\t\tbreak;\n\t\t\t\t} else {\n\t\t\t\t\tretNotation += \" + \";\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tif (retNotation === \"\"){\n\t\t\tretNotation = \"0\";\n\t\t}\n\t\treturn retNotation;\n\t};\n\n\t/**\n\t * Convert a notation value to the current units\n\t * @param {Notation} notation \n\t * @return {Number} \n\t * @private\n\t */\n\tTone.Time.prototype._notationToUnits = function(notation){\n\t\tvar primaryExprs = this._primaryExpressions;\n\t\tvar notationExprs = [primaryExprs.n, primaryExprs.t, primaryExprs.m];\n\t\tfor (var i = 0; i < notationExprs.length; i++){\n\t\t\tvar expr = notationExprs[i];\n\t\t\tvar match = notation.match(expr.regexp);\n\t\t\tif (match){\n\t\t\t\treturn expr.method.call(this, match[1]);\n\t\t\t}\n\t\t}\n\t};\n\n\t/**\n\t * Return the time encoded as Bars:Beats:Sixteenths.\n\t * @return {BarsBeatsSixteenths}\n\t */\n\tTone.Time.prototype.toBarsBeatsSixteenths = function(){\n\t\tvar quarterTime = this._beatsToUnits(1);\n\t\tvar quarters = this.toSeconds() / quarterTime;\n\t\tvar measures = Math.floor(quarters / this._timeSignature());\n\t\tvar sixteenths = (quarters % 1) * 4;\n\t\tquarters = Math.floor(quarters) % this._timeSignature();\n\t\tsixteenths = sixteenths.toString();\n\t\tif (sixteenths.length > 3){\n\t\t\tsixteenths = parseFloat(sixteenths).toFixed(3);\n\t\t}\n\t\tvar progress = [measures, quarters, sixteenths];\n\t\treturn progress.join(\":\");\n\t};\n\n\t/**\n\t * Return the time in ticks.\n\t * @return {Ticks}\n\t */\n\tTone.Time.prototype.toTicks = function(){\n\t\tvar quarterTime = this._beatsToUnits(1);\n\t\tvar quarters = this.valueOf() / quarterTime;\n\t\treturn Math.floor(quarters * Tone.Transport.PPQ);\n\t};\n\n\t/**\n\t * Return the time in samples\n\t * @return {Samples} \n\t */\n\tTone.Time.prototype.toSamples = function(){\n\t\treturn this.toSeconds() * this.context.sampleRate;\n\t};\n\n\t/**\n\t * Return the time as a frequency value\n\t * @return {Frequency} \n\t * @example\n\t * Tone.Time(2).toFrequency(); //0.5\n\t */\n\tTone.Time.prototype.toFrequency = function(){\n\t\treturn 1/this.toSeconds();\n\t};\n\n\t/**\n\t * Return the time in seconds.\n\t * @return {Seconds} \n\t */\n\tTone.Time.prototype.toSeconds = function(){\n\t\treturn this.valueOf();\n\t};\n\n\t/**\n\t * Return the time in milliseconds.\n\t * @return {Milliseconds} \n\t */\n\tTone.Time.prototype.toMilliseconds = function(){\n\t\treturn this.toSeconds() * 1000;\n\t};\n\n\t/**\n\t * Return the time in seconds.\n\t * @return {Seconds} \n\t */\n\tTone.Time.prototype.valueOf = function(){\n\t\tvar val = this._expr();\n\t\treturn val + (this._plusNow?this.now():0);\n\t};\n\n\treturn Tone.Time;\n});","define([\"Tone/core/Tone\"], function (Tone) {\n\n\t/**\n\t * @class Tone.TimeBase is a flexible encoding of time\n\t * which can be evaluated to and from a string.\n\t * Parsing code modified from https://code.google.com/p/tapdigit/\n\t * Copyright 2011 2012 Ariya Hidayat, New BSD License\n\t * @extends {Tone}\n\t * @param {Time} val The time value as a number or string\n\t * @param {String=} units Unit values\n\t * @example\n\t * Tone.TimeBase(4, \"n\")\n\t * Tone.TimeBase(2, \"t\")\n\t * Tone.TimeBase(\"2t\").add(\"1m\")\n\t * Tone.TimeBase(\"2t + 1m\");\n\t */\n\tTone.TimeBase = function(val, units){\n\n\t\t//allows it to be constructed with or without 'new'\n\t\tif (this instanceof Tone.TimeBase) {\n\n\t\t\t/**\n\t\t\t * Any expressions parsed from the Time\n\t\t\t * @type {Array}\n\t\t\t * @private\n\t\t\t */\n\t\t\tthis._expr = this._noOp;\n\n\t\t\tif (val instanceof Tone.TimeBase){\n\t\t\t\tthis.copy(val);\n\t\t\t} else if (!this.isUndef(units) || this.isNumber(val)){\n\t\t\t\t//default units\n\t\t\t\tunits = this.defaultArg(units, this._defaultUnits);\n\t\t\t\tvar method = this._primaryExpressions[units].method;\n\t\t\t\tthis._expr = method.bind(this, val);\n\t\t\t} else if (this.isString(val)){\n\t\t\t\tthis.set(val);\n\t\t\t} else if (this.isUndef(val)){\n\t\t\t\t//default expression\n\t\t\t\tthis._expr = this._defaultExpr();\n\t\t\t}\n\t\t} else {\n\n\t\t\treturn new Tone.TimeBase(val, units);\n\t\t}\n\t};\n\n\tTone.extend(Tone.TimeBase);\n\n\t/**\n\t * Repalce the current time value with the value\n\t * given by the expression string.\n\t * @param {String} exprString\n\t * @return {Tone.TimeBase} this\n\t */\n\tTone.TimeBase.prototype.set = function(exprString){\n\t\tthis._expr = this._parseExprString(exprString);\n\t\treturn this;\n\t};\n\n\t/**\n\t * Return a clone of the TimeBase object.\n\t * @return {Tone.TimeBase} The new cloned Tone.TimeBase\n\t */\n\tTone.TimeBase.prototype.clone = function(){\n\t\tvar instance = new this.constructor();\n\t\tinstance.copy(this);\n\t\treturn instance;\n\t};\n\n\t/**\n\t * Copies the value of time to this Time\n\t * @param {Tone.TimeBase} time\n\t * @return {TimeBase}\n\t */\n\tTone.TimeBase.prototype.copy = function(time){\n\t\tvar val = time._expr();\n\t\treturn this.set(val);\n\t};\n\n\t///////////////////////////////////////////////////////////////////////////\n\t//\tABSTRACT SYNTAX TREE PARSER\n\t///////////////////////////////////////////////////////////////////////////\n\n\t/**\n\t * All the primary expressions.\n\t * @private\n\t * @type {Object}\n\t */\n\tTone.TimeBase.prototype._primaryExpressions = {\n\t\t\"n\" : {\n\t\t\tregexp : /^(\\d+)n/i,\n\t\t\tmethod : function(value){\n\t\t\t\tvalue = parseInt(value);\n\t\t\t\tif (value === 1){\n\t\t\t\t\treturn this._beatsToUnits(this._timeSignature());\n\t\t\t\t} else {\n\t\t\t\t\treturn this._beatsToUnits(4 / value);\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\t\t\"t\" : {\n\t\t\tregexp : /^(\\d+)t/i,\n\t\t\tmethod : function(value){\n\t\t\t\tvalue = parseInt(value);\n\t\t\t\treturn this._beatsToUnits(8 / (parseInt(value) * 3));\n\t\t\t}\n\t\t},\n\t\t\"m\" : {\n\t\t\tregexp : /^(\\d+)m/i,\n\t\t\tmethod : function(value){\n\t\t\t\treturn this._beatsToUnits(parseInt(value) * this._timeSignature());\n\t\t\t}\n\t\t},\n\t\t\"i\" : {\n\t\t\tregexp : /^(\\d+)i/i,\n\t\t\tmethod : function(value){\n\t\t\t\treturn this._ticksToUnits(parseInt(value));\n\t\t\t}\n\t\t},\n\t\t\"hz\" : {\n\t\t\tregexp : /^(\\d+(?:\\.\\d+)?)hz/i,\n\t\t\tmethod : function(value){\n\t\t\t\treturn this._frequencyToUnits(parseFloat(value));\n\t\t\t}\n\t\t},\n\t\t\"tr\" : {\n\t\t\tregexp : /^(\\d+(?:\\.\\d+)?):(\\d+(?:\\.\\d+)?):?(\\d+(?:\\.\\d+)?)?/,\n\t\t\tmethod : function(m, q, s){\n\t\t\t\tvar total = 0;\n\t\t\t\tif (m && m !== \"0\"){\n\t\t\t\t\ttotal += this._beatsToUnits(this._timeSignature() * parseFloat(m));\n\t\t\t\t}\n\t\t\t\tif (q && q !== \"0\"){\n\t\t\t\t\ttotal += this._beatsToUnits(parseFloat(q));\n\t\t\t\t}\n\t\t\t\tif (s && s !== \"0\"){\n\t\t\t\t\ttotal += this._beatsToUnits(parseFloat(s) / 4);\n\t\t\t\t}\n\t\t\t\treturn total;\n\t\t\t}\n\t\t},\n\t\t\"s\" : {\n\t\t\tregexp : /^(\\d+(?:\\.\\d+)?s)/,\n\t\t\tmethod : function(value){\n\t\t\t\treturn this._secondsToUnits(parseFloat(value));\n\t\t\t}\n\t\t},\n\t\t\"samples\" : {\n\t\t\tregexp : /^(\\d+)samples/,\n\t\t\tmethod : function(value){\n\t\t\t\treturn parseInt(value) / this.context.sampleRate;\n\t\t\t}\n\t\t},\n\t\t\"default\" : {\n\t\t\tregexp : /^(\\d+(?:\\.\\d+)?)/,\n\t\t\tmethod : function(value){\n\t\t\t\treturn this._primaryExpressions[this._defaultUnits].method.call(this, value);\n\t\t\t}\n\t\t}\n\t};\n\n\t/**\n\t * All the binary expressions that TimeBase can accept.\n\t * @private\n\t * @type {Object}\n\t */\n\tTone.TimeBase.prototype._binaryExpressions = {\n\t\t\"+\" : {\n\t\t\tregexp : /^\\+/,\n\t\t\tprecedence : 2,\n\t\t\tmethod : function(lh, rh){\n\t\t\t\treturn lh() + rh();\n\t\t\t}\n\t\t},\n\t\t\"-\" : {\n\t\t\tregexp : /^\\-/,\n\t\t\tprecedence : 2,\n\t\t\tmethod : function(lh, rh){\n\t\t\t\treturn lh() - rh();\n\t\t\t}\n\t\t},\n\t\t\"*\" : {\n\t\t\tregexp : /^\\*/,\n\t\t\tprecedence : 1,\n\t\t\tmethod : function(lh, rh){\n\t\t\t\treturn lh() * rh();\n\t\t\t}\n\t\t},\n\t\t\"/\" : {\n\t\t\tregexp : /^\\//,\n\t\t\tprecedence : 1,\n\t\t\tmethod : function(lh, rh){\n\t\t\t\treturn lh() / rh();\n\t\t\t}\n\t\t}\n\t};\n\n\t/**\n\t * All the unary expressions.\n\t * @private\n\t * @type {Object}\n\t */\n\tTone.TimeBase.prototype._unaryExpressions = {\n\t\t\"neg\" : {\n\t\t\tregexp : /^\\-/,\n\t\t\tmethod : function(lh){\n\t\t\t\treturn -lh();\n\t\t\t}\n\t\t}\n\t};\n\n\t/**\n\t * Syntactic glue which holds expressions together\n\t * @private\n\t * @type {Object}\n\t */\n\tTone.TimeBase.prototype._syntaxGlue = {\n\t\t\"(\" : {\n\t\t\tregexp : /^\\(/\n\t\t},\n\t\t\")\" : {\n\t\t\tregexp : /^\\)/\n\t\t}\n\t};\n\n\t/**\n\t * tokenize the expression based on the Expressions object\n\t * @param {string} expr \n\t * @return {Object} returns two methods on the tokenized list, next and peek\n\t * @private\n\t */\n\tTone.TimeBase.prototype._tokenize = function(expr){\n\t\tvar position = -1;\n\t\tvar tokens = [];\n\n\t\twhile(expr.length > 0){\n\t\t\texpr = expr.trim();\n\t\t\tvar token = getNextToken(expr, this);\n\t\t\ttokens.push(token);\n\t\t\texpr = expr.substr(token.value.length);\n\t\t}\n\n\t\tfunction getNextToken(expr, context){\n\t\t\tvar expressions = [\"_binaryExpressions\", \"_unaryExpressions\", \"_primaryExpressions\", \"_syntaxGlue\"];\n\t\t\tfor (var i = 0; i < expressions.length; i++){\n\t\t\t\tvar group = context[expressions[i]];\n\t\t\t\tfor (var opName in group){\n\t\t\t\t\tvar op = group[opName];\n\t\t\t\t\tvar reg = op.regexp;\n\t\t\t\t\tvar match = expr.match(reg);\n\t\t\t\t\tif (match !== null){\n\t\t\t\t\t\treturn {\n\t\t\t\t\t\t\tmethod : op.method,\n\t\t\t\t\t\t\tprecedence : op.precedence,\n\t\t\t\t\t\t\tregexp : op.regexp,\n\t\t\t\t\t\t\tvalue : match[0],\n\t\t\t\t\t\t};\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\tthrow new SyntaxError(\"Tone.TimeBase: Unexpected token \"+expr);\n\t\t}\n\n\t\treturn {\n\t\t\tnext : function(){\n\t\t\t\treturn tokens[++position];\n\t\t\t},\n\t\t\tpeek : function(){\n\t\t\t\treturn tokens[position + 1];\n\t\t\t}\n\t\t};\n\t};\n\n\t/**\n\t * Given a token, find the value within the groupName\n\t * @param {Object} token\n\t * @param {String} groupName\n\t * @param {Number} precedence\n\t * @private\n\t */\n\tTone.TimeBase.prototype._matchGroup = function(token, group, prec) {\n\t\tvar ret = false;\n\t\tif (!this.isUndef(token)){\n\t\t\tfor (var opName in group){\n\t\t\t\tvar op = group[opName];\n\t\t\t\tif (op.regexp.test(token.value)){\n\t\t\t\t\tif (!this.isUndef(prec)){\n\t\t\t\t\t\tif(op.precedence === prec){\t\n\t\t\t\t\t\t\treturn op;\n\t\t\t\t\t\t}\n\t\t\t\t\t} else {\n\t\t\t\t\t\treturn op;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\treturn ret;\n\t};\n\n\t/**\n\t * Match a binary expression given the token and the precedence\n\t * @param {Lexer} lexer\n\t * @param {Number} precedence\n\t * @private\n\t */\n\tTone.TimeBase.prototype._parseBinary = function(lexer, precedence){\n\t\tif (this.isUndef(precedence)){\n\t\t\tprecedence = 2;\n\t\t}\n\t\tvar expr;\n\t\tif (precedence < 0){\n\t\t\texpr = this._parseUnary(lexer);\n\t\t} else {\n\t\t\texpr = this._parseBinary(lexer, precedence - 1);\n\t\t}\n\t\tvar token = lexer.peek();\n\t\twhile (token && this._matchGroup(token, this._binaryExpressions, precedence)){\n\t\t\ttoken = lexer.next();\n\t\t\texpr = token.method.bind(this, expr, this._parseBinary(lexer, precedence - 1));\n\t\t\ttoken = lexer.peek();\n\t\t}\n\t\treturn expr;\n\t};\n\n\t/**\n\t * Match a unary expression.\n\t * @param {Lexer} lexer\n\t * @private\n\t */\n\tTone.TimeBase.prototype._parseUnary = function(lexer){\n\t\tvar token, expr;\n\t\ttoken = lexer.peek();\n\t\tvar op = this._matchGroup(token, this._unaryExpressions);\n\t\tif (op) {\n\t\t\ttoken = lexer.next();\n\t\t\texpr = this._parseUnary(lexer);\n\t\t\treturn op.method.bind(this, expr);\n\t\t}\n\t\treturn this._parsePrimary(lexer);\n\t};\n\n\t/**\n\t * Match a primary expression (a value).\n\t * @param {Lexer} lexer\n\t * @private\n\t */\n\tTone.TimeBase.prototype._parsePrimary = function(lexer){\n\t\tvar token, expr;\n\t\ttoken = lexer.peek();\n\t\tif (this.isUndef(token)) {\n\t\t\tthrow new SyntaxError(\"Tone.TimeBase: Unexpected end of expression\");\n\t\t}\n\t\tif (this._matchGroup(token, this._primaryExpressions)) {\n\t\t\ttoken = lexer.next();\n\t\t\tvar matching = token.value.match(token.regexp);\n\t\t\treturn token.method.bind(this, matching[1], matching[2], matching[3]);\n\t\t}\n\t\tif (token && token.value === \"(\"){\n\t\t\tlexer.next();\n\t\t\texpr = this._parseBinary(lexer);\n\t\t\ttoken = lexer.next();\n\t\t\tif (!(token && token.value === \")\")) {\n\t\t\t\tthrow new SyntaxError(\"Expected )\");\n\t\t\t}\n\t\t\treturn expr;\n\t\t}\n\t\tthrow new SyntaxError(\"Tone.TimeBase: Cannot process token \" + token.value);\n\t};\n\n\t/**\n\t * Recursively parse the string expression into a syntax tree.\n\t * @param {string} expr \n\t * @return {Function} the bound method to be evaluated later\n\t * @private\n\t */\n\tTone.TimeBase.prototype._parseExprString = function(exprString){\n\t\tif (!this.isString(exprString)){\n\t\t\texprString = exprString.toString();\n\t\t}\n\t\tvar lexer = this._tokenize(exprString);\n\t\tvar tree = this._parseBinary(lexer);\n\t\treturn tree;\n\t};\n\n\t///////////////////////////////////////////////////////////////////////////\n\t//\tDEFAULTS\n\t///////////////////////////////////////////////////////////////////////////\n\n\t/**\n\t * The initial expression value\n\t * @return {Number} The initial value 0\n\t * @private\n\t */\n\tTone.TimeBase.prototype._noOp = function(){\n\t\treturn 0;\n\t};\n\n\t/**\n\t * The default expression value if no arguments are given\n\t * @private\n\t */\n\tTone.TimeBase.prototype._defaultExpr = function(){\n\t\treturn this._noOp;\n\t};\n\n\t/**\n\t * The default units if none are given.\n\t * @private\n\t */\n\tTone.TimeBase.prototype._defaultUnits = \"s\";\n\n\t///////////////////////////////////////////////////////////////////////////\n\t//\tUNIT CONVERSIONS\n\t///////////////////////////////////////////////////////////////////////////\n\n\t/**\n\t * Returns the value of a frequency in the current units\n\t * @param {Frequency} freq\n\t * @return {Number}\n\t * @private\n\t */\n\tTone.TimeBase.prototype._frequencyToUnits = function(freq){\n\t\treturn 1/freq;\n\t};\n\n\t/**\n\t * Return the value of the beats in the current units\n\t * @param {Number} beats\n\t * @return {Number}\n\t * @private\n\t */\n\tTone.TimeBase.prototype._beatsToUnits = function(beats){\n\t\treturn (60 / Tone.Transport.bpm.value) * beats;\n\t};\n\n\t/**\n\t * Returns the value of a second in the current units\n\t * @param {Seconds} seconds\n\t * @return {Number}\n\t * @private\n\t */\n\tTone.TimeBase.prototype._secondsToUnits = function(seconds){\n\t\treturn seconds;\n\t};\n\n\t/**\n\t * Returns the value of a tick in the current time units\n\t * @param {Ticks} ticks\n\t * @return {Number}\n\t * @private\n\t */\n\tTone.TimeBase.prototype._ticksToUnits = function(ticks){\n\t\treturn ticks * (this._beatsToUnits(1) / Tone.Transport.PPQ);\n\t};\n\n\t/**\n\t * Return the time signature.\n\t * @return {Number}\n\t * @private\n\t */\n\tTone.TimeBase.prototype._timeSignature = function(){\n\t\treturn Tone.Transport.timeSignature;\n\t};\n\n\t///////////////////////////////////////////////////////////////////////////\n\t//\tEXPRESSIONS\n\t///////////////////////////////////////////////////////////////////////////\n\n\t/**\n\t * Push an expression onto the expression list\n\t * @param {Time} val\n\t * @param {String} type\n\t * @param {String} units\n\t * @return {Tone.TimeBase} \n\t * @private\n\t */\n\tTone.TimeBase.prototype._pushExpr = function(val, name, units){\n\t\t//create the expression\n\t\tif (!(val instanceof Tone.TimeBase)){\n\t\t\tval = new this.constructor(val, units);\n\t\t}\n\t\tthis._expr = this._binaryExpressions[name].method.bind(this, this._expr, val._expr);\n\t\treturn this;\n\t};\n\n\t/**\n\t * Add to the current value.\n\t * @param {Time} val The value to add\n\t * @param {String=} units Optional units to use with the value.\n\t * @return {Tone.TimeBase} this\n\t * @example\n\t * Tone.TimeBase(\"2m\").add(\"1m\"); //\"3m\"\n\t */\n\tTone.TimeBase.prototype.add = function(val, units){\n\t\treturn this._pushExpr(val, \"+\", units);\n\t};\n\n\t/**\n\t * Subtract the value from the current time.\n\t * @param {Time} val The value to subtract\n\t * @param {String=} units Optional units to use with the value.\n\t * @return {Tone.TimeBase} this\n\t * @example\n\t * Tone.TimeBase(\"2m\").sub(\"1m\"); //\"1m\"\n\t */\n\tTone.TimeBase.prototype.sub = function(val, units){\n\t\treturn this._pushExpr(val, \"-\", units);\n\t};\n\n\t/**\n\t * Multiply the current value by the given time.\n\t * @param {Time} val The value to multiply\n\t * @param {String=} units Optional units to use with the value.\n\t * @return {Tone.TimeBase} this\n\t * @example\n\t * Tone.TimeBase(\"2m\").mult(\"2\"); //\"4m\"\n\t */\n\tTone.TimeBase.prototype.mult = function(val, units){\n\t\treturn this._pushExpr(val, \"*\", units);\n\t};\n\n\t/**\n\t * Divide the current value by the given time.\n\t * @param {Time} val The value to divide by\n\t * @param {String=} units Optional units to use with the value.\n\t * @return {Tone.TimeBase} this\n\t * @example\n\t * Tone.TimeBase(\"2m\").div(2); //\"1m\"\n\t */\n\tTone.TimeBase.prototype.div = function(val, units){\n\t\treturn this._pushExpr(val, \"/\", units);\n\t};\n\n\t/**\n\t * Evaluate the time value. Returns the time\n\t * in seconds.\n\t * @return {Seconds} \n\t */\n\tTone.TimeBase.prototype.valueOf = function(){\n\t\treturn this._expr();\n\t};\n\n\t/**\n\t * Clean up\n\t * @return {Tone.TimeBase} this\n\t */\n\tTone.TimeBase.prototype.dispose = function(){\n\t\tthis._expr = null;\n\t};\n\n\treturn Tone.TimeBase;\n});","define([\"Tone/core/Tone\", \"Tone/type/Type\"], function(Tone){\n\n\t\"use strict\";\n\n\t/**\n\t * @class Tone.Param wraps the native Web Audio's AudioParam to provide\n\t * additional unit conversion functionality. It also\n\t * serves as a base-class for classes which have a single,\n\t * automatable parameter. \n\t * @extends {Tone}\n\t * @param {AudioParam} param The parameter to wrap.\n\t * @param {Tone.Type} units The units of the audio param.\n\t * @param {Boolean} convert If the param should be converted.\n\t */\n\tTone.Param = function(){\n\n\t\tvar options = this.optionsObject(arguments, [\"param\", \"units\", \"convert\"], Tone.Param.defaults);\n\n\t\t/**\n\t\t * The native parameter to control\n\t\t * @type {AudioParam}\n\t\t * @private\n\t\t */\n\t\tthis._param = this.input = options.param;\n\n\t\t/**\n\t\t * The units of the parameter\n\t\t * @type {Tone.Type}\n\t\t */\n\t\tthis.units = options.units;\n\n\t\t/**\n\t\t * If the value should be converted or not\n\t\t * @type {Boolean}\n\t\t */\n\t\tthis.convert = options.convert;\n\n\t\t/**\n\t\t * True if the signal value is being overridden by \n\t\t * a connected signal.\n\t\t * @readOnly\n\t\t * @type {boolean}\n\t\t * @private\n\t\t */\n\t\tthis.overridden = false;\n\n\t\t/**\n\t\t * If there is an LFO, this is where it is held.\n\t\t * @type {Tone.LFO}\n\t\t * @private\n\t\t */\n\t\tthis._lfo = null;\n\n\t\tif (this.isObject(options.lfo)){\n\t\t\tthis.value = options.lfo;\n\t\t} else if (!this.isUndef(options.value)){\n\t\t\tthis.value = options.value;\n\t\t}\n\t};\n\n\tTone.extend(Tone.Param);\n\t\n\t/**\n\t * Defaults\n\t * @type {Object}\n\t * @const\n\t */\n\tTone.Param.defaults = {\n\t\t\"units\" : Tone.Type.Default,\n\t\t\"convert\" : true,\n\t\t\"param\" : undefined\n\t};\n\n\t/**\n\t * The current value of the parameter. \n\t * @memberOf Tone.Param#\n\t * @type {Number}\n\t * @name value\n\t */\n\tObject.defineProperty(Tone.Param.prototype, \"value\", {\n\t\tget : function(){\n\t\t\treturn this._toUnits(this._param.value);\n\t\t},\n\t\tset : function(value){\n\t\t\tif (this.isObject(value)){\n\t\t\t\t//throw an error if the LFO needs to be included\n\t\t\t\tif (this.isUndef(Tone.LFO)){\n\t\t\t\t\tthrow new Error(\"Include 'Tone.LFO' to use an LFO as a Param value.\");\n\t\t\t\t}\n\t\t\t\t//remove the old one\n\t\t\t\tif (this._lfo){\n\t\t\t\t\tthis._lfo.dispose();\n\t\t\t\t}\n\t\t\t\tthis._lfo = new Tone.LFO(value).start();\n\t\t\t\tthis._lfo.connect(this.input);\n\t\t\t} else {\n\t\t\t\tvar convertedVal = this._fromUnits(value);\n\t\t\t\tthis._param.cancelScheduledValues(0);\n\t\t\t\tthis._param.value = convertedVal;\n\t\t\t}\n\t\t}\n\t});\n\n\t/**\n\t * Convert the given value from the type specified by Tone.Param.units\n\t * into the destination value (such as Gain or Frequency).\n\t * @private\n\t * @param {*} val the value to convert\n\t * @return {number} the number which the value should be set to\n\t */\n\tTone.Param.prototype._fromUnits = function(val){\n\t\tif (this.convert || this.isUndef(this.convert)){\n\t\t\tswitch(this.units){\n\t\t\t\tcase Tone.Type.Time: \n\t\t\t\t\treturn this.toSeconds(val);\n\t\t\t\tcase Tone.Type.Frequency: \n\t\t\t\t\treturn this.toFrequency(val);\n\t\t\t\tcase Tone.Type.Decibels: \n\t\t\t\t\treturn this.dbToGain(val);\n\t\t\t\tcase Tone.Type.NormalRange: \n\t\t\t\t\treturn Math.min(Math.max(val, 0), 1);\n\t\t\t\tcase Tone.Type.AudioRange: \n\t\t\t\t\treturn Math.min(Math.max(val, -1), 1);\n\t\t\t\tcase Tone.Type.Positive: \n\t\t\t\t\treturn Math.max(val, 0);\n\t\t\t\tdefault:\n\t\t\t\t\treturn val;\n\t\t\t}\n\t\t} else {\n\t\t\treturn val;\n\t\t}\n\t};\n\n\t/**\n\t * Convert the parameters value into the units specified by Tone.Param.units.\n\t * @private\n\t * @param {number} val the value to convert\n\t * @return {number}\n\t */\n\tTone.Param.prototype._toUnits = function(val){\n\t\tif (this.convert || this.isUndef(this.convert)){\n\t\t\tswitch(this.units){\n\t\t\t\tcase Tone.Type.Decibels: \n\t\t\t\t\treturn this.gainToDb(val);\n\t\t\t\tdefault:\n\t\t\t\t\treturn val;\n\t\t\t}\n\t\t} else {\n\t\t\treturn val;\n\t\t}\n\t};\n\n\t/**\n\t * the minimum output value\n\t * @type {Number}\n\t * @private\n\t */\n\tTone.Param.prototype._minOutput = 0.00001;\n\n\t/**\n\t * Schedules a parameter value change at the given time.\n\t * @param {*}\tvalue The value to set the signal.\n\t * @param {Time} time The time when the change should occur.\n\t * @returns {Tone.Param} this\n\t * @example\n\t * //set the frequency to \"G4\" in exactly 1 second from now. \n\t * freq.setValueAtTime(\"G4\", \"+1\");\n\t */\n\tTone.Param.prototype.setValueAtTime = function(value, time){\n\t\tvalue = this._fromUnits(value);\n\t\ttime = this.toSeconds(time);\n\t\tif (time <= this.now() + this.blockTime){\n\t\t\tthis._param.value = value;\n\t\t} else {\n\t\t\tthis._param.setValueAtTime(value, time);\n\t\t}\n\t\treturn this;\n\t};\n\n\t/**\n\t * Creates a schedule point with the current value at the current time.\n\t * This is useful for creating an automation anchor point in order to \n\t * schedule changes from the current value. \n\t *\n\t * @param {number=} now (Optionally) pass the now value in. \n\t * @returns {Tone.Param} this\n\t */\n\tTone.Param.prototype.setRampPoint = function(now){\n\t\tnow = this.defaultArg(now, this.now());\n\t\tvar currentVal = this._param.value;\n\t\t// exponentialRampToValueAt cannot ever ramp from or to 0\n\t\t// More info: https://bugzilla.mozilla.org/show_bug.cgi?id=1125600#c2\n\t\tif (currentVal === 0){\n\t\t\tcurrentVal = this._minOutput;\n\t\t}\n\t\tthis._param.setValueAtTime(currentVal, now);\n\t\treturn this;\n\t};\n\n\t/**\n\t * Schedules a linear continuous change in parameter value from the \n\t * previous scheduled parameter value to the given value.\n\t * \n\t * @param {number} value \n\t * @param {Time} endTime \n\t * @returns {Tone.Param} this\n\t */\n\tTone.Param.prototype.linearRampToValueAtTime = function(value, endTime){\n\t\tvalue = this._fromUnits(value);\n\t\tthis._param.linearRampToValueAtTime(value, this.toSeconds(endTime));\n\t\treturn this;\n\t};\n\n\t/**\n\t * Schedules an exponential continuous change in parameter value from \n\t * the previous scheduled parameter value to the given value.\n\t * \n\t * @param {number} value \n\t * @param {Time} endTime \n\t * @returns {Tone.Param} this\n\t */\n\tTone.Param.prototype.exponentialRampToValueAtTime = function(value, endTime){\n\t\tvalue = this._fromUnits(value);\n\t\tvalue = Math.max(this._minOutput, value);\n\t\tthis._param.exponentialRampToValueAtTime(value, this.toSeconds(endTime));\n\t\treturn this;\n\t};\n\n\t/**\n\t * Schedules an exponential continuous change in parameter value from \n\t * the current time and current value to the given value over the \n\t * duration of the rampTime.\n\t * \n\t * @param {number} value The value to ramp to.\n\t * @param {Time} rampTime the time that it takes the \n\t * value to ramp from it's current value\n\t * @param {Time}\t[startTime=now] \tWhen the ramp should start. \n\t * @returns {Tone.Param} this\n\t * @example\n\t * //exponentially ramp to the value 2 over 4 seconds. \n\t * signal.exponentialRampToValue(2, 4);\n\t */\n\tTone.Param.prototype.exponentialRampToValue = function(value, rampTime, startTime){\n\t\tstartTime = this.toSeconds(startTime);\n\t\tthis.setRampPoint(startTime);\n\t\tthis.exponentialRampToValueAtTime(value, startTime + this.toSeconds(rampTime));\n\t\treturn this;\n\t};\n\n\t/**\n\t * Schedules an linear continuous change in parameter value from \n\t * the current time and current value to the given value over the \n\t * duration of the rampTime.\n\t * \n\t * @param {number} value The value to ramp to.\n\t * @param {Time} rampTime the time that it takes the \n\t * value to ramp from it's current value\n\t * @param {Time}\t[startTime=now] \tWhen the ramp should start. \n\t * @returns {Tone.Param} this\n\t * @example\n\t * //linearly ramp to the value 4 over 3 seconds. \n\t * signal.linearRampToValue(4, 3);\n\t */\n\tTone.Param.prototype.linearRampToValue = function(value, rampTime, startTime){\n\t\tstartTime = this.toSeconds(startTime);\n\t\tthis.setRampPoint(startTime);\n\t\tthis.linearRampToValueAtTime(value, startTime + this.toSeconds(rampTime));\n\t\treturn this;\n\t};\n\n\t/**\n\t * Start exponentially approaching the target value at the given time with\n\t * a rate having the given time constant.\n\t * @param {number} value \n\t * @param {Time} startTime \n\t * @param {number} timeConstant \n\t * @returns {Tone.Param} this \n\t */\n\tTone.Param.prototype.setTargetAtTime = function(value, startTime, timeConstant){\n\t\tvalue = this._fromUnits(value);\n\t\t// The value will never be able to approach without timeConstant > 0.\n\t\t// http://www.w3.org/TR/webaudio/#dfn-setTargetAtTime, where the equation\n\t\t// is described. 0 results in a division by 0.\n\t\tvalue = Math.max(this._minOutput, value);\n\t\ttimeConstant = Math.max(this._minOutput, timeConstant);\n\t\tthis._param.setTargetAtTime(value, this.toSeconds(startTime), timeConstant);\n\t\treturn this;\n\t};\n\n\t/**\n\t * Sets an array of arbitrary parameter values starting at the given time\n\t * for the given duration.\n\t * \t\n\t * @param {Array} values \n\t * @param {Time} startTime \n\t * @param {Time} duration \n\t * @returns {Tone.Param} this\n\t */\n\tTone.Param.prototype.setValueCurveAtTime = function(values, startTime, duration){\n\t\tfor (var i = 0; i < values.length; i++){\n\t\t\tvalues[i] = this._fromUnits(values[i]);\n\t\t}\n\t\tthis._param.setValueCurveAtTime(values, this.toSeconds(startTime), this.toSeconds(duration));\n\t\treturn this;\n\t};\n\n\t/**\n\t * Cancels all scheduled parameter changes with times greater than or \n\t * equal to startTime.\n\t * \n\t * @param {Time} startTime\n\t * @returns {Tone.Param} this\n\t */\n\tTone.Param.prototype.cancelScheduledValues = function(startTime){\n\t\tthis._param.cancelScheduledValues(this.toSeconds(startTime));\n\t\treturn this;\n\t};\n\n\t/**\n\t * Ramps to the given value over the duration of the rampTime. \n\t * Automatically selects the best ramp type (exponential or linear)\n\t * depending on the `units` of the signal\n\t * \n\t * @param {number} value \n\t * @param {Time} rampTime \tThe time that it takes the \n\t * value to ramp from it's current value\n\t * @param {Time}\t[startTime=now] \tWhen the ramp should start. \n\t * @returns {Tone.Param} this\n\t * @example\n\t * //ramp to the value either linearly or exponentially \n\t * //depending on the \"units\" value of the signal\n\t * signal.rampTo(0, 10);\n\t * @example\n\t * //schedule it to ramp starting at a specific time\n\t * signal.rampTo(0, 10, 5)\n\t */\n\tTone.Param.prototype.rampTo = function(value, rampTime, startTime){\n\t\trampTime = this.defaultArg(rampTime, 0);\n\t\tif (this.units === Tone.Type.Frequency || this.units === Tone.Type.BPM || this.units === Tone.Type.Decibels){\n\t\t\tthis.exponentialRampToValue(value, rampTime, startTime);\n\t\t} else {\n\t\t\tthis.linearRampToValue(value, rampTime, startTime);\n\t\t}\n\t\treturn this;\n\t};\n\n\t/**\n\t * The LFO created by the signal instance. If none\n\t * was created, this is null.\n\t * @type {Tone.LFO}\n\t * @readOnly\n\t * @memberOf Tone.Param#\n\t * @name lfo\n\t */\n\tObject.defineProperty(Tone.Param.prototype, \"lfo\", {\n\t\tget : function(){\n\t\t\treturn this._lfo;\n\t\t}\n\t});\n\n\t/**\n\t * Clean up\n\t * @returns {Tone.Param} this\n\t */\n\tTone.Param.prototype.dispose = function(){\n\t\tTone.prototype.dispose.call(this);\n\t\tthis._param = null;\n\t\tif (this._lfo){\n\t\t\tthis._lfo.dispose();\n\t\t\tthis._lfo = null;\n\t\t}\n\t\treturn this;\n\t};\n\n\treturn Tone.Param;\n});","'use strict';\n\ndefine(function (require) {\n var p5sound = require('master');\n\n var Add = require('Tone/signal/Add');\n var Mult = require('Tone/signal/Multiply');\n var Scale = require('Tone/signal/Scale');\n\n /**\n *
Creates a signal that oscillates between -1.0 and 1.0.\n * By default, the oscillation takes the form of a sinusoidal\n * shape ('sine'). Additional types include 'triangle',\n * 'sawtooth' and 'square'. The frequency defaults to\n * 440 oscillations per second (440Hz, equal to the pitch of an\n * 'A' note).
\n *\n * @class p5.Oscillator\n * @constructor\n * @param {Number} [freq] frequency defaults to 440Hz\n * @param {String} [type] type of oscillator. Options:\n * 'sine' (default), 'triangle',\n * 'sawtooth', 'square'\n * @example\n *
\n * var osc;\n * var playing = false;\n *\n * function setup() {\n * backgroundColor = color(255,0,255);\n * textAlign(CENTER);\n *\n * osc = new p5.Oscillator();\n * osc.setType('sine');\n * osc.freq(240);\n * osc.amp(0);\n * osc.start();\n * }\n *\n * function draw() {\n * background(backgroundColor)\n * text('click to play', width/2, height/2);\n * }\n *\n * function mouseClicked() {\n * if (mouseX > 0 && mouseX < width && mouseY < height && mouseY > 0) {\n * if (!playing) {\n * // ramp amplitude to 0.5 over 0.05 seconds\n * osc.amp(0.5, 0.05);\n * playing = true;\n * backgroundColor = color(0,255,255);\n * } else {\n * // ramp amplitude to 0 over 0.5 seconds\n * osc.amp(0, 0.5);\n * playing = false;\n * backgroundColor = color(255,0,255);\n * }\n * }\n * }\n *
\n */\n p5.Oscillator = function(freq, type) {\n if (typeof freq === 'string') {\n var f = type;\n type = freq;\n freq = f;\n } if (typeof type === 'number') {\n var f = type;\n type = freq;\n freq = f;\n }\n this.started = false;\n\n // components\n this.phaseAmount = undefined;\n this.oscillator = p5sound.audiocontext.createOscillator();\n this.f = freq || 440.0; // frequency\n this.oscillator.type = type || 'sine';\n this.oscillator.frequency.setValueAtTime(this.f, p5sound.audiocontext.currentTime);\n\n // connections\n this.output = p5sound.audiocontext.createGain();\n\n this._freqMods = []; // modulators connected to this oscillator's frequency\n\n // set default output gain to 0.5\n this.output.gain.value = 0.5;\n this.output.gain.setValueAtTime(0.5, p5sound.audiocontext.currentTime);\n\n this.oscillator.connect(this.output);\n // stereo panning\n this.panPosition = 0.0;\n this.connection = p5sound.input; // connect to p5sound by default\n this.panner = new p5.Panner(this.output, this.connection, 1);\n\n //array of math operation signal chaining\n this.mathOps = [this.output];\n\n // add to the soundArray so we can dispose of the osc later\n p5sound.soundArray.push(this);\n };\n\n /**\n * Start an oscillator. Accepts an optional parameter to\n * determine how long (in seconds from now) until the\n * oscillator starts.\n *\n * @method start\n * @for p5.Oscillator\n * @param {Number} [time] startTime in seconds from now.\n * @param {Number} [frequency] frequency in Hz.\n */\n p5.Oscillator.prototype.start = function(time, f) {\n if (this.started) {\n var now = p5sound.audiocontext.currentTime;\n this.stop(now);\n }\n if (!this.started) {\n var freq = f || this.f;\n var type = this.oscillator.type;\n\n // set old osc free to be garbage collected (memory)\n if (this.oscillator) {\n this.oscillator.disconnect();\n delete this.oscillator;\n }\n\n // var detune = this.oscillator.frequency.value;\n this.oscillator = p5sound.audiocontext.createOscillator();\n this.oscillator.frequency.value = Math.abs(freq);\n this.oscillator.type = type;\n // this.oscillator.detune.value = detune;\n this.oscillator.connect(this.output);\n time = time || 0;\n this.oscillator.start(time + p5sound.audiocontext.currentTime);\n this.freqNode = this.oscillator.frequency;\n\n // if other oscillators are already connected to this osc's freq\n for (var i in this._freqMods) {\n if (typeof this._freqMods[i].connect !== 'undefined') {\n this._freqMods[i].connect(this.oscillator.frequency);\n }\n }\n\n this.started = true;\n }\n };\n\n /**\n * Stop an oscillator. Accepts an optional parameter\n * to determine how long (in seconds from now) until the\n * oscillator stops.\n *\n * @method stop\n * @for p5.Oscillator\n * @param {Number} secondsFromNow Time, in seconds from now.\n */\n p5.Oscillator.prototype.stop = function(time) {\n if (this.started) {\n var t = time || 0;\n var now = p5sound.audiocontext.currentTime;\n this.oscillator.stop(t + now);\n this.started = false;\n }\n };\n\n /**\n * Set the amplitude between 0 and 1.0. Or, pass in an object\n * such as an oscillator to modulate amplitude with an audio signal.\n *\n * @method amp\n * @for p5.Oscillator\n * @param {Number|Object} vol between 0 and 1.0\n * or a modulating signal/oscillator\n * @param {Number} [rampTime] create a fade that lasts rampTime\n * @param {Number} [timeFromNow] schedule this event to happen\n * seconds from now\n * @return {AudioParam} gain If no value is provided,\n * returns the Web Audio API\n * AudioParam that controls\n * this oscillator's\n * gain/amplitude/volume)\n */\n p5.Oscillator.prototype.amp = function(vol, rampTime, tFromNow) {\n var self = this;\n if (typeof vol === 'number') {\n var rampTime = rampTime || 0;\n var tFromNow = tFromNow || 0;\n var now = p5sound.audiocontext.currentTime;\n this.output.gain.linearRampToValueAtTime(vol, now + tFromNow + rampTime);\n }\n\n else if (vol) {\n vol.connect(self.output.gain);\n } else {\n // return the Gain Node\n return this.output.gain;\n }\n };\n\n // these are now the same thing\n p5.Oscillator.prototype.fade = p5.Oscillator.prototype.amp;\n\n p5.Oscillator.prototype.getAmp = function() {\n return this.output.gain.value;\n };\n\n /**\n * Set frequency of an oscillator to a value. Or, pass in an object\n * such as an oscillator to modulate the frequency with an audio signal.\n *\n * @method freq\n * @for p5.Oscillator\n * @param {Number|Object} Frequency Frequency in Hz\n * or modulating signal/oscillator\n * @param {Number} [rampTime] Ramp time (in seconds)\n * @param {Number} [timeFromNow] Schedule this event to happen\n * at x seconds from now\n * @return {AudioParam} Frequency If no value is provided,\n * returns the Web Audio API\n * AudioParam that controls\n * this oscillator's frequency\n * @example\n *
\n * var osc = new p5.Oscillator(300);\n * osc.start();\n * osc.freq(40, 10);\n *
\n */\n p5.Oscillator.prototype.freq = function(val, rampTime, tFromNow) {\n if (typeof val === 'number' && !isNaN(val)) {\n this.f = val;\n var now = p5sound.audiocontext.currentTime;\n var rampTime = rampTime || 0;\n var tFromNow = tFromNow || 0;\n var t = now + tFromNow + rampTime;\n // var currentFreq = this.oscillator.frequency.value;\n // this.oscillator.frequency.cancelScheduledValues(now);\n\n if (rampTime === 0) {\n this.oscillator.frequency.setValueAtTime(val, tFromNow + now);\n } else {\n if (val > 0 ) {\n this.oscillator.frequency.exponentialRampToValueAtTime(val, tFromNow + rampTime + now);\n } else {\n this.oscillator.frequency.linearRampToValueAtTime(val, tFromNow + rampTime + now);\n }\n }\n\n // reset phase if oscillator has a phase\n if (this.phaseAmount) {\n this.phase(this.phaseAmount);\n }\n\n } else if (val) {\n if (val.output) {\n val = val.output;\n }\n val.connect(this.oscillator.frequency);\n\n // keep track of what is modulating this param\n // so it can be re-connected if\n this._freqMods.push( val );\n } else {\n // return the Frequency Node\n return this.oscillator.frequency;\n }\n };\n\n p5.Oscillator.prototype.getFreq = function() {\n return this.oscillator.frequency.value;\n };\n\n /**\n * Set type to 'sine', 'triangle', 'sawtooth' or 'square'.\n *\n * @method setType\n * @for p5.Oscillator\n * @param {String} type 'sine', 'triangle', 'sawtooth' or 'square'.\n */\n p5.Oscillator.prototype.setType = function(type) {\n this.oscillator.type = type;\n };\n\n p5.Oscillator.prototype.getType = function() {\n return this.oscillator.type;\n };\n\n /**\n * Connect to a p5.sound / Web Audio object.\n *\n * @method connect\n * @for p5.Oscillator\n * @param {Object} unit A p5.sound or Web Audio object\n */\n p5.Oscillator.prototype.connect = function(unit) {\n if (!unit) {\n this.panner.connect(p5sound.input);\n }\n else if (unit.hasOwnProperty('input')) {\n this.panner.connect(unit.input);\n this.connection = unit.input;\n }\n else {\n this.panner.connect(unit);\n this.connection = unit;\n }\n };\n\n /**\n * Disconnect all outputs\n *\n * @method disconnect\n * @for p5.Oscillator\n */\n p5.Oscillator.prototype.disconnect = function() {\n if (this.output) {\n this.output.disconnect();\n }\n if (this.panner) {\n this.panner.disconnect();\n if (this.output) {\n this.output.connect(this.panner);\n }\n }\n this.oscMods = [];\n };\n\n /**\n * Pan between Left (-1) and Right (1)\n *\n * @method pan\n * @for p5.Oscillator\n * @param {Number} panning Number between -1 and 1\n * @param {Number} timeFromNow schedule this event to happen\n * seconds from now\n */\n p5.Oscillator.prototype.pan = function(pval, tFromNow) {\n this.panPosition = pval;\n this.panner.pan(pval, tFromNow);\n };\n\n p5.Oscillator.prototype.getPan = function() {\n return this.panPosition;\n };\n\n // get rid of the oscillator\n p5.Oscillator.prototype.dispose = function() {\n // remove reference from soundArray\n var index = p5sound.soundArray.indexOf(this);\n p5sound.soundArray.splice(index, 1);\n\n if (this.oscillator) {\n var now = p5sound.audiocontext.currentTime;\n this.stop(now);\n this.disconnect();\n this.panner = null;\n this.oscillator = null;\n }\n // if it is a Pulse\n if (this.osc2) {\n this.osc2.dispose();\n }\n };\n\n /**\n * Set the phase of an oscillator between 0.0 and 1.0.\n * In this implementation, phase is a delay time\n * based on the oscillator's current frequency.\n *\n * @method phase\n * @for p5.Oscillator\n * @param {Number} phase float between 0.0 and 1.0\n */\n p5.Oscillator.prototype.phase = function(p) {\n var delayAmt = p5.prototype.map(p, 0, 1.0, 0, 1/this.f);\n var now = p5sound.audiocontext.currentTime;\n\n this.phaseAmount = p;\n\n if (!this.dNode) {\n // create a delay node\n this.dNode = p5sound.audiocontext.createDelay();\n // put the delay node in between output and panner\n this.oscillator.disconnect();\n this.oscillator.connect(this.dNode);\n this.dNode.connect(this.output);\n }\n\n // set delay time to match phase:\n this.dNode.delayTime.setValueAtTime(delayAmt, now);\n };\n\n // ========================== //\n // SIGNAL MATH FOR MODULATION //\n // ========================== //\n\n // return sigChain(this, scale, thisChain, nextChain, Scale);\n var sigChain = function(o, mathObj, thisChain, nextChain, type) {\n var chainSource = o.oscillator;\n // if this type of math already exists in the chain, replace it\n for (var i in o.mathOps) {\n if (o.mathOps[i] instanceof type) {\n chainSource.disconnect();\n o.mathOps[i].dispose();\n thisChain = i;\n // assume nextChain is output gain node unless...\n if (thisChain < o.mathOps.length - 2) {\n nextChain = o.mathOps[i+1];\n }\n }\n }\n if (thisChain === o.mathOps.length - 1) {\n o.mathOps.push(nextChain);\n }\n // assume source is the oscillator unless i > 0\n if (i > 0) {\n chainSource = o.mathOps[i-1];\n }\n chainSource.disconnect();\n chainSource.connect(mathObj);\n mathObj.connect(nextChain);\n o.mathOps[thisChain] = mathObj;\n return o;\n };\n\n /**\n * Add a value to the p5.Oscillator's output amplitude,\n * and return the oscillator. Calling this method again\n * will override the initial add() with a new value.\n *\n * @method add\n * @for p5.Oscillator\n * @param {Number} number Constant number to add\n * @return {p5.Oscillator} Oscillator Returns this oscillator\n * with scaled output\n *\n */\n p5.Oscillator.prototype.add = function(num) {\n var add = new Add(num);\n var thisChain = this.mathOps.length-1;\n var nextChain = this.output;\n return sigChain(this, add, thisChain, nextChain, Add);\n };\n\n /**\n * Multiply the p5.Oscillator's output amplitude\n * by a fixed value (i.e. turn it up!). Calling this method\n * again will override the initial mult() with a new value.\n *\n * @method mult\n * @for p5.Oscillator\n * @param {Number} number Constant number to multiply\n * @return {p5.Oscillator} Oscillator Returns this oscillator\n * with multiplied output\n */\n p5.Oscillator.prototype.mult = function(num) {\n var mult = new Mult(num);\n var thisChain = this.mathOps.length-1;\n var nextChain = this.output;\n return sigChain(this, mult, thisChain, nextChain, Mult);\n };\n\n /**\n * Scale this oscillator's amplitude values to a given\n * range, and return the oscillator. Calling this method\n * again will override the initial scale() with new values.\n *\n * @method scale\n * @for p5.Oscillator\n * @param {Number} inMin input range minumum\n * @param {Number} inMax input range maximum\n * @param {Number} outMin input range minumum\n * @param {Number} outMax input range maximum\n * @return {p5.Oscillator} Oscillator Returns this oscillator\n * with scaled output\n */\n p5.Oscillator.prototype.scale = function(inMin, inMax, outMin, outMax) {\n var mapOutMin, mapOutMax;\n if (arguments.length === 4) {\n mapOutMin = p5.prototype.map(outMin, inMin, inMax, 0, 1) - 0.5;\n mapOutMax = p5.prototype.map(outMax, inMin, inMax, 0, 1) - 0.5;\n }\n else {\n mapOutMin = arguments[0];\n mapOutMax = arguments[1];\n }\n var scale = new Scale(mapOutMin, mapOutMax);\n var thisChain = this.mathOps.length-1;\n var nextChain = this.output;\n return sigChain(this, scale, thisChain, nextChain, Scale);\n\n // this.output.disconnect();\n // this.output.connect(scale)\n };\n\n // ============================== //\n // SinOsc, TriOsc, SqrOsc, SawOsc //\n // ============================== //\n\n /**\n * Constructor: new p5.SinOsc().\n * This creates a Sine Wave Oscillator and is\n * equivalent to new p5.Oscillator('sine')\n * or creating a p5.Oscillator and then calling\n * its method setType('sine').\n * See p5.Oscillator for methods.\n *\n * @class p5.SinOsc\n * @constructor\n * @extends p5.Oscillator\n * @param {Number} [freq] Set the frequency\n */\n p5.SinOsc = function(freq) {\n p5.Oscillator.call(this, freq, 'sine');\n };\n\n p5.SinOsc.prototype = Object.create(p5.Oscillator.prototype);\n\n /**\n * Constructor: new p5.TriOsc().\n * This creates a Triangle Wave Oscillator and is\n * equivalent to new p5.Oscillator('triangle')\n * or creating a p5.Oscillator and then calling\n * its method setType('triangle').\n * See p5.Oscillator for methods.\n *\n * @class p5.TriOsc\n * @constructor\n * @extends p5.Oscillator\n * @param {Number} [freq] Set the frequency\n */\n p5.TriOsc = function(freq) {\n p5.Oscillator.call(this, freq, 'triangle');\n };\n\n p5.TriOsc.prototype = Object.create(p5.Oscillator.prototype);\n\n /**\n * Constructor: new p5.SawOsc().\n * This creates a SawTooth Wave Oscillator and is\n * equivalent to new p5.Oscillator('sawtooth')\n * or creating a p5.Oscillator and then calling\n * its method setType('sawtooth').\n * See p5.Oscillator for methods.\n *\n * @class p5.SawOsc\n * @constructor\n * @extends p5.Oscillator\n * @param {Number} [freq] Set the frequency\n */\n p5.SawOsc = function(freq) {\n p5.Oscillator.call(this, freq, 'sawtooth');\n };\n\n p5.SawOsc.prototype = Object.create(p5.Oscillator.prototype);\n\n /**\n * Constructor: new p5.SqrOsc().\n * This creates a Square Wave Oscillator and is\n * equivalent to new p5.Oscillator('square')\n * or creating a p5.Oscillator and then calling\n * its method setType('square').\n * See p5.Oscillator for methods.\n *\n * @class p5.SqrOsc\n * @constructor\n * @extends p5.Oscillator\n * @param {Number} [freq] Set the frequency\n */\n p5.SqrOsc = function(freq) {\n p5.Oscillator.call(this, freq, 'square');\n };\n\n p5.SqrOsc.prototype = Object.create(p5.Oscillator.prototype);\n\n});\n","define([\"Tone/core/Tone\", \"Tone/type/Type\"], function (Tone) {\n\n\t\"use strict\";\n\n\t/**\n\t * @class A Timeline class for scheduling and maintaining state\n\t * along a timeline. All events must have a \"time\" property. \n\t * Internally, events are stored in time order for fast \n\t * retrieval.\n\t * @extends {Tone}\n\t * @param {Positive} [memory=Infinity] The number of previous events that are retained.\n\t */\n\tTone.Timeline = function(){\n\n\t\tvar options = this.optionsObject(arguments, [\"memory\"], Tone.Timeline.defaults);\n\n\t\t/**\n\t\t * The array of scheduled timeline events\n\t\t * @type {Array}\n\t\t * @private\n\t\t */\n\t\tthis._timeline = [];\n\n\t\t/**\n\t\t * An array of items to remove from the list. \n\t\t * @type {Array}\n\t\t * @private\n\t\t */\n\t\tthis._toRemove = [];\n\n\t\t/**\n\t\t * Flag if the tieline is mid iteration\n\t\t * @private\n\t\t * @type {Boolean}\n\t\t */\n\t\tthis._iterating = false;\n\n\t\t/**\n\t\t * The memory of the timeline, i.e.\n\t\t * how many events in the past it will retain\n\t\t * @type {Positive}\n\t\t */\n\t\tthis.memory = options.memory;\n\t};\n\n\tTone.extend(Tone.Timeline);\n\n\t/**\n\t * the default parameters\n\t * @static\n\t * @const\n\t */\n\tTone.Timeline.defaults = {\n\t\t\"memory\" : Infinity\n\t};\n\n\t/**\n\t * The number of items in the timeline.\n\t * @type {Number}\n\t * @memberOf Tone.Timeline#\n\t * @name length\n\t * @readOnly\n\t */\n\tObject.defineProperty(Tone.Timeline.prototype, \"length\", {\n\t\tget : function(){\n\t\t\treturn this._timeline.length;\n\t\t}\n\t});\n\n\t/**\n\t * Insert an event object onto the timeline. Events must have a \"time\" attribute.\n\t * @param {Object} event The event object to insert into the \n\t * timeline. \n\t * @returns {Tone.Timeline} this\n\t */\n\tTone.Timeline.prototype.add = function(event){\n\t\t//the event needs to have a time attribute\n\t\tif (this.isUndef(event.time)){\n\t\t\tthrow new Error(\"Tone.Timeline: events must have a time attribute\");\n\t\t}\n\t\tif (this._timeline.length){\n\t\t\tvar index = this._search(event.time);\n\t\t\tthis._timeline.splice(index + 1, 0, event);\n\t\t} else {\n\t\t\tthis._timeline.push(event);\t\t\t\n\t\t}\n\t\t//if the length is more than the memory, remove the previous ones\n\t\tif (this.length > this.memory){\n\t\t\tvar diff = this.length - this.memory;\n\t\t\tthis._timeline.splice(0, diff);\n\t\t}\n\t\treturn this;\n\t};\n\n\t/**\n\t * Remove an event from the timeline.\n\t * @param {Object} event The event object to remove from the list.\n\t * @returns {Tone.Timeline} this\n\t */\n\tTone.Timeline.prototype.remove = function(event){\n\t\tif (this._iterating){\n\t\t\tthis._toRemove.push(event);\n\t\t} else {\n\t\t\tvar index = this._timeline.indexOf(event);\n\t\t\tif (index !== -1){\n\t\t\t\tthis._timeline.splice(index, 1);\n\t\t\t}\n\t\t}\n\t\treturn this;\n\t};\n\n\t/**\n\t * Get the nearest event whose time is less than or equal to the given time.\n\t * @param {Number} time The time to query.\n\t * @returns {Object} The event object set after that time.\n\t */\n\tTone.Timeline.prototype.get = function(time){\n\t\tvar index = this._search(time);\n\t\tif (index !== -1){\n\t\t\treturn this._timeline[index];\n\t\t} else {\n\t\t\treturn null;\n\t\t}\n\t};\n\n\t/**\n\t * Return the first event in the timeline without removing it\n\t * @returns {Object} The first event object\n\t */\n\tTone.Timeline.prototype.peek = function(){\n\t\treturn this._timeline[0];\n\t};\n\n\t/**\n\t * Return the first event in the timeline and remove it\n\t * @returns {Object} The first event object\n\t */\n\tTone.Timeline.prototype.shift = function(){\n\t\treturn this._timeline.shift();\n\t};\n\n\t/**\n\t * Get the event which is scheduled after the given time.\n\t * @param {Number} time The time to query.\n\t * @returns {Object} The event object after the given time\n\t */\n\tTone.Timeline.prototype.getAfter = function(time){\n\t\tvar index = this._search(time);\n\t\tif (index + 1 < this._timeline.length){\n\t\t\treturn this._timeline[index + 1];\n\t\t} else {\n\t\t\treturn null;\n\t\t}\n\t};\n\n\t/**\n\t * Get the event before the event at the given time.\n\t * @param {Number} time The time to query.\n\t * @returns {Object} The event object before the given time\n\t */\n\tTone.Timeline.prototype.getBefore = function(time){\n\t\tvar len = this._timeline.length;\n\t\t//if it's after the last item, return the last item\n\t\tif (len > 0 && this._timeline[len - 1].time < time){\n\t\t\treturn this._timeline[len - 1];\n\t\t}\n\t\tvar index = this._search(time);\n\t\tif (index - 1 >= 0){\n\t\t\treturn this._timeline[index - 1];\n\t\t} else {\n\t\t\treturn null;\n\t\t}\n\t};\n\n\t/**\n\t * Cancel events after the given time\n\t * @param {Number} time The time to query.\n\t * @returns {Tone.Timeline} this\n\t */\n\tTone.Timeline.prototype.cancel = function(after){\n\t\tif (this._timeline.length > 1){\n\t\t\tvar index = this._search(after);\n\t\t\tif (index >= 0){\n\t\t\t\tif (this._timeline[index].time === after){\n\t\t\t\t\t//get the first item with that time\n\t\t\t\t\tfor (var i = index; i >= 0; i--){\n\t\t\t\t\t\tif (this._timeline[i].time === after){\n\t\t\t\t\t\t\tindex = i;\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tthis._timeline = this._timeline.slice(0, index);\n\t\t\t\t} else {\n\t\t\t\t\tthis._timeline = this._timeline.slice(0, index + 1);\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tthis._timeline = [];\n\t\t\t}\n\t\t} else if (this._timeline.length === 1){\n\t\t\t//the first item's time\n\t\t\tif (this._timeline[0].time >= after){\n\t\t\t\tthis._timeline = [];\n\t\t\t}\n\t\t}\n\t\treturn this;\n\t};\n\n\t/**\n\t * Cancel events before or equal to the given time.\n\t * @param {Number} time The time to cancel before.\n\t * @returns {Tone.Timeline} this\n\t */\n\tTone.Timeline.prototype.cancelBefore = function(time){\n\t\tif (this._timeline.length){\n\t\t\tvar index = this._search(time);\n\t\t\tif (index >= 0){\n\t\t\t\tthis._timeline = this._timeline.slice(index + 1);\n\t\t\t}\n\t\t}\n\t\treturn this;\n\t};\n\n\t/**\n\t * Does a binary serach on the timeline array and returns the \n\t * nearest event index whose time is after or equal to the given time.\n\t * If a time is searched before the first index in the timeline, -1 is returned.\n\t * If the time is after the end, the index of the last item is returned.\n\t * @param {Number} time \n\t * @return {Number} the index in the timeline array \n\t * @private\n\t */\n\tTone.Timeline.prototype._search = function(time){\n\t\tvar beginning = 0;\n\t\tvar len = this._timeline.length;\n\t\tvar end = len;\n\t\tif (len > 0 && this._timeline[len - 1].time <= time){\n\t\t\treturn len - 1;\n\t\t}\n\t\twhile (beginning < end){\n\t\t\t// calculate the midpoint for roughly equal partition\n\t\t\tvar midPoint = Math.floor(beginning + (end - beginning) / 2);\n\t\t\tvar event = this._timeline[midPoint];\n\t\t\tvar nextEvent = this._timeline[midPoint + 1];\n\t\t\tif (event.time === time){\n\t\t\t\t//choose the last one that has the same time\n\t\t\t\tfor (var i = midPoint; i < this._timeline.length; i++){\n\t\t\t\t\tvar testEvent = this._timeline[i];\n\t\t\t\t\tif (testEvent.time === time){\n\t\t\t\t\t\tmidPoint = i;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\treturn midPoint;\n\t\t\t} else if (event.time < time && nextEvent.time > time){\n\t\t\t\treturn midPoint;\n\t\t\t} else if (event.time > time){\n\t\t\t\t//search lower\n\t\t\t\tend = midPoint;\n\t\t\t} else if (event.time < time){\n\t\t\t\t//search upper\n\t\t\t\tbeginning = midPoint + 1;\n\t\t\t} \n\t\t}\n\t\treturn -1;\n\t};\n\n\t/**\n\t * Internal iterator. Applies extra safety checks for \n\t * removing items from the array. \n\t * @param {Function} callback \n\t * @param {Number=} lowerBound \n\t * @param {Number=} upperBound \n\t * @private\n\t */\n\tTone.Timeline.prototype._iterate = function(callback, lowerBound, upperBound){\n\t\tthis._iterating = true;\n\t\tlowerBound = this.defaultArg(lowerBound, 0);\n\t\tupperBound = this.defaultArg(upperBound, this._timeline.length - 1);\n\t\tfor (var i = lowerBound; i <= upperBound; i++){\n\t\t\tcallback(this._timeline[i]);\n\t\t}\n\t\tthis._iterating = false;\n\t\tif (this._toRemove.length > 0){\n\t\t\tfor (var j = 0; j < this._toRemove.length; j++){\n\t\t\t\tvar index = this._timeline.indexOf(this._toRemove[j]);\n\t\t\t\tif (index !== -1){\n\t\t\t\t\tthis._timeline.splice(index, 1);\n\t\t\t\t}\n\t\t\t}\n\t\t\tthis._toRemove = [];\n\t\t}\n\t};\n\n\t/**\n\t * Iterate over everything in the array\n\t * @param {Function} callback The callback to invoke with every item\n\t * @returns {Tone.Timeline} this\n\t */\n\tTone.Timeline.prototype.forEach = function(callback){\n\t\tthis._iterate(callback);\n\t\treturn this;\n\t};\n\n\t/**\n\t * Iterate over everything in the array at or before the given time.\n\t * @param {Number} time The time to check if items are before\n\t * @param {Function} callback The callback to invoke with every item\n\t * @returns {Tone.Timeline} this\n\t */\n\tTone.Timeline.prototype.forEachBefore = function(time, callback){\n\t\t//iterate over the items in reverse so that removing an item doesn't break things\n\t\tvar upperBound = this._search(time);\n\t\tif (upperBound !== -1){\n\t\t\tthis._iterate(callback, 0, upperBound);\n\t\t}\n\t\treturn this;\n\t};\n\n\t/**\n\t * Iterate over everything in the array after the given time.\n\t * @param {Number} time The time to check if items are before\n\t * @param {Function} callback The callback to invoke with every item\n\t * @returns {Tone.Timeline} this\n\t */\n\tTone.Timeline.prototype.forEachAfter = function(time, callback){\n\t\t//iterate over the items in reverse so that removing an item doesn't break things\n\t\tvar lowerBound = this._search(time);\n\t\tthis._iterate(callback, lowerBound + 1);\n\t\treturn this;\n\t};\n\n\t/**\n\t * Iterate over everything in the array at or after the given time. Similar to \n\t * forEachAfter, but includes the item(s) at the given time.\n\t * @param {Number} time The time to check if items are before\n\t * @param {Function} callback The callback to invoke with every item\n\t * @returns {Tone.Timeline} this\n\t */\n\tTone.Timeline.prototype.forEachFrom = function(time, callback){\n\t\t//iterate over the items in reverse so that removing an item doesn't break things\n\t\tvar lowerBound = this._search(time);\n\t\t//work backwards until the event time is less than time\n\t\twhile (lowerBound >= 0 && this._timeline[lowerBound].time >= time){\n\t\t\tlowerBound--;\n\t\t}\n\t\tthis._iterate(callback, lowerBound + 1);\n\t\treturn this;\n\t};\n\n\t/**\n\t * Iterate over everything in the array at the given time\n\t * @param {Number} time The time to check if items are before\n\t * @param {Function} callback The callback to invoke with every item\n\t * @returns {Tone.Timeline} this\n\t */\n\tTone.Timeline.prototype.forEachAtTime = function(time, callback){\n\t\t//iterate over the items in reverse so that removing an item doesn't break things\n\t\tvar upperBound = this._search(time);\n\t\tif (upperBound !== -1){\n\t\t\tthis._iterate(function(event){\n\t\t\t\tif (event.time === time){\n\t\t\t\t\tcallback(event);\n\t\t\t\t} \n\t\t\t}, 0, upperBound);\n\t\t}\n\t\treturn this;\n\t};\n\n\t/**\n\t * Clean up.\n\t * @return {Tone.Timeline} this\n\t */\n\tTone.Timeline.prototype.dispose = function(){\n\t\tTone.prototype.dispose.call(this);\n\t\tthis._timeline = null;\n\t\tthis._toRemove = null;\n\t};\n\n\treturn Tone.Timeline;\n});","define([\"Tone/core/Tone\", \"Tone/signal/Multiply\", \"Tone/signal/Signal\"], function(Tone){\n\n\t\"use strict\";\n\n\t/**\n\t * @class Negate the incoming signal. i.e. an input signal of 10 will output -10\n\t *\n\t * @constructor\n\t * @extends {Tone.SignalBase}\n\t * @example\n\t * var neg = new Tone.Negate();\n\t * var sig = new Tone.Signal(-2).connect(neg);\n\t * //output of neg is positive 2. \n\t */\n\tTone.Negate = function(){\n\t\t/**\n\t\t * negation is done by multiplying by -1\n\t\t * @type {Tone.Multiply}\n\t\t * @private\n\t\t */\n\t\tthis._multiply = this.input = this.output = new Tone.Multiply(-1);\n\t};\n\n\tTone.extend(Tone.Negate, Tone.SignalBase);\n\n\t/**\n\t * clean up\n\t * @returns {Tone.Negate} this\n\t */\n\tTone.Negate.prototype.dispose = function(){\n\t\tTone.prototype.dispose.call(this);\n\t\tthis._multiply.dispose();\n\t\tthis._multiply = null;\n\t\treturn this;\n\t}; \n\n\treturn Tone.Negate;\n});","define([\"Tone/core/Tone\", \"Tone/signal/Signal\", \"Tone/signal/Multiply\", \"Tone/signal/WaveShaper\"], \nfunction(Tone){\n\n\t\"use strict\";\n\n\t/**\n\t * @class GreaterThanZero outputs 1 when the input is strictly greater than zero\n\t * \n\t * @constructor\n\t * @extends {Tone.SignalBase}\n\t * @example\n\t * var gt0 = new Tone.GreaterThanZero();\n\t * var sig = new Tone.Signal(0.01).connect(gt0);\n\t * //the output of gt0 is 1. \n\t * sig.value = 0;\n\t * //the output of gt0 is 0. \n\t */\n\tTone.GreaterThanZero = function(){\n\t\t\n\t\t/**\n\t\t * @type {Tone.WaveShaper}\n\t\t * @private\n\t\t */\n\t\tthis._thresh = this.output = new Tone.WaveShaper(function(val){\n\t\t\tif (val <= 0){\n\t\t\t\treturn 0;\n\t\t\t} else {\n\t\t\t\treturn 1;\n\t\t\t}\n\t\t}, 127);\n\n\t\t/**\n\t\t * scale the first thresholded signal by a large value.\n\t\t * this will help with values which are very close to 0\n\t\t * @type {Tone.Multiply}\n\t\t * @private\n\t\t */\n\t\tthis._scale = this.input = new Tone.Multiply(10000);\n\n\t\t//connections\n\t\tthis._scale.connect(this._thresh);\n\t};\n\n\tTone.extend(Tone.GreaterThanZero, Tone.SignalBase);\n\n\t/**\n\t * dispose method\n\t * @returns {Tone.GreaterThanZero} this\n\t */\n\tTone.GreaterThanZero.prototype.dispose = function(){\n\t\tTone.prototype.dispose.call(this);\n\t\tthis._scale.dispose();\n\t\tthis._scale = null;\n\t\tthis._thresh.dispose();\n\t\tthis._thresh = null;\n\t\treturn this;\n\t};\n\n\treturn Tone.GreaterThanZero;\n});","define([\"Tone/core/Tone\", \"Tone/signal/TimelineSignal\", \"Tone/core/TimelineState\", \n\t\"Tone/core/Emitter\", \"Tone/core/Context\"], function (Tone) {\n\n\t\"use strict\";\n\n\t/**\n\t * @class A sample accurate clock which provides a callback at the given rate. \n\t * While the callback is not sample-accurate (it is still susceptible to\n\t * loose JS timing), the time passed in as the argument to the callback\n\t * is precise. For most applications, it is better to use Tone.Transport\n\t * instead of the Clock by itself since you can synchronize multiple callbacks.\n\t *\n\t * \t@constructor\n\t * @extends {Tone.Emitter}\n\t * \t@param {function} callback The callback to be invoked with the time of the audio event\n\t * \t@param {Frequency} frequency The rate of the callback\n\t * \t@example\n\t * //the callback will be invoked approximately once a second\n\t * //and will print the time exactly once a second apart.\n\t * var clock = new Tone.Clock(function(time){\n\t * \tconsole.log(time);\n\t * }, 1);\n\t */\n\tTone.Clock = function(){\n\n\t\tTone.Emitter.call(this);\n\n\t\tvar options = this.optionsObject(arguments, [\"callback\", \"frequency\"], Tone.Clock.defaults);\n\n\t\t/**\n\t\t * The callback function to invoke at the scheduled tick.\n\t\t * @type {Function}\n\t\t */\n\t\tthis.callback = options.callback;\n\n\t\t/**\n\t\t * The next time the callback is scheduled.\n\t\t * @type {Number}\n\t\t * @private\n\t\t */\n\t\tthis._nextTick = 0;\n\n\t\t/**\n\t\t * The last state of the clock.\n\t\t * @type {State}\n\t\t * @private\n\t\t */\n\t\tthis._lastState = Tone.State.Stopped;\n\n\t\t/**\n\t\t * The rate the callback function should be invoked. \n\t\t * @type {BPM}\n\t\t * @signal\n\t\t */\n\t\tthis.frequency = new Tone.TimelineSignal(options.frequency, Tone.Type.Frequency);\n\t\tthis._readOnly(\"frequency\");\n\n\t\t/**\n\t\t * The number of times the callback was invoked. Starts counting at 0\n\t\t * and increments after the callback was invoked. \n\t\t * @type {Ticks}\n\t\t * @readOnly\n\t\t */\n\t\tthis.ticks = 0;\n\n\t\t/**\n\t\t * The state timeline\n\t\t * @type {Tone.TimelineState}\n\t\t * @private\n\t\t */\n\t\tthis._state = new Tone.TimelineState(Tone.State.Stopped);\n\n\t\t/**\n\t\t * The loop function bound to its context. \n\t\t * This is necessary to remove the event in the end.\n\t\t * @type {Function}\n\t\t * @private\n\t\t */\n\t\tthis._boundLoop = this._loop.bind(this);\n\n\t\t//bind a callback to the worker thread\n \tthis.context.on(\"tick\", this._boundLoop);\n\t};\n\n\tTone.extend(Tone.Clock, Tone.Emitter);\n\n\t/**\n\t * The defaults\n\t * @const\n\t * @type {Object}\n\t */\n\tTone.Clock.defaults = {\n\t\t\"callback\" : Tone.noOp,\n\t\t\"frequency\" : 1,\n\t\t\"lookAhead\" : \"auto\",\n\t};\n\n\t/**\n\t * Returns the playback state of the source, either \"started\", \"stopped\" or \"paused\".\n\t * @type {Tone.State}\n\t * @readOnly\n\t * @memberOf Tone.Clock#\n\t * @name state\n\t */\n\tObject.defineProperty(Tone.Clock.prototype, \"state\", {\n\t\tget : function(){\n\t\t\treturn this._state.getValueAtTime(this.now());\n\t\t}\n\t});\n\n\t/**\n\t * Start the clock at the given time. Optionally pass in an offset\n\t * of where to start the tick counter from.\n\t * @param {Time} time The time the clock should start\n\t * @param {Ticks=} offset Where the tick counter starts counting from.\n\t * @return {Tone.Clock} this\n\t */\n\tTone.Clock.prototype.start = function(time, offset){\n\t\ttime = this.toSeconds(time);\n\t\tif (this._state.getValueAtTime(time) !== Tone.State.Started){\n\t\t\tthis._state.add({\n\t\t\t\t\"state\" : Tone.State.Started, \n\t\t\t\t\"time\" : time,\n\t\t\t\t\"offset\" : offset\n\t\t\t});\n\t\t}\n\t\treturn this;\t\n\t};\n\n\t/**\n\t * Stop the clock. Stopping the clock resets the tick counter to 0.\n\t * @param {Time} [time=now] The time when the clock should stop.\n\t * @returns {Tone.Clock} this\n\t * @example\n\t * clock.stop();\n\t */\n\tTone.Clock.prototype.stop = function(time){\n\t\ttime = this.toSeconds(time);\n\t\tthis._state.cancel(time);\n\t\tthis._state.setStateAtTime(Tone.State.Stopped, time);\n\t\treturn this;\t\n\t};\n\n\n\t/**\n\t * Pause the clock. Pausing does not reset the tick counter.\n\t * @param {Time} [time=now] The time when the clock should stop.\n\t * @returns {Tone.Clock} this\n\t */\n\tTone.Clock.prototype.pause = function(time){\n\t\ttime = this.toSeconds(time);\n\t\tif (this._state.getValueAtTime(time) === Tone.State.Started){\n\t\t\tthis._state.setStateAtTime(Tone.State.Paused, time);\n\t\t}\n\t\treturn this;\t\n\t};\n\n\t/**\n\t * The scheduling loop.\n\t * @param {Number} time The current page time starting from 0\n\t * when the page was loaded.\n\t * @private\n\t */\n\tTone.Clock.prototype._loop = function(){\n\t\t//get the frequency value to compute the value of the next loop\n\t\tvar now = this.now();\n\t\t//if it's started\n\t\tvar lookAhead = this.context.lookAhead;\n\t\tvar updateInterval = this.context.updateInterval;\n\t\tvar lagCompensation = this.context.lag * 2;\n\t\tvar loopInterval = now + lookAhead + updateInterval + lagCompensation;\n\t\twhile (loopInterval > this._nextTick && this._state){\n\t\t\tvar currentState = this._state.getValueAtTime(this._nextTick);\n\t\t\tif (currentState !== this._lastState){\n\t\t\t\tthis._lastState = currentState;\n\t\t\t\tvar event = this._state.get(this._nextTick);\n\t\t\t\t// emit an event\n\t\t\t\tif (currentState === Tone.State.Started){\n\t\t\t\t\t//correct the time\n\t\t\t\t\tthis._nextTick = event.time;\n\t\t\t\t\tif (!this.isUndef(event.offset)){\n\t\t\t\t\t\tthis.ticks = event.offset;\n\t\t\t\t\t}\n\t\t\t\t\tthis.emit(\"start\", event.time, this.ticks);\n\t\t\t\t} else if (currentState === Tone.State.Stopped){\n\t\t\t\t\tthis.ticks = 0;\n\n\t\t\t\t\tthis.emit(\"stop\", event.time);\n\t\t\t\t} else if (currentState === Tone.State.Paused){\n\t\t\t\t\tthis.emit(\"pause\", event.time);\n\t\t\t\t}\n\t\t\t}\n\t\t\tvar tickTime = this._nextTick;\n\t\t\tif (this.frequency){\n\t\t\t\tthis._nextTick += 1 / this.frequency.getValueAtTime(this._nextTick);\n\t\t\t\tif (currentState === Tone.State.Started){\n\t\t\t\t\tthis.callback(tickTime);\n\t\t\t\t\tthis.ticks++;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t};\n\n\t/**\n\t * Returns the scheduled state at the given time.\n\t * @param {Time} time The time to query.\n\t * @return {String} The name of the state input in setStateAtTime.\n\t * @example\n\t * clock.start(\"+0.1\");\n\t * clock.getStateAtTime(\"+0.1\"); //returns \"started\"\n\t */\n\tTone.Clock.prototype.getStateAtTime = function(time){\n\t\ttime = this.toSeconds(time);\n\t\treturn this._state.getValueAtTime(time);\n\t};\n\n\t/**\n\t * Clean up\n\t * @returns {Tone.Clock} this\n\t */\n\tTone.Clock.prototype.dispose = function(){\n\t\tTone.Emitter.prototype.dispose.call(this);\n\t\tthis.context.off(\"tick\", this._boundLoop);\n\t\tthis._writable(\"frequency\");\n\t\tthis.frequency.dispose();\n\t\tthis.frequency = null;\n\t\tthis._boundLoop = null;\n\t\tthis._nextTick = Infinity;\n\t\tthis.callback = null;\n\t\tthis._state.dispose();\n\t\tthis._state = null;\n\t};\n\n\treturn Tone.Clock;\n});","'use strict';\ndefine(function (require) {\n\n var p5sound = require('master');\n var AudioVoice = require('audioVoice');\n var noteToFreq = require('helpers').noteToFreq;\n\n var DEFAULT_SUSTAIN = 0.15;\n\n /**\n * A MonoSynth is used as a single voice for sound synthesis.\n * This is a class to be used in conjunction with the PolySynth\n * class. Custom synthetisers should be built inheriting from\n * this class.\n *\n * @class p5.MonoSynth\n * @constructor\n * @example\n *
\n * var monoSynth;\n *\n * function setup() {\n * var cnv = createCanvas(100, 100);\n * cnv.mousePressed(playSynth);\n *\n * monoSynth = new p5.MonoSynth();\n *\n * textAlign(CENTER);\n * text('click to play', width/2, height/2);\n * }\n *\n * function playSynth() {\n * // time from now (in seconds)\n * var time = 0;\n * // note duration (in seconds)\n * var dur = 0.25;\n * // velocity (volume, from 0 to 1)\n * var v = 0.2;\n *\n * monoSynth.play(\"G3\", v, time, dur);\n * monoSynth.play(\"C4\", v, time += dur, dur);\n *\n * background(random(255), random(255), 255);\n * text('click to play', width/2, height/2);\n * }\n *
\n **/\n\n p5.MonoSynth = function () {\n AudioVoice.call(this);\n\n this.oscillator = new p5.Oscillator();\n\n this.env = new p5.Envelope();\n this.env.setRange(1, 0);\n this.env.setExp(true);\n\n //set params\n this.setADSR(0.02, 0.25, 0.05, 0.35);\n\n // oscillator --> env --> this.output (gain) --> p5.soundOut\n this.oscillator.disconnect();\n this.oscillator.connect(this.output);\n\n this.env.disconnect();\n this.env.setInput(this.output.gain);\n\n // reset oscillator gain to 1.0\n this.oscillator.output.gain.value = 1.0;\n\n this.oscillator.start();\n this.connect();\n\n p5sound.soundArray.push(this);\n };\n\n p5.MonoSynth.prototype = Object.create(p5.AudioVoice.prototype);\n\n /**\n * Play tells the MonoSynth to start playing a note. This method schedules\n * the calling of .triggerAttack and .triggerRelease.\n *\n * @method play\n * @for p5.MonoSynth\n * @param {String | Number} note the note you want to play, specified as a\n * frequency in Hertz (Number) or as a midi\n * value in Note/Octave format (\"C4\", \"Eb3\"...etc\")\n * See \n * Tone. Defaults to 440 hz.\n * @param {Number} [velocity] velocity of the note to play (ranging from 0 to 1)\n * @param {Number} [secondsFromNow] time from now (in seconds) at which to play\n * @param {Number} [sustainTime] time to sustain before releasing the envelope\n * @example\n *
\n * var monoSynth;\n *\n * function setup() {\n * var cnv = createCanvas(100, 100);\n * cnv.mousePressed(playSynth);\n *\n * monoSynth = new p5.MonoSynth();\n *\n * textAlign(CENTER);\n * text('click to play', width/2, height/2);\n * }\n *\n * function playSynth() {\n * // time from now (in seconds)\n * var time = 0;\n * // note duration (in seconds)\n * var dur = 1/6;\n * // note velocity (volume, from 0 to 1)\n * var v = random();\n *\n * monoSynth.play(\"Fb3\", v, 0, dur);\n * monoSynth.play(\"Gb3\", v, time += dur, dur);\n *\n * background(random(255), random(255), 255);\n * text('click to play', width/2, height/2);\n * }\n *
\n *\n */\n p5.MonoSynth.prototype.play = function (note, velocity, secondsFromNow, susTime) {\n this.triggerAttack(note, velocity, ~~secondsFromNow);\n this.triggerRelease(~~secondsFromNow + (susTime || DEFAULT_SUSTAIN));\n };\n\n /**\n * Trigger the Attack, and Decay portion of the Envelope.\n * Similar to holding down a key on a piano, but it will\n * hold the sustain level until you let go.\n *\n * @param {String | Number} note the note you want to play, specified as a\n * frequency in Hertz (Number) or as a midi\n * value in Note/Octave format (\"C4\", \"Eb3\"...etc\")\n * See \n * Tone. Defaults to 440 hz\n * @param {Number} [velocity] velocity of the note to play (ranging from 0 to 1)\n * @param {Number} [secondsFromNow] time from now (in seconds) at which to play\n * @method triggerAttack\n * @for p5.MonoSynth\n * @example\n *
\n * var monoSynth = new p5.MonoSynth();\n *\n * function mousePressed() {\n * monoSynth.triggerAttack(\"E3\");\n * }\n *\n * function mouseReleased() {\n * monoSynth.triggerRelease();\n * }\n *
\n */\n p5.MonoSynth.prototype.triggerAttack = function (note, velocity, secondsFromNow) {\n var secondsFromNow = ~~secondsFromNow;\n var freq = noteToFreq(note);\n var vel = velocity || 0.1;\n this.oscillator.freq(freq, 0, secondsFromNow);\n this.env.ramp(this.output.gain, secondsFromNow, vel);\n };\n\n /**\n * Trigger the release of the Envelope. This is similar to releasing\n * the key on a piano and letting the sound fade according to the\n * release level and release time.\n *\n * @param {Number} secondsFromNow time to trigger the release\n * @method triggerRelease\n * @for p5.MonoSynth\n * @example\n *
\n * var monoSynth = new p5.MonoSynth();\n *\n * function mousePressed() {\n * monoSynth.triggerAttack(\"E3\");\n * }\n *\n * function mouseReleased() {\n * monoSynth.triggerRelease();\n * }\n *
\n */\n p5.MonoSynth.prototype.triggerRelease = function (secondsFromNow) {\n var secondsFromNow = secondsFromNow || 0;\n this.env.ramp(this.output.gain, secondsFromNow, 0);\n };\n\n /**\n * Set values like a traditional\n * \n * ADSR envelope\n * .\n *\n * @method setADSR\n * @for p5.MonoSynth\n * @param {Number} attackTime Time (in seconds before envelope\n * reaches Attack Level\n * @param {Number} [decayTime] Time (in seconds) before envelope\n * reaches Decay/Sustain Level\n * @param {Number} [susRatio] Ratio between attackLevel and releaseLevel, on a scale from 0 to 1,\n * where 1.0 = attackLevel, 0.0 = releaseLevel.\n * The susRatio determines the decayLevel and the level at which the\n * sustain portion of the envelope will sustain.\n * For example, if attackLevel is 0.4, releaseLevel is 0,\n * and susAmt is 0.5, the decayLevel would be 0.2. If attackLevel is\n * increased to 1.0 (using setRange),\n * then decayLevel would increase proportionally, to become 0.5.\n * @param {Number} [releaseTime] Time in seconds from now (defaults to 0)\n */\n p5.MonoSynth.prototype.setADSR = function (attack,decay,sustain,release) {\n this.env.setADSR(attack, decay, sustain, release);\n };\n\n\n /**\n * Getters and Setters\n * @property {Number} attack\n * @for p5.MonoSynth\n */\n /**\n * @property {Number} decay\n * @for p5.MonoSynth\n */\n /**\n * @property {Number} sustain\n * @for p5.MonoSynth\n */\n /**\n * @property {Number} release\n * @for p5.MonoSynth\n */\n Object.defineProperties(p5.MonoSynth.prototype, {\n 'attack': {\n get : function() {\n return this.env.aTime;\n },\n set : function(attack) {\n this.env.setADSR(attack, this.env.dTime,\n this.env.sPercent, this.env.rTime);\n }\n },\n 'decay': {\n get : function() {\n return this.env.dTime;\n },\n set : function(decay) {\n this.env.setADSR(this.env.aTime, decay,\n this.env.sPercent, this.env.rTime);\n }\n },\n 'sustain': {\n get : function() {\n return this.env.sPercent;\n },\n set : function(sustain) {\n this.env.setADSR(this.env.aTime, this.env.dTime,\n sustain, this.env.rTime);\n }\n },\n 'release': {\n get : function() {\n return this.env.rTime;\n },\n set : function(release) {\n this.env.setADSR(this.env.aTime, this.env.dTime,\n this.env.sPercent, release);\n }\n },\n });\n\n\n /**\n * MonoSynth amp\n * @method amp\n * @for p5.MonoSynth\n * @param {Number} vol desired volume\n * @param {Number} [rampTime] Time to reach new volume\n * @return {Number} new volume value\n */\n p5.MonoSynth.prototype.amp = function(vol, rampTime) {\n var t = rampTime || 0;\n if (typeof vol !== 'undefined') {\n this.oscillator.amp(vol, t);\n }\n return this.oscillator.amp().value;\n };\n\n /**\n * Connect to a p5.sound / Web Audio object.\n *\n * @method connect\n * @for p5.MonoSynth\n * @param {Object} unit A p5.sound or Web Audio object\n */\n\n p5.MonoSynth.prototype.connect = function(unit) {\n var u = unit || p5sound.input;\n this.output.connect(u.input ? u.input : u);\n };\n\n /**\n * Disconnect all outputs\n *\n * @method disconnect\n * @for p5.MonoSynth\n */\n p5.MonoSynth.prototype.disconnect = function() {\n if (this.output) {\n this.output.disconnect();\n }\n };\n\n\n /**\n * Get rid of the MonoSynth and free up its resources / memory.\n *\n * @method dispose\n * @for p5.MonoSynth\n */\n p5.MonoSynth.prototype.dispose = function() {\n AudioVoice.prototype.dispose.apply(this);\n\n if (this.env) {\n this.env.dispose();\n }\n if (this.oscillator) {\n this.oscillator.dispose();\n }\n };\n\n});\n","'use strict';\ndefine(function() {\n var p5sound = require('master');\n\n /**\n * Base class for monophonic synthesizers. Any extensions of this class\n * should follow the API and implement the methods below in order to\n * remain compatible with p5.PolySynth();\n *\n * @class p5.AudioVoice\n * @constructor\n */\n p5.AudioVoice = function () {\n\t this.ac = p5sound.audiocontext;\n\t this.output = this.ac.createGain();\n\t this.connect();\n\t p5sound.soundArray.push(this);\n };\n\n p5.AudioVoice.prototype.play = function (note, velocity, secondsFromNow, sustime) {\n };\n\n p5.AudioVoice.prototype.triggerAttack = function (note, velocity, secondsFromNow) {\n };\n\n p5.AudioVoice.prototype.triggerRelease = function (secondsFromNow) {\n };\n\n p5.AudioVoice.prototype.amp = function(vol, rampTime) {\n };\n\n /**\n * Connect to p5 objects or Web Audio Nodes\n * @method connect\n * @for p5.AudioVoice\n * @param {Object} unit\n */\n p5.AudioVoice.prototype.connect = function(unit) {\n var u = unit || p5sound.input;\n this.output.connect(u.input ? u.input : u);\n };\n\n /**\n * Disconnect from soundOut\n * @method disconnect\n * @for p5.AudioVoice\n */\n p5.AudioVoice.prototype.disconnect = function() {\n this.output.disconnect();\n };\n\n p5.AudioVoice.prototype.dispose = function() {\n if (this.output) {\n this.output.disconnect();\n delete this.output;\n }\n };\n\n return p5.AudioVoice;\n});\n","'use strict';\ndefine(function (require) {\n\n var p5sound = require('master');\n var TimelineSignal = require('Tone/signal/TimelineSignal');\n var noteToFreq = require('helpers').noteToFreq;\n\n /**\n * An AudioVoice is used as a single voice for sound synthesis.\n * The PolySynth class holds an array of AudioVoice, and deals\n * with voices allocations, with setting notes to be played, and\n * parameters to be set.\n *\n * @class p5.PolySynth\n * @constructor\n *\n * @param {Number} [synthVoice] A monophonic synth voice inheriting\n * the AudioVoice class. Defaults to p5.MonoSynth\n * @param {Number} [maxVoices] Number of voices, defaults to 8;\n * @example\n *
\n * var polySynth;\n *\n * function setup() {\n * var cnv = createCanvas(100, 100);\n * cnv.mousePressed(playSynth);\n *\n * polySynth = new p5.PolySynth();\n *\n * textAlign(CENTER);\n * text('click to play', width/2, height/2);\n * }\n *\n * function playSynth() {\n * // note duration (in seconds)\n * var dur = 1.5;\n *\n * // time from now (in seconds)\n * var time = 0;\n *\n * // velocity (volume, from 0 to 1)\n * var vel = 0.1;\n *\n * // notes can overlap with each other\n * polySynth.play(\"G2\", vel, 0, dur);\n * polySynth.play(\"C3\", vel, time += 1/3, dur);\n * polySynth.play(\"G3\", vel, time += 1/3, dur);\n *\n * background(random(255), random(255), 255);\n * text('click to play', width/2, height/2);\n * }\n *
\n **/\n p5.PolySynth = function(audioVoice, maxVoices) {\n //audiovoices will contain maxVoices many monophonic synths\n this.audiovoices = [];\n\n /**\n * An object that holds information about which notes have been played and\n * which notes are currently being played. New notes are added as keys\n * on the fly. While a note has been attacked, but not released, the value of the\n * key is the audiovoice which is generating that note. When notes are released,\n * the value of the key becomes undefined.\n * @property notes\n */\n this.notes = {};\n\n //indices of the most recently used, and least recently used audiovoice\n this._newest = 0;\n this._oldest = 0;\n\n /**\n * A PolySynth must have at least 1 voice, defaults to 8\n * @property polyvalue\n */\n this.maxVoices = maxVoices || 8;\n\n /**\n * Monosynth that generates the sound for each note that is triggered. The\n * p5.PolySynth defaults to using the p5.MonoSynth as its voice.\n * @property AudioVoice\n */\n this.AudioVoice = audioVoice === undefined ? p5.MonoSynth : audioVoice;\n\n /**\n * This value must only change as a note is attacked or released. Due to delay\n * and sustain times, Tone.TimelineSignal is required to schedule the change in value.\n\t * @private\n * @property {Tone.TimelineSignal} _voicesInUse\n */\n this._voicesInUse = new TimelineSignal(0);\n\n this.output = p5sound.audiocontext.createGain();\n this.connect();\n\n //Construct the appropriate number of audiovoices\n this._allocateVoices();\n p5sound.soundArray.push(this);\n };\n\n /**\n * Construct the appropriate number of audiovoices\n * @private\n * @for p5.PolySynth\n * @method _allocateVoices\n */\n p5.PolySynth.prototype._allocateVoices = function() {\n for(var i = 0; i< this.maxVoices; i++) {\n this.audiovoices.push(new this.AudioVoice());\n this.audiovoices[i].disconnect();\n this.audiovoices[i].connect(this.output);\n }\n };\n\n /**\n * Play a note by triggering noteAttack and noteRelease with sustain time\n *\n * @method play\n * @for p5.PolySynth\n * @param {Number} [note] midi note to play (ranging from 0 to 127 - 60 being a middle C)\n * @param {Number} [velocity] velocity of the note to play (ranging from 0 to 1)\n * @param {Number} [secondsFromNow] time from now (in seconds) at which to play\n * @param {Number} [sustainTime] time to sustain before releasing the envelope\n * @example\n *
\n * var polySynth;\n *\n * function setup() {\n * var cnv = createCanvas(100, 100);\n * cnv.mousePressed(playSynth);\n *\n * polySynth = new p5.PolySynth();\n *\n * textAlign(CENTER);\n * text('click to play', width/2, height/2);\n * }\n *\n * function playSynth() {\n * // note duration (in seconds)\n * var dur = 0.1;\n *\n * // time from now (in seconds)\n * var time = 0;\n *\n * // velocity (volume, from 0 to 1)\n * var vel = 0.1;\n *\n * polySynth.play(\"G2\", vel, 0, dur);\n * polySynth.play(\"C3\", vel, 0, dur);\n * polySynth.play(\"G3\", vel, 0, dur);\n *\n * background(random(255), random(255), 255);\n * text('click to play', width/2, height/2);\n * }\n *
\n */\n p5.PolySynth.prototype.play = function (note,velocity, secondsFromNow, susTime) {\n var susTime = susTime || 1;\n this.noteAttack(note, velocity, secondsFromNow);\n this.noteRelease(note, secondsFromNow + susTime);\n };\n\n\n /**\n * noteADSR sets the envelope for a specific note that has just been triggered.\n * Using this method modifies the envelope of whichever audiovoice is being used\n * to play the desired note. The envelope should be reset before noteRelease is called\n * in order to prevent the modified envelope from being used on other notes.\n *\n * @method noteADSR\n * @for p5.PolySynth\n * @param {Number} [note] Midi note on which ADSR should be set.\n * @param {Number} [attackTime] Time (in seconds before envelope\n * reaches Attack Level\n * @param {Number} [decayTime] Time (in seconds) before envelope\n * reaches Decay/Sustain Level\n * @param {Number} [susRatio] Ratio between attackLevel and releaseLevel, on a scale from 0 to 1,\n * where 1.0 = attackLevel, 0.0 = releaseLevel.\n * The susRatio determines the decayLevel and the level at which the\n * sustain portion of the envelope will sustain.\n * For example, if attackLevel is 0.4, releaseLevel is 0,\n * and susAmt is 0.5, the decayLevel would be 0.2. If attackLevel is\n * increased to 1.0 (using setRange),\n * then decayLevel would increase proportionally, to become 0.5.\n * @param {Number} [releaseTime] Time in seconds from now (defaults to 0)\n **/\n\n p5.PolySynth.prototype.noteADSR = function (note,a,d,s,r,timeFromNow) {\n var now = p5sound.audiocontext.currentTime;\n var timeFromNow = timeFromNow || 0;\n var t = now + timeFromNow\n this.audiovoices[ this.notes[note].getValueAtTime(t) ].setADSR(a,d,s,r);\n };\n\n\n /**\n * Set the PolySynths global envelope. This method modifies the envelopes of each\n * monosynth so that all notes are played with this envelope.\n *\n * @method setADSR\n * @for p5.PolySynth\n * @param {Number} [attackTime] Time (in seconds before envelope\n * reaches Attack Level\n * @param {Number} [decayTime] Time (in seconds) before envelope\n * reaches Decay/Sustain Level\n * @param {Number} [susRatio] Ratio between attackLevel and releaseLevel, on a scale from 0 to 1,\n * where 1.0 = attackLevel, 0.0 = releaseLevel.\n * The susRatio determines the decayLevel and the level at which the\n * sustain portion of the envelope will sustain.\n * For example, if attackLevel is 0.4, releaseLevel is 0,\n * and susAmt is 0.5, the decayLevel would be 0.2. If attackLevel is\n * increased to 1.0 (using setRange),\n * then decayLevel would increase proportionally, to become 0.5.\n * @param {Number} [releaseTime] Time in seconds from now (defaults to 0)\n **/\n p5.PolySynth.prototype.setADSR = function(a,d,s,r) {\n this.audiovoices.forEach(function(voice) {\n voice.setADSR(a,d,s,r);\n });\n };\n\n /**\n * Trigger the Attack, and Decay portion of a MonoSynth.\n * Similar to holding down a key on a piano, but it will\n * hold the sustain level until you let go.\n *\n * @method noteAttack\n * @for p5.PolySynth\n * @param {Number} [note] midi note on which attack should be triggered.\n * @param {Number} [velocity] velocity of the note to play (ranging from 0 to 1)/\n * @param {Number} [secondsFromNow] time from now (in seconds)\n * @example\n *
\n * var polySynth = new p5.PolySynth();\n * var pitches = [\"G\", \"D\", \"G\", \"C\"];\n * var octaves = [2, 3, 4];\n *\n * function mousePressed() {\n * // play a chord: multiple notes at the same time\n * for (var i = 0; i < 4; i++) {\n * var note = random(pitches) + random(octaves);\n * polySynth.noteAttack(note, 0.1);\n * }\n * }\n *\n * function mouseReleased() {\n * // release all voices\n * polySynth.noteRelease();\n * }\n *
\n */\n p5.PolySynth.prototype.noteAttack = function (_note, _velocity, secondsFromNow) {\n //this value goes to the audiovoices which handle their own scheduling\n var secondsFromNow = ~~secondsFromNow;\n\n //this value is used by this._voicesInUse\n var acTime = p5sound.audiocontext.currentTime + secondsFromNow;\n\n //Convert note to frequency if necessary. This is because entries into this.notes\n //should be based on frequency for the sake of consistency.\n var note = noteToFreq(_note);\n var velocity = _velocity || 0.1;\n\n var currentVoice;\n\n //Release the note if it is already playing\n if (this.notes[note] && this.notes[note].getValueAtTime(acTime) !== null) {\n this.noteRelease(note, 0);\n }\n\n //Check to see how many voices are in use at the time the note will start\n if (this._voicesInUse.getValueAtTime(acTime) < this.maxVoices) {\n currentVoice = Math.max(~~this._voicesInUse.getValueAtTime(acTime), 0);\n }\n //If we are exceeding the polyvalue, bump off the oldest notes and replace\n //with a new note\n else {\n currentVoice = this._oldest;\n\n var oldestNote = p5.prototype.freqToMidi(this.audiovoices[this._oldest].oscillator.freq().value);\n this.noteRelease(oldestNote);\n this._oldest = ( this._oldest + 1 ) % (this.maxVoices - 1);\n }\n\n //Overrite the entry in the notes object. A note (frequency value)\n //corresponds to the index of the audiovoice that is playing it\n this.notes[note] = new TimelineSignal();\n this.notes[note].setValueAtTime(currentVoice, acTime);\n\n //Find the scheduled change in this._voicesInUse that will be previous to this new note\n //Add 1 and schedule this value at time 't', when this note will start playing\n var previousVal = this._voicesInUse._searchBefore(acTime) === null ? 0 : this._voicesInUse._searchBefore(acTime).value;\n this._voicesInUse.setValueAtTime(previousVal + 1, acTime);\n\n //Then update all scheduled values that follow to increase by 1\n this._updateAfter(acTime, 1);\n\n this._newest = currentVoice;\n //The audiovoice handles the actual scheduling of the note\n if (typeof velocity === 'number') {\n var maxRange = 1 / this._voicesInUse.getValueAtTime(acTime) * 2;\n velocity = velocity > maxRange ? maxRange : velocity;\n }\n this.audiovoices[currentVoice].triggerAttack(note, velocity, secondsFromNow);\n };\n\n /**\n * Private method to ensure accurate values of this._voicesInUse\n * Any time a new value is scheduled, it is necessary to increment all subsequent\n * scheduledValues after attack, and decrement all subsequent\n * scheduledValues after release\n *\n * @private\n * @for p5.PolySynth\n * @param {[type]} time [description]\n * @param {[type]} value [description]\n * @return {[type]} [description]\n */\n p5.PolySynth.prototype._updateAfter = function(time, value) {\n if(this._voicesInUse._searchAfter(time) === null) {\n return;\n } else{\n this._voicesInUse._searchAfter(time).value += value;\n var nextTime = this._voicesInUse._searchAfter(time).time;\n this._updateAfter(nextTime, value);\n }\n };\n\n\n /**\n * Trigger the Release of an AudioVoice note. This is similar to releasing\n * the key on a piano and letting the sound fade according to the\n * release level and release time.\n *\n * @method noteRelease\n * @for p5.PolySynth\n * @param {Number} [note] midi note on which attack should be triggered.\n * If no value is provided, all notes will be released.\n * @param {Number} [secondsFromNow] time to trigger the release\n * @example\n *
\n * var pitches = [\"G\", \"D\", \"G\", \"C\"];\n * var octaves = [2, 3, 4];\n * var polySynth = new p5.PolySynth();\n *\n * function mousePressed() {\n * // play a chord: multiple notes at the same time\n * for (var i = 0; i < 4; i++) {\n * var note = random(pitches) + random(octaves);\n * polySynth.noteAttack(note, 0.1);\n * }\n * }\n *\n * function mouseReleased() {\n * // release all voices\n * polySynth.noteRelease();\n * }\n *
\n *\n */\n p5.PolySynth.prototype.noteRelease = function (_note,secondsFromNow) {\n var now = p5sound.audiocontext.currentTime;\n var tFromNow = secondsFromNow || 0;\n var t = now + tFromNow;\n\n // if a note value is not provided, release all voices\n if (!_note) {\n this.audiovoices.forEach(function(voice) {\n voice.triggerRelease(tFromNow)\n });\n this._voicesInUse.setValueAtTime(0, t);\n for (var n in this.notes) {\n this.notes[n].dispose();\n delete this.notes[n];\n }\n return;\n }\n\n //Make sure note is in frequency inorder to query the this.notes object\n var note = noteToFreq(_note);\n\n if (!this.notes[note] || this.notes[note].getValueAtTime(t) === null) {\n console.warn('Cannot release a note that is not already playing');\n } else {\n //Find the scheduled change in this._voicesInUse that will be previous to this new note\n //subtract 1 and schedule this value at time 't', when this note will stop playing\n var previousVal = Math.max(~~this._voicesInUse.getValueAtTime(t).value, 1);\n this._voicesInUse.setValueAtTime(previousVal - 1, t);\n //Then update all scheduled values that follow to decrease by 1 but never go below 0\n if (previousVal > 0) {\n this._updateAfter(t, -1);\n }\n\n this.audiovoices[ this.notes[note].getValueAtTime(t) ].triggerRelease(tFromNow);\n this.notes[note].dispose();\n delete this.notes[note];\n\n this._newest = this._newest === 0 ? 0 : (this._newest - 1) % (this.maxVoices - 1);\n }\n\n };\n\n /**\n * Connect to a p5.sound / Web Audio object.\n *\n * @method connect\n * @for p5.PolySynth\n * @param {Object} unit A p5.sound or Web Audio object\n */\n p5.PolySynth.prototype.connect = function (unit) {\n var u = unit || p5sound.input;\n this.output.connect(u.input ? u.input : u);\n };\n\n /**\n * Disconnect all outputs\n *\n * @method disconnect\n * @for p5.PolySynth\n */\n p5.PolySynth.prototype.disconnect = function() {\n if (this.output) {\n this.output.disconnect();\n }\n };\n\n /**\n * Get rid of the MonoSynth and free up its resources / memory.\n *\n * @method dispose\n * @for p5.PolySynth\n */\n p5.PolySynth.prototype.dispose = function() {\n this.audiovoices.forEach(function(voice) {\n voice.dispose();\n });\n\n if (this.output) {\n this.output.disconnect();\n delete this.output;\n }\n };\n\n});\n","'use strict';\n\ndefine(function (require) {\n\n require('audioworklet-polyfill');\n require('shims');\n require('audiocontext');\n var p5SOUND = require('master');\n require('helpers');\n require('errorHandler');\n require('audioWorklet');\n require('panner');\n require('soundfile');\n require('amplitude');\n require('fft');\n require('signal');\n require('oscillator');\n require('envelope');\n require('pulse');\n require('noise');\n require('audioin');\n require('filter');\n require('eq');\n require('panner3d');\n require('listener3d');\n require('delay');\n require('reverb');\n require('metro');\n require('looper');\n require('soundLoop');\n require('compressor');\n require('soundRecorder');\n require('peakDetect');\n require('gain');\n require('monosynth');\n require('polysynth');\n require('distortion');\n require('audioVoice');\n require('monosynth');\n require('polysynth');\n\n return p5SOUND;\n\n});\n","!function(){var e,t=[];function r(e){var r=this,n={},i=-1;this.parameters.forEach(function(e,o){var s=t[++i]||(t[i]=new Float32Array(r.bufferSize));s.fill(e.value),n[o]=s}),this.processor.realm.exec(\"self.sampleRate=sampleRate=\"+this.context.sampleRate+\";self.currentTime=currentTime=\"+this.context.currentTime);var s=o(e.inputBuffer),a=o(e.outputBuffer);this.instance.process([s],[a],n)}function o(e){for(var t=[],r=0;r= this.sampleLimit) {\\n this.stop();\\n return true;\\n }\\n\\n var input = inputs[0];\\n var output = outputs[0];\\n\\n for (var channel = 0; channel < output.length; ++channel) {\\n var inputChannel = input[channel];\\n\\n if (channel === 0) {\\n this.leftBuffers.push(inputChannel);\\n\\n if (this.numInputChannels === 1) {\\n this.rightBuffers.push(inputChannel);\\n }\\n } else if (channel === 1 && this.numInputChannels > 1) {\\n this.rightBuffers.push(inputChannel);\\n }\\n }\\n\\n this.recordedSamples += output[0].length;\\n return true;\\n }\\n }, {\\n key: \\\"record\\\",\\n value: function record(duration) {\\n if (duration) {\\n this.sampleLimit = Math.round(duration * sampleRate);\\n }\\n\\n this.recording = true;\\n }\\n }, {\\n key: \\\"stop\\\",\\n value: function stop() {\\n this.recording = false;\\n var buffers = this.getBuffers();\\n var leftBuffer = buffers[0].buffer;\\n var rightBuffer = buffers[1].buffer;\\n this.port.postMessage({\\n name: 'buffers',\\n leftBuffer: leftBuffer,\\n rightBuffer: rightBuffer\\n }, [leftBuffer, rightBuffer]);\\n this.clear();\\n }\\n }, {\\n key: \\\"getBuffers\\\",\\n value: function getBuffers() {\\n var buffers = [];\\n buffers.push(this.mergeBuffers(this.leftBuffers));\\n buffers.push(this.mergeBuffers(this.rightBuffers));\\n return buffers;\\n }\\n }, {\\n key: \\\"mergeBuffers\\\",\\n value: function mergeBuffers(channelBuffer) {\\n var result = new Float32Array(this.recordedSamples);\\n var offset = 0;\\n var lng = channelBuffer.length;\\n\\n for (var i = 0; i < lng; i++) {\\n var buffer = channelBuffer[i];\\n result.set(buffer, offset);\\n offset += buffer.length;\\n }\\n\\n return result;\\n }\\n }, {\\n key: \\\"clear\\\",\\n value: function clear() {\\n this.leftBuffers = [];\\n this.rightBuffers = [];\\n this.recordedSamples = 0;\\n this.sampleLimit = null;\\n }\\n }]);\\n\\n return RecorderProcessor;\\n}(_wrapNativeSuper(AudioWorkletProcessor));\\n\\nregisterProcessor(processorNames.recorderProcessor, RecorderProcessor);\"","export default \"function _typeof(obj) { if (typeof Symbol === \\\"function\\\" && typeof Symbol.iterator === \\\"symbol\\\") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === \\\"function\\\" && obj.constructor === Symbol && obj !== Symbol.prototype ? \\\"symbol\\\" : typeof obj; }; } return _typeof(obj); }\\n\\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\\\"Cannot call a class as a function\\\"); } }\\n\\nfunction _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if (\\\"value\\\" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }\\n\\nfunction _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }\\n\\nfunction _possibleConstructorReturn(self, call) { if (call && (_typeof(call) === \\\"object\\\" || typeof call === \\\"function\\\")) { return call; } return _assertThisInitialized(self); }\\n\\nfunction _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError(\\\"this hasn't been initialised - super() hasn't been called\\\"); } return self; }\\n\\nfunction _inherits(subClass, superClass) { if (typeof superClass !== \\\"function\\\" && superClass !== null) { throw new TypeError(\\\"Super expression must either be null or a function\\\"); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, writable: true, configurable: true } }); if (superClass) _setPrototypeOf(subClass, superClass); }\\n\\nfunction _wrapNativeSuper(Class) { var _cache = typeof Map === \\\"function\\\" ? new Map() : undefined; _wrapNativeSuper = function _wrapNativeSuper(Class) { if (Class === null || !_isNativeFunction(Class)) return Class; if (typeof Class !== \\\"function\\\") { throw new TypeError(\\\"Super expression must either be null or a function\\\"); } if (typeof _cache !== \\\"undefined\\\") { if (_cache.has(Class)) return _cache.get(Class); _cache.set(Class, Wrapper); } function Wrapper() { return _construct(Class, arguments, _getPrototypeOf(this).constructor); } Wrapper.prototype = Object.create(Class.prototype, { constructor: { value: Wrapper, enumerable: false, writable: true, configurable: true } }); return _setPrototypeOf(Wrapper, Class); }; return _wrapNativeSuper(Class); }\\n\\nfunction isNativeReflectConstruct() { if (typeof Reflect === \\\"undefined\\\" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === \\\"function\\\") return true; try { Date.prototype.toString.call(Reflect.construct(Date, [], function () {})); return true; } catch (e) { return false; } }\\n\\nfunction _construct(Parent, args, Class) { if (isNativeReflectConstruct()) { _construct = Reflect.construct; } else { _construct = function _construct(Parent, args, Class) { var a = [null]; a.push.apply(a, args); var Constructor = Function.bind.apply(Parent, a); var instance = new Constructor(); if (Class) _setPrototypeOf(instance, Class.prototype); return instance; }; } return _construct.apply(null, arguments); }\\n\\nfunction _isNativeFunction(fn) { return Function.toString.call(fn).indexOf(\\\"[native code]\\\") !== -1; }\\n\\nfunction _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); }\\n\\nfunction _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); }; return _getPrototypeOf(o); }\\n\\n// import processor name via preval.require so that it's available as a value at compile time\\nvar processorNames = {\\n \\\"recorderProcessor\\\": \\\"recorder-processor\\\",\\n \\\"soundFileProcessor\\\": \\\"sound-file-processor\\\",\\n \\\"amplitudeProcessor\\\": \\\"amplitude-processor\\\"\\n};\\n\\nvar SoundFileProcessor =\\n/*#__PURE__*/\\nfunction (_AudioWorkletProcesso) {\\n _inherits(SoundFileProcessor, _AudioWorkletProcesso);\\n\\n function SoundFileProcessor() {\\n var _this;\\n\\n _classCallCheck(this, SoundFileProcessor);\\n\\n _this = _possibleConstructorReturn(this, _getPrototypeOf(SoundFileProcessor).call(this));\\n _this.paused = false;\\n\\n _this.port.onmessage = function (event) {\\n var data = event.data;\\n\\n if (data.name === 'play') {\\n _this.paused = false;\\n } else if (data.name === 'pause') {\\n _this.paused = true;\\n }\\n };\\n\\n return _this;\\n }\\n\\n _createClass(SoundFileProcessor, [{\\n key: \\\"process\\\",\\n value: function process(inputs) {\\n var input = inputs[0];\\n var inputChannel = input[0];\\n var position = inputChannel[inputChannel.length - 1];\\n\\n if (!this.paused) {\\n this.port.postMessage({\\n name: 'position',\\n position: position\\n });\\n }\\n\\n return true;\\n }\\n }]);\\n\\n return SoundFileProcessor;\\n}(_wrapNativeSuper(AudioWorkletProcessor));\\n\\nregisterProcessor(processorNames.soundFileProcessor, SoundFileProcessor);\"","export default \"function _typeof(obj) { if (typeof Symbol === \\\"function\\\" && typeof Symbol.iterator === \\\"symbol\\\") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === \\\"function\\\" && obj.constructor === Symbol && obj !== Symbol.prototype ? \\\"symbol\\\" : typeof obj; }; } return _typeof(obj); }\\n\\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\\\"Cannot call a class as a function\\\"); } }\\n\\nfunction _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if (\\\"value\\\" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }\\n\\nfunction _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }\\n\\nfunction _possibleConstructorReturn(self, call) { if (call && (_typeof(call) === \\\"object\\\" || typeof call === \\\"function\\\")) { return call; } return _assertThisInitialized(self); }\\n\\nfunction _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError(\\\"this hasn't been initialised - super() hasn't been called\\\"); } return self; }\\n\\nfunction _inherits(subClass, superClass) { if (typeof superClass !== \\\"function\\\" && superClass !== null) { throw new TypeError(\\\"Super expression must either be null or a function\\\"); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, writable: true, configurable: true } }); if (superClass) _setPrototypeOf(subClass, superClass); }\\n\\nfunction _wrapNativeSuper(Class) { var _cache = typeof Map === \\\"function\\\" ? new Map() : undefined; _wrapNativeSuper = function _wrapNativeSuper(Class) { if (Class === null || !_isNativeFunction(Class)) return Class; if (typeof Class !== \\\"function\\\") { throw new TypeError(\\\"Super expression must either be null or a function\\\"); } if (typeof _cache !== \\\"undefined\\\") { if (_cache.has(Class)) return _cache.get(Class); _cache.set(Class, Wrapper); } function Wrapper() { return _construct(Class, arguments, _getPrototypeOf(this).constructor); } Wrapper.prototype = Object.create(Class.prototype, { constructor: { value: Wrapper, enumerable: false, writable: true, configurable: true } }); return _setPrototypeOf(Wrapper, Class); }; return _wrapNativeSuper(Class); }\\n\\nfunction isNativeReflectConstruct() { if (typeof Reflect === \\\"undefined\\\" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === \\\"function\\\") return true; try { Date.prototype.toString.call(Reflect.construct(Date, [], function () {})); return true; } catch (e) { return false; } }\\n\\nfunction _construct(Parent, args, Class) { if (isNativeReflectConstruct()) { _construct = Reflect.construct; } else { _construct = function _construct(Parent, args, Class) { var a = [null]; a.push.apply(a, args); var Constructor = Function.bind.apply(Parent, a); var instance = new Constructor(); if (Class) _setPrototypeOf(instance, Class.prototype); return instance; }; } return _construct.apply(null, arguments); }\\n\\nfunction _isNativeFunction(fn) { return Function.toString.call(fn).indexOf(\\\"[native code]\\\") !== -1; }\\n\\nfunction _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); }\\n\\nfunction _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); }; return _getPrototypeOf(o); }\\n\\n// import processor name via preval.require so that it's available as a value at compile time\\nvar processorNames = {\\n \\\"recorderProcessor\\\": \\\"recorder-processor\\\",\\n \\\"soundFileProcessor\\\": \\\"sound-file-processor\\\",\\n \\\"amplitudeProcessor\\\": \\\"amplitude-processor\\\"\\n};\\n\\nvar AmplitudeProcessor =\\n/*#__PURE__*/\\nfunction (_AudioWorkletProcesso) {\\n _inherits(AmplitudeProcessor, _AudioWorkletProcesso);\\n\\n function AmplitudeProcessor(options) {\\n var _this;\\n\\n _classCallCheck(this, AmplitudeProcessor);\\n\\n _this = _possibleConstructorReturn(this, _getPrototypeOf(AmplitudeProcessor).call(this));\\n var processorOptions = options.processorOptions || {};\\n _this.smoothing = processorOptions.smoothing || 0;\\n _this.normalize = processorOptions.normalize || false;\\n _this.stereoVol = [0, 0];\\n _this.stereoVolNorm = [0, 0];\\n _this.volMax = 0.001;\\n\\n _this.port.onmessage = function (event) {\\n var data = event.data;\\n\\n if (data.name === 'toggleNormalize') {\\n _this.normalize = data.normalize;\\n } else if (data.name === 'smoothing') {\\n _this.smoothing = Math.max(0, Math.min(1, data.smoothing));\\n }\\n };\\n\\n return _this;\\n } // TO DO make this stereo / dependent on # of audio channels\\n\\n\\n _createClass(AmplitudeProcessor, [{\\n key: \\\"process\\\",\\n value: function process(inputs, outputs) {\\n var input = inputs[0];\\n var output = outputs[0];\\n var smoothing = this.smoothing;\\n\\n for (var channel = 0; channel < input.length; ++channel) {\\n var inputBuffer = input[channel];\\n var bufLength = inputBuffer.length;\\n var sum = 0;\\n\\n for (var i = 0; i < bufLength; i++) {\\n var x = inputBuffer[i];\\n\\n if (this.normalize) {\\n sum += Math.max(Math.min(x / this.volMax, 1), -1) * Math.max(Math.min(x / this.volMax, 1), -1);\\n } else {\\n sum += x * x;\\n }\\n } // ... then take the square root of the sum.\\n\\n\\n var rms = Math.sqrt(sum / bufLength);\\n this.stereoVol[channel] = Math.max(rms, this.stereoVol[channel] * smoothing);\\n this.volMax = Math.max(this.stereoVol[channel], this.volMax);\\n } // calculate stero normalized volume and add volume from all channels together\\n\\n\\n var volSum = 0;\\n\\n for (var index = 0; index < this.stereoVol.length; index++) {\\n this.stereoVolNorm[index] = Math.max(Math.min(this.stereoVol[index] / this.volMax, 1), 0);\\n volSum += this.stereoVol[index];\\n } // volume is average of channels\\n\\n\\n var volume = volSum / this.stereoVol.length; // normalized value\\n\\n var volNorm = Math.max(Math.min(volume / this.volMax, 1), 0);\\n this.port.postMessage({\\n name: 'amplitude',\\n volume: volume,\\n volNorm: volNorm,\\n stereoVol: this.stereoVol,\\n stereoVolNorm: this.stereoVolNorm\\n }); // pass input through to output\\n\\n for (var _channel = 0; _channel < output.length; ++_channel) {\\n output[_channel].set(input[_channel]);\\n }\\n\\n return true;\\n }\\n }]);\\n\\n return AmplitudeProcessor;\\n}(_wrapNativeSuper(AudioWorkletProcessor));\\n\\nregisterProcessor(processorNames.amplitudeProcessor, AmplitudeProcessor);\"","'use strict';\n\ndefine(function (require) {\n\n var p5sound = require('master');\n var ac = p5sound.audiocontext;\n\n // Stereo panner\n // if there is a stereo panner node use it\n if(typeof ac.createStereoPanner !== 'undefined') {\n p5.Panner = function (input, output) {\n this.stereoPanner = this.input = ac.createStereoPanner();\n input.connect(this.stereoPanner);\n this.stereoPanner.connect(output);\n };\n\n p5.Panner.prototype.pan = function(val, tFromNow) {\n var time = tFromNow || 0;\n var t = ac.currentTime + time;\n\n this.stereoPanner.pan.linearRampToValueAtTime(val, t);\n };\n\n //not implemented because stereopanner\n //node does not require this and will automatically\n //convert single channel or multichannel to stereo.\n //tested with single and stereo, not with (>2) multichannel\n p5.Panner.prototype.inputChannels = function() {};\n\n p5.Panner.prototype.connect = function(obj) {\n this.stereoPanner.connect(obj);\n };\n\n p5.Panner.prototype.disconnect = function() {\n if (this.stereoPanner) {\n this.stereoPanner.disconnect();\n }\n };\n\n } else {\n // if there is no createStereoPanner object\n // such as in safari 7.1.7 at the time of writing this\n // use this method to create the effect\n p5.Panner = function(input, output, numInputChannels) {\n this.input = ac.createGain();\n input.connect(this.input);\n\n this.left = ac.createGain();\n this.right = ac.createGain();\n this.left.channelInterpretation = 'discrete';\n this.right.channelInterpretation = 'discrete';\n\n // if input is stereo\n if (numInputChannels > 1) {\n this.splitter = ac.createChannelSplitter(2);\n this.input.connect(this.splitter);\n\n this.splitter.connect(this.left, 1);\n this.splitter.connect(this.right, 0);\n }\n else {\n this.input.connect(this.left);\n this.input.connect(this.right);\n }\n\n this.output = ac.createChannelMerger(2);\n this.left.connect(this.output, 0, 1);\n this.right.connect(this.output, 0, 0);\n this.output.connect(output);\n };\n\n // -1 is left, +1 is right\n p5.Panner.prototype.pan = function(val, tFromNow) {\n var time = tFromNow || 0;\n var t = ac.currentTime + time;\n var v = (val + 1) / 2;\n var rightVal = Math.cos(v*Math.PI/2);\n var leftVal = Math.sin(v * Math.PI/2);\n this.left.gain.linearRampToValueAtTime(leftVal, t);\n this.right.gain.linearRampToValueAtTime(rightVal, t);\n };\n\n p5.Panner.prototype.inputChannels = function(numChannels) {\n if (numChannels === 1) {\n this.input.disconnect();\n this.input.connect(this.left);\n this.input.connect(this.right);\n } else if (numChannels === 2) {\n if (typeof(this.splitter === 'undefined')) {\n this.splitter = ac.createChannelSplitter(2);\n }\n this.input.disconnect();\n this.input.connect(this.splitter);\n this.splitter.connect(this.left, 1);\n this.splitter.connect(this.right, 0);\n }\n };\n\n p5.Panner.prototype.connect = function(obj) {\n this.output.connect(obj);\n };\n\n p5.Panner.prototype.disconnect = function() {\n if (this.output) {\n this.output.disconnect();\n }\n };\n }\n});\n","'use strict';\n\ndefine(function (require) {\n\n var CustomError = require('errorHandler');\n var p5sound = require('master');\n var ac = p5sound.audiocontext;\n var midiToFreq = require('helpers').midiToFreq;\n var convertToWav = require('helpers').convertToWav;\n var processorNames = require('./audioWorklet/processorNames');\n\n /**\n *
SoundFile object with a path to a file.
\n *\n *
The p5.SoundFile may not be available immediately because\n * it loads the file information asynchronously.
\n *\n *
To do something with the sound as soon as it loads\n * pass the name of a function as the second parameter.
\n *\n *
Only one file path is required. However, audio file formats\n * (i.e. mp3, ogg, wav and m4a/aac) are not supported by all\n * web browsers. If you want to ensure compatability, instead of a single\n * file path, you may include an Array of filepaths, and the browser will\n * choose a format that works.
\n *\n * @class p5.SoundFile\n * @constructor\n * @param {String|Array} path path to a sound file (String). Optionally,\n * you may include multiple file formats in\n * an array. Alternately, accepts an object\n * from the HTML5 File API, or a p5.File.\n * @param {Function} [successCallback] Name of a function to call once file loads\n * @param {Function} [errorCallback] Name of a function to call if file fails to\n * load. This function will receive an error or\n * XMLHttpRequest object with information\n * about what went wrong.\n * @param {Function} [whileLoadingCallback] Name of a function to call while file\n * is loading. That function will\n * receive progress of the request to\n * load the sound file\n * (between 0 and 1) as its first\n * parameter. This progress\n * does not account for the additional\n * time needed to decode the audio data.\n *\n * @example\n *
\n */\n p5.SoundFile = function(paths, onload, onerror, whileLoading) {\n if (typeof paths !== 'undefined') {\n if (typeof paths === 'string' || typeof paths[0] === 'string') {\n var path = p5.prototype._checkFileFormats(paths);\n this.url = path;\n }\n else if(typeof paths === 'object') {\n if (!(window.File && window.FileReader && window.FileList && window.Blob)) {\n // The File API isn't supported in this browser\n throw 'Unable to load file because the File API is not supported';\n }\n }\n\n // if type is a p5.File...get the actual file\n if (paths.file) {\n paths = paths.file;\n }\n\n this.file = paths;\n }\n\n // private _onended callback, set by the method: onended(callback)\n this._onended = function() {};\n\n this._looping = false;\n this._playing = false;\n this._paused = false;\n this._pauseTime = 0;\n\n // cues for scheduling events with addCue() removeCue()\n this._cues = [];\n this._cueIDCounter = 0;\n\n // position of the most recently played sample\n this._lastPos = 0;\n this._counterNode = null;\n this._workletNode = null;\n\n // array of sources so that they can all be stopped!\n this.bufferSourceNodes = [];\n\n // current source\n this.bufferSourceNode = null;\n\n this.buffer = null;\n this.playbackRate = 1;\n\n this.input = p5sound.audiocontext.createGain();\n this.output = p5sound.audiocontext.createGain();\n\n this.reversed = false;\n\n // start and end of playback / loop\n this.startTime = 0;\n this.endTime = null;\n this.pauseTime = 0;\n\n // \"restart\" would stop playback before retriggering\n this.mode = 'sustain';\n\n // time that playback was started, in millis\n this.startMillis = null;\n\n // stereo panning\n this.panPosition = 0.0;\n this.panner = new p5.Panner(this.output, p5sound.input, 2);\n\n // it is possible to instantiate a soundfile with no path\n if (this.url || this.file) {\n this.load(onload, onerror);\n }\n\n // add this p5.SoundFile to the soundArray\n p5sound.soundArray.push(this);\n\n if (typeof whileLoading === 'function') {\n this._whileLoading = whileLoading;\n } else {\n this._whileLoading = function() {};\n }\n\n this._clearOnEnd = _clearOnEnd.bind(this);\n };\n\n // register preload handling of loadSound\n p5.prototype.registerPreloadMethod('loadSound', p5.prototype);\n\n /**\n * loadSound() returns a new p5.SoundFile from a specified\n * path. If called during preload(), the p5.SoundFile will be ready\n * to play in time for setup() and draw(). If called outside of\n * preload, the p5.SoundFile will not be ready immediately, so\n * loadSound accepts a callback as the second parameter. Using a\n * \n * local server is recommended when loading external files.\n *\n * @method loadSound\n * @for p5\n * @param {String|Array} path Path to the sound file, or an array with\n * paths to soundfiles in multiple formats\n * i.e. ['sound.ogg', 'sound.mp3'].\n * Alternately, accepts an object: either\n * from the HTML5 File API, or a p5.File.\n * @param {Function} [successCallback] Name of a function to call once file loads\n * @param {Function} [errorCallback] Name of a function to call if there is\n * an error loading the file.\n * @param {Function} [whileLoading] Name of a function to call while file is loading.\n * This function will receive the percentage loaded\n * so far, from 0.0 to 1.0.\n * @return {SoundFile} Returns a p5.SoundFile\n * @example\n *
\n */\n p5.prototype.loadSound = function(path, callback, onerror, whileLoading) {\n // if loading locally without a server\n if (window.location.origin.indexOf('file://') > -1 && window.cordova === 'undefined' ) {\n window.alert('This sketch may require a server to load external files. Please see http://bit.ly/1qcInwS');\n }\n\n var self = this;\n var s = new p5.SoundFile(path, function() {\n if(typeof callback === 'function') {\n callback.apply(self, arguments);\n }\n\n if (typeof self._decrementPreload === 'function') {\n self._decrementPreload();\n }\n }, onerror, whileLoading);\n\n return s;\n };\n\n /**\n * This is a helper function that the p5.SoundFile calls to load\n * itself. Accepts a callback (the name of another function)\n * as an optional parameter.\n *\n * @private\n * @for p5.SoundFile\n * @param {Function} [successCallback] Name of a function to call once file loads\n * @param {Function} [errorCallback] Name of a function to call if there is an error\n */\n p5.SoundFile.prototype.load = function(callback, errorCallback) {\n var self = this;\n var errorTrace = new Error().stack;\n\n if (this.url !== undefined && this.url !== '') {\n var request = new XMLHttpRequest();\n request.addEventListener('progress', function(evt) {\n self._updateProgress(evt);\n }, false);\n request.open('GET', this.url, true);\n request.responseType = 'arraybuffer';\n\n request.onload = function() {\n if (request.status === 200) {\n // on sucess loading file:\n if (!self.panner) return;\n ac.decodeAudioData(request.response,\n // success decoding buffer:\n function(buff) {\n if (!self.panner) return;\n self.buffer = buff;\n self.panner.inputChannels(buff.numberOfChannels);\n if (callback) {\n callback(self);\n }\n },\n // error decoding buffer. \"e\" is undefined in Chrome 11/22/2015\n function() {\n if (!self.panner) return;\n var err = new CustomError('decodeAudioData', errorTrace, self.url);\n var msg = 'AudioContext error at decodeAudioData for ' + self.url;\n if (errorCallback) {\n err.msg = msg;\n errorCallback(err);\n } else {\n console.error(msg +'\\n The error stack trace includes: \\n' + err.stack);\n }\n }\n );\n }\n // if request status != 200, it failed\n else {\n if (!self.panner) return;\n var err = new CustomError('loadSound', errorTrace, self.url);\n var msg = 'Unable to load ' + self.url + '. The request status was: ' +\n request.status + ' (' + request.statusText + ')';\n\n if (errorCallback) {\n err.message = msg;\n errorCallback(err);\n } else {\n console.error(msg +'\\n The error stack trace includes: \\n' + err.stack);\n }\n }\n };\n\n // if there is another error, aside from 404...\n request.onerror = function() {\n var err = new CustomError('loadSound', errorTrace, self.url);\n var msg = 'There was no response from the server at ' + self.url + '. Check the url and internet connectivity.';\n\n if (errorCallback) {\n err.message = msg;\n errorCallback(err);\n } else {\n console.error(msg +'\\n The error stack trace includes: \\n' + err.stack);\n }\n };\n\n request.send();\n }\n else if (this.file !== undefined) {\n var reader = new FileReader();\n reader.onload = function() {\n if (!self.panner) return;\n ac.decodeAudioData(reader.result, function(buff) {\n if (!self.panner) return;\n self.buffer = buff;\n self.panner.inputChannels(buff.numberOfChannels);\n if (callback) {\n callback(self);\n }\n });\n };\n reader.onerror = function(e) {\n if (!self.panner) return;\n if (onerror) {\n onerror(e);\n }\n };\n reader.readAsArrayBuffer(this.file);\n }\n };\n\n // TO DO: use this method to create a loading bar that shows progress during file upload/decode.\n p5.SoundFile.prototype._updateProgress = function(evt) {\n if (evt.lengthComputable) {\n var percentComplete = evt.loaded / evt.total * 0.99;\n this._whileLoading(percentComplete, evt);\n // ...\n } else {\n // Unable to compute progress information since the total size is unknown\n this._whileLoading('size unknown');\n }\n };\n\n /**\n * Returns true if the sound file finished loading successfully.\n *\n * @method isLoaded\n * @for p5.SoundFile\n * @return {Boolean}\n */\n p5.SoundFile.prototype.isLoaded = function() {\n if (this.buffer) {\n return true;\n } else {\n return false;\n }\n };\n\n /**\n * Play the p5.SoundFile\n *\n * @method play\n * @for p5.SoundFile\n * @param {Number} [startTime] (optional) schedule playback to start (in seconds from now).\n * @param {Number} [rate] (optional) playback rate\n * @param {Number} [amp] (optional) amplitude (volume)\n * of playback\n * @param {Number} [cueStart] (optional) cue start time in seconds\n * @param {Number} [duration] (optional) duration of playback in seconds\n */\n p5.SoundFile.prototype.play = function(startTime, rate, amp, _cueStart, duration) {\n if (!this.output) {\n console.warn('SoundFile.play() called after dispose');\n return;\n }\n\n var now = p5sound.audiocontext.currentTime;\n var cueStart, cueEnd;\n var time = startTime || 0;\n if (time < 0) {\n time = 0;\n }\n\n time = time + now;\n\n if (typeof rate !== 'undefined') {\n this.rate(rate);\n }\n\n if (typeof amp !== 'undefined') {\n this.setVolume(amp);\n }\n\n // TO DO: if already playing, create array of buffers for easy stop()\n if (this.buffer) {\n\n // reset the pause time (if it was paused)\n this._pauseTime = 0;\n\n // handle restart playmode\n if (this.mode === 'restart' && this.buffer && this.bufferSourceNode) {\n this.bufferSourceNode.stop(time);\n this._counterNode.stop(time);\n }\n\n //dont create another instance if already playing\n if (this.mode === 'untildone' && this.isPlaying()) {\n return;\n }\n // make a new source and counter. They are automatically assigned playbackRate and buffer\n this.bufferSourceNode = this._initSourceNode();\n\n // garbage collect counterNode and create a new one\n delete this._counterNode;\n this._counterNode = this._initCounterNode();\n\n if (_cueStart) {\n if (_cueStart >=0 && _cueStart < this.buffer.duration) {\n // this.startTime = cueStart;\n cueStart = _cueStart;\n } else { throw 'start time out of range'; }\n } else {\n cueStart = 0;\n }\n\n if (duration) {\n // if duration is greater than buffer.duration, just play entire file anyway rather than throw an error\n duration = duration <= this.buffer.duration - cueStart ? duration : this.buffer.duration;\n }\n\n // if it was paused, play at the pause position\n if (this._paused) {\n this.bufferSourceNode.start(time, this.pauseTime, duration);\n this._counterNode.start(time, this.pauseTime, duration);\n } else {\n this.bufferSourceNode.start(time, cueStart, duration);\n this._counterNode.start(time, cueStart, duration);\n }\n\n this._playing = true;\n this._paused = false;\n\n // add source to sources array, which is used in stopAll()\n this.bufferSourceNodes.push(this.bufferSourceNode);\n this.bufferSourceNode._arrayIndex = this.bufferSourceNodes.length - 1;\n\n this.bufferSourceNode.addEventListener('ended', this._clearOnEnd);\n }\n // If soundFile hasn't loaded the buffer yet, throw an error\n else {\n throw 'not ready to play file, buffer has yet to load. Try preload()';\n }\n\n // if looping, will restart at original time\n this.bufferSourceNode.loop = this._looping;\n this._counterNode.loop = this._looping;\n\n if (this._looping === true) {\n cueEnd = duration ? duration : cueStart - 0.000000000000001;\n this.bufferSourceNode.loopStart = cueStart;\n this.bufferSourceNode.loopEnd = cueEnd;\n this._counterNode.loopStart = cueStart;\n this._counterNode.loopEnd = cueEnd;\n }\n\n this._workletNode.port.postMessage({ name: 'play' });\n };\n\n\n /**\n * p5.SoundFile has two play modes: restart and\n * sustain. Play Mode determines what happens to a\n * p5.SoundFile if it is triggered while in the middle of playback.\n * In sustain mode, playback will continue simultaneous to the\n * new playback. In restart mode, play() will stop playback\n * and start over. With untilDone, a sound will play only if it's\n * not already playing. Sustain is the default mode.\n *\n * @method playMode\n * @for p5.SoundFile\n * @param {String} str 'restart' or 'sustain' or 'untilDone'\n * @example\n *
\n * var mySound;\n * function preload(){\n * mySound = loadSound('assets/Damscray_DancingTiger.mp3');\n * }\n * function mouseClicked() {\n * mySound.playMode('sustain');\n * mySound.play();\n * }\n * function keyPressed() {\n * mySound.playMode('restart');\n * mySound.play();\n * }\n *\n *
\n */\n p5.SoundFile.prototype.playMode = function(str) {\n var s = str.toLowerCase();\n\n // if restart, stop all other sounds from playing\n if (s === 'restart' && this.buffer && this.bufferSourceNode) {\n for (var i = 0; i < this.bufferSourceNodes.length - 1; i++) {\n var now = p5sound.audiocontext.currentTime;\n this.bufferSourceNodes[i].stop(now);\n }\n }\n\n // set play mode to effect future playback\n if (s === 'restart' || s === 'sustain' || s === 'untildone') {\n this.mode = s;\n } else {\n throw 'Invalid play mode. Must be either \"restart\" or \"sustain\"';\n }\n };\n\n /**\n * Pauses a file that is currently playing. If the file is not\n * playing, then nothing will happen.\n *\n * After pausing, .play() will resume from the paused\n * position.\n * If p5.SoundFile had been set to loop before it was paused,\n * it will continue to loop after it is unpaused with .play().\n *\n * @method pause\n * @for p5.SoundFile\n * @param {Number} [startTime] (optional) schedule event to occur\n * seconds from now\n * @example\n *
\n */\n p5.SoundFile.prototype.pause = function(startTime) {\n var now = p5sound.audiocontext.currentTime;\n var time = startTime || 0;\n var pTime = time + now;\n\n if (this.isPlaying() && this.buffer && this.bufferSourceNode) {\n this._workletNode.port.postMessage({ name: 'pause' });\n\n this.pauseTime = this.currentTime();\n this.bufferSourceNode.stop(pTime);\n this._counterNode.stop(pTime);\n this._paused = true;\n this._playing = false;\n\n this._pauseTime = this.currentTime();\n // TO DO: make sure play() still starts from orig start position\n } else {\n this._pauseTime = 0;\n }\n };\n\n /**\n * Loop the p5.SoundFile. Accepts optional parameters to set the\n * playback rate, playback volume, loopStart, loopEnd.\n *\n * @method loop\n * @for p5.SoundFile\n * @param {Number} [startTime] (optional) schedule event to occur\n * seconds from now\n * @param {Number} [rate] (optional) playback rate\n * @param {Number} [amp] (optional) playback volume\n * @param {Number} [cueLoopStart] (optional) startTime in seconds\n * @param {Number} [duration] (optional) loop duration in seconds\n */\n p5.SoundFile.prototype.loop = function(startTime, rate, amp, loopStart, duration) {\n this._looping = true;\n this.play(startTime, rate, amp, loopStart, duration);\n };\n\n /**\n * Set a p5.SoundFile's looping flag to true or false. If the sound\n * is currently playing, this change will take effect when it\n * reaches the end of the current playback.\n *\n * @method setLoop\n * @for p5.SoundFile\n * @param {Boolean} Boolean set looping to true or false\n */\n p5.SoundFile.prototype.setLoop = function(bool) {\n if (bool === true) {\n this._looping = true;\n }\n else if (bool === false) {\n this._looping = false;\n }\n else {\n throw 'Error: setLoop accepts either true or false';\n }\n if (this.bufferSourceNode) {\n this.bufferSourceNode.loop = this._looping;\n this._counterNode.loop = this._looping;\n }\n };\n\n /**\n * Returns 'true' if a p5.SoundFile is currently looping and playing, 'false' if not.\n *\n * @method isLooping\n * @for p5.SoundFile\n * @return {Boolean}\n */\n p5.SoundFile.prototype.isLooping = function() {\n if (!this.bufferSourceNode) {\n return false;\n }\n if (this._looping === true && this.isPlaying() === true) {\n return true;\n }\n return false;\n };\n\n /**\n * Returns true if a p5.SoundFile is playing, false if not (i.e.\n * paused or stopped).\n *\n * @method isPlaying\n * @for p5.SoundFile\n * @return {Boolean}\n */\n p5.SoundFile.prototype.isPlaying = function() {\n return this._playing;\n };\n\n /**\n * Returns true if a p5.SoundFile is paused, false if not (i.e.\n * playing or stopped).\n *\n * @method isPaused\n * @for p5.SoundFile\n * @return {Boolean}\n */\n p5.SoundFile.prototype.isPaused = function() {\n return this._paused;\n };\n\n /**\n * Stop soundfile playback.\n *\n * @method stop\n * @for p5.SoundFile\n * @param {Number} [startTime] (optional) schedule event to occur\n * in seconds from now\n */\n p5.SoundFile.prototype.stop = function(timeFromNow) {\n var time = timeFromNow || 0;\n\n if (this.mode === 'sustain' || this.mode === 'untildone') {\n this.stopAll(time);\n this._playing = false;\n this.pauseTime = 0;\n this._paused = false;\n }\n else if (this.buffer && this.bufferSourceNode) {\n var now = p5sound.audiocontext.currentTime;\n var t = time || 0;\n this.pauseTime = 0;\n this.bufferSourceNode.stop(now + t);\n this._counterNode.stop(now + t);\n this._playing = false;\n this._paused = false;\n }\n };\n\n /**\n * Stop playback on all of this soundfile's sources.\n * @private\n */\n p5.SoundFile.prototype.stopAll = function(_time) {\n var now = p5sound.audiocontext.currentTime;\n var time = _time || 0;\n if (this.buffer && this.bufferSourceNode) {\n for (var i in this.bufferSourceNodes) {\n const bufferSourceNode = this.bufferSourceNodes[i];\n if (!!bufferSourceNode) {\n try {\n bufferSourceNode.stop(now + time);\n } catch(e) {\n // this was throwing errors only on Safari\n }\n }\n }\n this._counterNode.stop(now + time);\n this._onended(this);\n }\n };\n\n /**\n * Multiply the output volume (amplitude) of a sound file\n * between 0.0 (silence) and 1.0 (full volume).\n * 1.0 is the maximum amplitude of a digital sound, so multiplying\n * by greater than 1.0 may cause digital distortion. To\n * fade, provide a rampTime parameter. For more\n * complex fades, see the Envelope class.\n *\n * Alternately, you can pass in a signal source such as an\n * oscillator to modulate the amplitude with an audio signal.\n *\n * @method setVolume\n * @for p5.SoundFile\n * @param {Number|Object} volume Volume (amplitude) between 0.0\n * and 1.0 or modulating signal/oscillator\n * @param {Number} [rampTime] Fade for t seconds\n * @param {Number} [timeFromNow] Schedule this event to happen at\n * t seconds in the future\n */\n p5.SoundFile.prototype.setVolume = function(vol, _rampTime, _tFromNow) {\n if (typeof vol === 'number') {\n var rampTime = _rampTime || 0;\n var tFromNow = _tFromNow || 0;\n var now = p5sound.audiocontext.currentTime;\n var currentVol = this.output.gain.value;\n this.output.gain.cancelScheduledValues(now + tFromNow);\n this.output.gain.linearRampToValueAtTime(currentVol, now + tFromNow);\n this.output.gain.linearRampToValueAtTime(vol, now + tFromNow + rampTime);\n }\n else if (vol) {\n vol.connect(this.output.gain);\n } else {\n // return the Gain Node\n return this.output.gain;\n }\n };\n\n // same as setVolume, to match Processing Sound\n p5.SoundFile.prototype.amp = p5.SoundFile.prototype.setVolume;\n\n // these are the same thing\n p5.SoundFile.prototype.fade = p5.SoundFile.prototype.setVolume;\n\n p5.SoundFile.prototype.getVolume = function() {\n return this.output.gain.value;\n };\n\n /**\n * Set the stereo panning of a p5.sound object to\n * a floating point number between -1.0 (left) and 1.0 (right).\n * Default is 0.0 (center).\n *\n * @method pan\n * @for p5.SoundFile\n * @param {Number} [panValue] Set the stereo panner\n * @param {Number} [timeFromNow] schedule this event to happen\n * seconds from now\n * @example\n *
\n *\n * var ball = {};\n * var soundFile;\n *\n * function preload() {\n * soundFormats('ogg', 'mp3');\n * soundFile = loadSound('assets/beatbox.mp3');\n * }\n *\n * function draw() {\n * background(0);\n * ball.x = constrain(mouseX, 0, width);\n * ellipse(ball.x, height/2, 20, 20)\n * }\n *\n * function mousePressed(){\n * // map the ball's x location to a panning degree\n * // between -1.0 (left) and 1.0 (right)\n * var panning = map(ball.x, 0., width,-1.0, 1.0);\n * soundFile.pan(panning);\n * soundFile.play();\n * }\n *
\n */\n p5.SoundFile.prototype.pan = function(pval, tFromNow) {\n this.panPosition = pval;\n this.panner.pan(pval, tFromNow);\n };\n\n /**\n * Returns the current stereo pan position (-1.0 to 1.0)\n *\n * @method getPan\n * @for p5.SoundFile\n * @return {Number} Returns the stereo pan setting of the Oscillator\n * as a number between -1.0 (left) and 1.0 (right).\n * 0.0 is center and default.\n */\n p5.SoundFile.prototype.getPan = function() {\n return this.panPosition;\n };\n\n /**\n * Set the playback rate of a sound file. Will change the speed and the pitch.\n * Values less than zero will reverse the audio buffer.\n *\n * @method rate\n * @for p5.SoundFile\n * @param {Number} [playbackRate] Set the playback rate. 1.0 is normal,\n * .5 is half-speed, 2.0 is twice as fast.\n * Values less than zero play backwards.\n * @example\n *
\n * var song;\n *\n * function preload() {\n * song = loadSound('assets/Damscray_DancingTiger.mp3');\n * }\n *\n * function setup() {\n * song.loop();\n * }\n *\n * function draw() {\n * background(200);\n *\n * // Set the rate to a range between 0.1 and 4\n * // Changing the rate also alters the pitch\n * var speed = map(mouseY, 0.1, height, 0, 2);\n * speed = constrain(speed, 0.01, 4);\n * song.rate(speed);\n *\n * // Draw a circle to show what is going on\n * stroke(0);\n * fill(51, 100);\n * ellipse(mouseX, 100, 48, 48);\n * }\n *\n * \n *
\n *\n */\n p5.SoundFile.prototype.rate = function(playbackRate) {\n var reverse = false;\n if (typeof playbackRate === 'undefined') {\n return this.playbackRate;\n }\n\n this.playbackRate = playbackRate;\n\n if (playbackRate === 0) {\n playbackRate = 0.0000000000001;\n }\n\n else if (playbackRate < 0 && !this.reversed) {\n playbackRate = Math.abs(playbackRate);\n reverse = true;\n }\n\n else if (playbackRate > 0 && this.reversed) {\n reverse = true;\n }\n\n if (this.bufferSourceNode) {\n var now = p5sound.audiocontext.currentTime;\n this.bufferSourceNode.playbackRate.cancelScheduledValues(now);\n this.bufferSourceNode.playbackRate.linearRampToValueAtTime(Math.abs(playbackRate), now);\n this._counterNode.playbackRate.cancelScheduledValues(now);\n this._counterNode.playbackRate.linearRampToValueAtTime(Math.abs(playbackRate), now);\n }\n\n if (reverse) {\n this.reverseBuffer();\n }\n return this.playbackRate;\n };\n\n // TO DO: document this\n p5.SoundFile.prototype.setPitch = function(num) {\n var newPlaybackRate = midiToFreq(num) / midiToFreq(60);\n this.rate(newPlaybackRate);\n };\n\n p5.SoundFile.prototype.getPlaybackRate = function() {\n return this.playbackRate;\n };\n\n /**\n * Returns the duration of a sound file in seconds.\n *\n * @method duration\n * @for p5.SoundFile\n * @return {Number} The duration of the soundFile in seconds.\n */\n p5.SoundFile.prototype.duration = function() {\n // Return Duration\n if (this.buffer) {\n return this.buffer.duration;\n } else {\n return 0;\n }\n };\n\n /**\n * Return the current position of the p5.SoundFile playhead, in seconds.\n * Time is relative to the normal buffer direction, so if `reverseBuffer`\n * has been called, currentTime will count backwards.\n *\n * @method currentTime\n * @for p5.SoundFile\n * @return {Number} currentTime of the soundFile in seconds.\n */\n p5.SoundFile.prototype.currentTime = function() {\n return this.reversed\n ? Math.abs(this._lastPos - this.buffer.length) / ac.sampleRate\n : this._lastPos / ac.sampleRate;\n };\n\n /**\n * Move the playhead of the song to a position, in seconds. Start timing\n * and playback duration. If none are given, will reset the file to play\n * entire duration from start to finish.\n *\n * @method jump\n * @for p5.SoundFile\n * @param {Number} cueTime cueTime of the soundFile in seconds.\n * @param {Number} duration duration in seconds.\n */\n p5.SoundFile.prototype.jump = function(cueTime, duration) {\n if (cueTime < 0 || cueTime > this.buffer.duration) {\n throw 'jump time out of range';\n }\n if (duration > this.buffer.duration - cueTime) {\n throw 'end time out of range';\n }\n\n var cTime = cueTime || 0;\n var dur = duration || undefined;\n if (this.isPlaying()) {\n this.stop(0);\n }\n this.play(0, this.playbackRate, this.output.gain.value, cTime, dur);\n };\n\n /**\n * Return the number of channels in a sound file.\n * For example, Mono = 1, Stereo = 2.\n *\n * @method channels\n * @for p5.SoundFile\n * @return {Number} [channels]\n */\n p5.SoundFile.prototype.channels = function() {\n return this.buffer.numberOfChannels;\n };\n\n /**\n * Return the sample rate of the sound file.\n *\n * @method sampleRate\n * @for p5.SoundFile\n * @return {Number} [sampleRate]\n */\n p5.SoundFile.prototype.sampleRate = function() {\n return this.buffer.sampleRate;\n };\n\n /**\n * Return the number of samples in a sound file.\n * Equal to sampleRate * duration.\n *\n * @method frames\n * @for p5.SoundFile\n * @return {Number} [sampleCount]\n */\n p5.SoundFile.prototype.frames = function() {\n return this.buffer.length;\n };\n\n /**\n * Returns an array of amplitude peaks in a p5.SoundFile that can be\n * used to draw a static waveform. Scans through the p5.SoundFile's\n * audio buffer to find the greatest amplitudes. Accepts one\n * parameter, 'length', which determines size of the array.\n * Larger arrays result in more precise waveform visualizations.\n *\n * Inspired by Wavesurfer.js.\n *\n * @method getPeaks\n * @for p5.SoundFile\n * @params {Number} [length] length is the size of the returned array.\n * Larger length results in more precision.\n * Defaults to 5*width of the browser window.\n * @returns {Float32Array} Array of peaks.\n */\n p5.SoundFile.prototype.getPeaks = function(length) {\n\n if (this.buffer) {\n // set length to window's width if no length is provided\n if (!length) {\n length = window.width*5;\n }\n if (this.buffer) {\n var buffer = this.buffer;\n var sampleSize = buffer.length / length;\n var sampleStep = ~~(sampleSize / 10) || 1;\n var channels = buffer.numberOfChannels;\n var peaks = new Float32Array(Math.round(length));\n\n for (var c = 0; c < channels; c++) {\n var chan = buffer.getChannelData(c);\n for (var i = 0; i < length; i++) {\n var start = ~~(i*sampleSize);\n var end = ~~(start + sampleSize);\n var max = 0;\n for (var j = start; j < end; j+= sampleStep) {\n var value = chan[j];\n if (value > max) {\n max = value;\n // faster than Math.abs\n } else if (-value > max) {\n max = value;\n }\n }\n if (c === 0 || Math.abs(max) > peaks[i]) {\n peaks[i] = max;\n }\n }\n }\n\n return peaks;\n }\n }\n\n else {\n throw 'Cannot load peaks yet, buffer is not loaded';\n }\n };\n\n /**\n * Reverses the p5.SoundFile's buffer source.\n * Playback must be handled separately (see example).\n *\n * @method reverseBuffer\n * @for p5.SoundFile\n * @example\n *
\n * var drum;\n *\n * function preload() {\n * drum = loadSound('assets/drum.mp3');\n * }\n *\n * function setup() {\n * drum.reverseBuffer();\n * drum.play();\n * }\n *\n * \n *
\n */\n p5.SoundFile.prototype.reverseBuffer = function() {\n if (this.buffer) {\n var currentPos = this._lastPos / ac.sampleRate;\n var curVol = this.getVolume();\n this.setVolume(0, 0.001);\n\n const numChannels = this.buffer.numberOfChannels;\n for (var i = 0; i < numChannels; i++) {\n this.buffer.getChannelData(i).reverse();\n }\n // set reversed flag\n this.reversed = !this.reversed;\n\n if (currentPos) {\n this.jump(this.duration() - currentPos);\n }\n this.setVolume(curVol, 0.001);\n } else {\n throw 'SoundFile is not done loading';\n }\n };\n\n /**\n * Schedule an event to be called when the soundfile\n * reaches the end of a buffer. If the soundfile is\n * playing through once, this will be called when it\n * ends. If it is looping, it will be called when\n * stop is called.\n *\n * @method onended\n * @for p5.SoundFile\n * @param {Function} callback function to call when the\n * soundfile has ended.\n */\n p5.SoundFile.prototype.onended = function(callback) {\n this._onended = callback;\n return this;\n };\n\n p5.SoundFile.prototype.add = function() {\n // TO DO\n };\n\n p5.SoundFile.prototype.dispose = function() {\n var now = p5sound.audiocontext.currentTime;\n\n // remove reference to soundfile\n var index = p5sound.soundArray.indexOf(this);\n p5sound.soundArray.splice(index, 1);\n\n this.stop(now);\n if (this.buffer && this.bufferSourceNode) {\n for (var i = 0; i < this.bufferSourceNodes.length - 1; i++) {\n if (this.bufferSourceNodes[i] !== null) {\n this.bufferSourceNodes[i].disconnect();\n try {\n this.bufferSourceNodes[i].stop(now);\n } catch(e) {\n console.warning('no buffer source node to dispose');\n }\n this.bufferSourceNodes[i] = null;\n }\n }\n if ( this.isPlaying() ) {\n try {\n this._counterNode.stop(now);\n } catch(e) {\n console.log(e);\n }\n this._counterNode = null;\n }\n }\n if (this.output) {\n this.output.disconnect();\n this.output = null;\n }\n if (this.panner) {\n this.panner.disconnect();\n this.panner = null;\n }\n };\n\n /**\n * Connects the output of a p5sound object to input of another\n * p5.sound object. For example, you may connect a p5.SoundFile to an\n * FFT or an Effect. If no parameter is given, it will connect to\n * the master output. Most p5sound objects connect to the master\n * output when they are created.\n *\n * @method connect\n * @for p5.SoundFile\n * @param {Object} [object] Audio object that accepts an input\n */\n p5.SoundFile.prototype.connect = function(unit) {\n if (!unit) {\n this.panner.connect(p5sound.input);\n }\n else {\n if (unit.hasOwnProperty('input')) {\n this.panner.connect(unit.input);\n } else {\n this.panner.connect(unit);\n }\n }\n };\n\n /**\n * Disconnects the output of this p5sound object.\n *\n * @method disconnect\n * @for p5.SoundFile\n */\n p5.SoundFile.prototype.disconnect = function() {\n if (this.panner) {\n this.panner.disconnect();\n }\n };\n\n /**\n */\n p5.SoundFile.prototype.getLevel = function() {\n console.warn('p5.SoundFile.getLevel has been removed from the library. Use p5.Amplitude instead');\n };\n\n /**\n * Reset the source for this SoundFile to a\n * new path (URL).\n *\n * @method setPath\n * @for p5.SoundFile\n * @param {String} path path to audio file\n * @param {Function} callback Callback\n */\n p5.SoundFile.prototype.setPath = function(p, callback) {\n var path = p5.prototype._checkFileFormats(p);\n this.url = path;\n this.load(callback);\n };\n\n /**\n * Replace the current Audio Buffer with a new Buffer.\n *\n * @method setBuffer\n * @for p5.SoundFile\n * @param {Array} buf Array of Float32 Array(s). 2 Float32 Arrays\n * will create a stereo source. 1 will create\n * a mono source.\n */\n p5.SoundFile.prototype.setBuffer = function(buf) {\n var numChannels = buf.length;\n var size = buf[0].length;\n var newBuffer = ac.createBuffer(numChannels, size, ac.sampleRate);\n\n if (!(buf[0] instanceof Float32Array)) {\n buf[0] = new Float32Array(buf[0]);\n }\n\n for (var channelNum = 0; channelNum < numChannels; channelNum++) {\n var channel = newBuffer.getChannelData( channelNum );\n channel.set(buf[channelNum]);\n }\n\n this.buffer = newBuffer;\n\n // set numbers of channels on input to the panner\n this.panner.inputChannels(numChannels);\n };\n\n //////////////////////////////////////////////////\n // script processor node with an empty buffer to help\n // keep a sample-accurate position in playback buffer.\n // Inspired by Chinmay Pendharkar's technique for Sonoport --> http://bit.ly/1HwdCsV\n // Copyright [2015] [Sonoport (Asia) Pte. Ltd.],\n // Licensed under the Apache License http://apache.org/licenses/LICENSE-2.0\n ////////////////////////////////////////////////////////////////////////////////////\n\n var _createCounterBuffer = function(buffer) {\n const len = buffer.length;\n const audioBuf = ac.createBuffer( 1, buffer.length, ac.sampleRate );\n const arrayBuffer = audioBuf.getChannelData(0);\n for (var index = 0; index < len; index++) {\n arrayBuffer[index] = index;\n }\n return audioBuf;\n };\n\n // initialize counterNode, set its initial buffer and playbackRate\n p5.SoundFile.prototype._initCounterNode = function() {\n var self = this;\n var now = ac.currentTime;\n var cNode = ac.createBufferSource();\n\n // dispose of worklet node if it already exists\n if (self._workletNode) {\n self._workletNode.disconnect();\n delete self._workletNode;\n }\n self._workletNode = new AudioWorkletNode(ac, processorNames.soundFileProcessor);\n self._workletNode.port.onmessage = function(event) {\n if (event.data.name === 'position') {\n this._lastPos = event.data.position;\n\n // do any callbacks that have been scheduled\n this._onTimeUpdate(self._lastPos);\n }\n }.bind(self);\n\n // create counter buffer of the same length as self.buffer\n cNode.buffer = _createCounterBuffer( self.buffer );\n\n cNode.playbackRate.setValueAtTime(self.playbackRate, now);\n\n cNode.connect(self._workletNode);\n self._workletNode.connect(p5.soundOut._silentNode);\n\n return cNode;\n };\n\n // initialize sourceNode, set its initial buffer and playbackRate\n p5.SoundFile.prototype._initSourceNode = function() {\n var bufferSourceNode = ac.createBufferSource();\n bufferSourceNode.buffer = this.buffer;\n bufferSourceNode.playbackRate.value = this.playbackRate;\n bufferSourceNode.connect(this.output);\n return bufferSourceNode;\n };\n\n /**\n * processPeaks returns an array of timestamps where it thinks there is a beat.\n *\n * This is an asynchronous function that processes the soundfile in an offline audio context,\n * and sends the results to your callback function.\n *\n * The process involves running the soundfile through a lowpass filter, and finding all of the\n * peaks above the initial threshold. If the total number of peaks are below the minimum number of peaks,\n * it decreases the threshold and re-runs the analysis until either minPeaks or minThreshold are reached.\n *\n * @method processPeaks\n * @for p5.SoundFile\n * @param {Function} callback a function to call once this data is returned\n * @param {Number} [initThreshold] initial threshold defaults to 0.9\n * @param {Number} [minThreshold] minimum threshold defaults to 0.22\n * @param {Number} [minPeaks] minimum number of peaks defaults to 200\n * @return {Array} Array of timestamped peaks\n */\n p5.SoundFile.prototype.processPeaks = function(callback, _initThreshold, _minThreshold, _minPeaks) {\n var bufLen = this.buffer.length;\n var sampleRate = this.buffer.sampleRate;\n var buffer = this.buffer;\n var allPeaks = [];\n\n var initialThreshold = _initThreshold || 0.9,\n threshold = initialThreshold,\n minThreshold = _minThreshold || 0.22,\n minPeaks = _minPeaks || 200;\n\n // Create offline context\n var offlineContext = new window.OfflineAudioContext(1, bufLen, sampleRate);\n\n // create buffer source\n var source = offlineContext.createBufferSource();\n source.buffer = buffer;\n\n // Create filter. TO DO: allow custom setting of filter\n var filter = offlineContext.createBiquadFilter();\n filter.type = 'lowpass';\n source.connect(filter);\n filter.connect(offlineContext.destination);\n\n // start playing at time:0\n source.start(0);\n offlineContext.startRendering(); // Render the song\n\n // act on the result\n offlineContext.oncomplete = function(e) {\n if (!self.panner) return;\n var filteredBuffer = e.renderedBuffer;\n var bufferData = filteredBuffer.getChannelData(0);\n\n\n // step 1:\n // create Peak instances, add them to array, with strength and sampleIndex\n do {\n allPeaks = getPeaksAtThreshold(bufferData, threshold);\n threshold -= 0.005;\n } while (Object.keys(allPeaks).length < minPeaks && threshold >= minThreshold);\n\n\n // step 2:\n // find intervals for each peak in the sampleIndex, add tempos array\n var intervalCounts = countIntervalsBetweenNearbyPeaks(allPeaks);\n\n // step 3: find top tempos\n var groups = groupNeighborsByTempo(intervalCounts, filteredBuffer.sampleRate);\n\n // sort top intervals\n var topTempos = groups.sort(function(intA, intB) {\n return intB.count - intA.count;\n\n }).splice(0,5);\n\n // set this SoundFile's tempo to the top tempo ??\n this.tempo = topTempos[0].tempo;\n\n // step 4:\n // new array of peaks at top tempo within a bpmVariance\n var bpmVariance = 5;\n var tempoPeaks = getPeaksAtTopTempo(allPeaks, topTempos[0].tempo, filteredBuffer.sampleRate, bpmVariance);\n\n callback(tempoPeaks);\n };\n };\n\n // process peaks\n var Peak = function(amp, i) {\n this.sampleIndex = i;\n this.amplitude = amp;\n this.tempos = [];\n this.intervals = [];\n };\n\n // 1. for processPeaks() Function to identify peaks above a threshold\n // returns an array of peak indexes as frames (samples) of the original soundfile\n function getPeaksAtThreshold(data, threshold) {\n var peaksObj = {};\n var length = data.length;\n\n for (var i = 0; i < length; i++) {\n if (data[i] > threshold) {\n var amp = data[i];\n var peak = new Peak(amp, i);\n peaksObj[i] = peak;\n // Skip forward ~ 1/8s to get past this peak.\n i += 6000;\n }\n i++;\n }\n return peaksObj;\n }\n\n // 2. for processPeaks()\n function countIntervalsBetweenNearbyPeaks(peaksObj) {\n var intervalCounts = [];\n var peaksArray = Object.keys(peaksObj).sort();\n\n for (var index = 0; index < peaksArray.length; index++) {\n\n // find intervals in comparison to nearby peaks\n for (var i = 0; i < 10; i++) {\n var startPeak = peaksObj[peaksArray[index]];\n var endPeak = peaksObj[peaksArray[index + i]];\n\n if (startPeak && endPeak) {\n var startPos = startPeak.sampleIndex;\n var endPos = endPeak.sampleIndex;\n var interval = endPos - startPos;\n\n // add a sample interval to the startPeak in the allPeaks array\n if (interval > 0) {\n startPeak.intervals.push(interval);\n }\n\n // tally the intervals and return interval counts\n var foundInterval = intervalCounts.some(function(intervalCount) {\n if (intervalCount.interval === interval) {\n intervalCount.count++;\n return intervalCount;\n }\n });\n\n // store with JSON like formatting\n if (!foundInterval) {\n intervalCounts.push({\n interval: interval,\n count: 1,\n });\n }\n }\n }\n }\n\n return intervalCounts;\n }\n\n\n // 3. for processPeaks --> find tempo\n function groupNeighborsByTempo(intervalCounts, sampleRate) {\n var tempoCounts = [];\n\n intervalCounts.forEach(function(intervalCount) {\n\n try {\n // Convert an interval to tempo\n var theoreticalTempo = Math.abs( 60 / (intervalCount.interval / sampleRate ) );\n\n theoreticalTempo = mapTempo(theoreticalTempo);\n\n var foundTempo = tempoCounts.some(function(tempoCount) {\n if (tempoCount.tempo === theoreticalTempo)\n return tempoCount.count += intervalCount.count;\n });\n if (!foundTempo) {\n if (isNaN(theoreticalTempo)) {\n return;\n }\n tempoCounts.push({\n tempo: Math.round(theoreticalTempo),\n count: intervalCount.count\n });\n }\n } catch(e) {\n throw e;\n }\n\n });\n\n return tempoCounts;\n }\n\n // 4. for processPeaks - get peaks at top tempo\n function getPeaksAtTopTempo(peaksObj, tempo, sampleRate, bpmVariance) {\n var peaksAtTopTempo = [];\n var peaksArray = Object.keys(peaksObj).sort();\n\n // TO DO: filter out peaks that have the tempo and return\n for (var i = 0; i < peaksArray.length; i++) {\n var key = peaksArray[i];\n var peak = peaksObj[key];\n\n for (var j = 0; j < peak.intervals.length; j++) {\n var intervalBPM = Math.round(Math.abs( 60 / (peak.intervals[j] / sampleRate) ) );\n\n intervalBPM = mapTempo(intervalBPM);\n\n if ( Math.abs(intervalBPM - tempo) < bpmVariance ) {\n // convert sampleIndex to seconds\n peaksAtTopTempo.push(peak.sampleIndex/sampleRate);\n }\n }\n }\n\n // filter out peaks that are very close to each other\n peaksAtTopTempo = peaksAtTopTempo.filter(function(peakTime, index, arr) {\n var dif = arr[index + 1] - peakTime;\n if (dif > 0.01) {\n return true;\n }\n });\n\n return peaksAtTopTempo;\n }\n\n // helper function for processPeaks\n function mapTempo(theoreticalTempo) {\n // these scenarios create infinite while loop\n if (!isFinite(theoreticalTempo) || theoreticalTempo === 0 ) {\n return;\n }\n\n // Adjust the tempo to fit within the 90-180 BPM range\n while (theoreticalTempo < 90) theoreticalTempo *= 2;\n while (theoreticalTempo > 180 && theoreticalTempo > 90) theoreticalTempo /= 2;\n\n return theoreticalTempo;\n }\n\n\n /*** SCHEDULE EVENTS ***/\n\n // Cue inspired by JavaScript setTimeout, and the\n // Tone.js Transport Timeline Event, MIT License Yotam Mann 2015 tonejs.org\n var Cue = function(callback, time, id, val) {\n this.callback = callback;\n this.time = time;\n this.id = id;\n this.val = val;\n };\n\n /**\n * Schedule events to trigger every time a MediaElement\n * (audio/video) reaches a playback cue point.\n *\n * Accepts a callback function, a time (in seconds) at which to trigger\n * the callback, and an optional parameter for the callback.\n *\n * Time will be passed as the first parameter to the callback function,\n * and param will be the second parameter.\n *\n *\n * @method addCue\n * @for p5.SoundFile\n * @param {Number} time Time in seconds, relative to this media\n * element's playback. For example, to trigger\n * an event every time playback reaches two\n * seconds, pass in the number 2. This will be\n * passed as the first parameter to\n * the callback function.\n * @param {Function} callback Name of a function that will be\n * called at the given time. The callback will\n * receive time and (optionally) param as its\n * two parameters.\n * @param {Object} [value] An object to be passed as the\n * second parameter to the\n * callback function.\n * @return {Number} id ID of this cue,\n * useful for removeCue(id)\n * @example\n *
\n */\n p5.SoundFile.prototype.addCue = function(time, callback, val) {\n var id = this._cueIDCounter++;\n\n var cue = new Cue(callback, time, id, val);\n this._cues.push(cue);\n\n // if (!this.elt.ontimeupdate) {\n // this.elt.ontimeupdate = this._onTimeUpdate.bind(this);\n // }\n\n return id;\n };\n\n /**\n * Remove a callback based on its ID. The ID is returned by the\n * addCue method.\n *\n * @method removeCue\n * @for p5.SoundFile\n * @param {Number} id ID of the cue, as returned by addCue\n */\n p5.SoundFile.prototype.removeCue = function(id) {\n var cueLength = this._cues.length;\n for (var i = 0; i < cueLength; i++) {\n var cue = this._cues[i];\n if (cue.id === id) {\n this._cues.splice(i, 1);\n break;\n }\n }\n\n if (this._cues.length === 0) {\n // TO DO: remove callback\n // this.elt.ontimeupdate = null\n }\n };\n\n /**\n * Remove all of the callbacks that had originally been scheduled\n * via the addCue method.\n *\n * @method clearCues\n */\n p5.SoundFile.prototype.clearCues = function() {\n this._cues = [];\n // this.elt.ontimeupdate = null;\n };\n\n // private method that checks for cues to be fired if events\n // have been scheduled using addCue(callback, time).\n p5.SoundFile.prototype._onTimeUpdate = function(position) {\n var playbackTime = position/this.buffer.sampleRate;\n var cueLength = this._cues.length;\n\n for (var i = 0 ; i < cueLength; i++) {\n var cue = this._cues[i];\n var callbackTime = cue.time;\n var val = cue.val;\n\n if (this._prevTime < callbackTime && callbackTime <= playbackTime) {\n\n // pass the scheduled callbackTime as parameter to the callback\n cue.callback(val);\n }\n\n }\n\n this._prevTime = playbackTime;\n };\n\n /**\n * Save a p5.SoundFile as a .wav file. The browser will prompt the user\n * to download the file to their device. To upload a file to a server, see\n * getBlob\n *\n * @method save\n * @for p5.SoundFile\n * @param {String} [fileName] name of the resulting .wav file.\n * @example\n *
\n * var inp, button, mySound;\n * var fileName = 'cool';\n * function preload() {\n * mySound = loadSound('assets/doorbell.mp3');\n * }\n * function setup() {\n * btn = createButton('click to save file');\n * btn.position(0, 0);\n * btn.mouseClicked(handleMouseClick);\n * }\n *\n * function handleMouseClick() {\n * mySound.save(fileName);\n * }\n *
\n */\n p5.SoundFile.prototype.save = function(fileName) {\n const dataView = convertToWav(this.buffer);\n p5.prototype.saveSound([dataView], fileName, 'wav');\n };\n\n /**\n * This method is useful for sending a SoundFile to a server. It returns the\n * .wav-encoded audio data as a \"Blob\".\n * A Blob is a file-like data object that can be uploaded to a server\n * with an http request. We'll\n * use the `httpDo` options object to send a POST request with some\n * specific options: we encode the request as `multipart/form-data`,\n * and attach the blob as one of the form values using `FormData`.\n *\n *\n * @method getBlob\n * @for p5.SoundFile\n * @returns {Blob} A file-like data object\n * @example\n *
\n *\n * function preload() {\n * mySound = loadSound('assets/doorbell.mp3');\n * }\n *\n * function setup() {\n * noCanvas();\n * var soundBlob = mySound.getBlob();\n *\n * // Now we can send the blob to a server...\n * var serverUrl = 'https://jsonplaceholder.typicode.com/posts';\n * var httpRequestOptions = {\n * method: 'POST',\n * body: new FormData().append('soundBlob', soundBlob),\n * headers: new Headers({\n * 'Content-Type': 'multipart/form-data'\n * })\n * };\n * httpDo(serverUrl, httpRequestOptions);\n *\n * // We can also create an `ObjectURL` pointing to the Blob\n * var blobUrl = URL.createObjectURL(soundBlob);\n *\n * // The `
\n */\n p5.SoundFile.prototype.getBlob = function() {\n const dataView = convertToWav(this.buffer);\n return new Blob([dataView], { type: 'audio/wav' });\n };\n\n // event handler to remove references to the bufferSourceNode when it is done playing\n function _clearOnEnd(e) {\n const thisBufferSourceNode = e.target;\n const soundFile = this;\n\n // delete this.bufferSourceNode from the sources array when it is done playing:\n thisBufferSourceNode._playing = false;\n thisBufferSourceNode.removeEventListener('ended', soundFile._clearOnEnd);\n\n // call the onended callback\n soundFile._onended(soundFile);\n\n soundFile.bufferSourceNodes.forEach(function (n, i) {\n if (n._playing === false) {\n soundFile.bufferSourceNodes.splice(i);\n }\n });\n\n if (soundFile.bufferSourceNodes.length === 0) {\n soundFile._playing = false;\n }\n }\n});\n","'use strict';\n\ndefine(function (require) {\n var p5sound = require('master');\n var processorNames = require('./audioWorklet/processorNames');\n\n /**\n * Amplitude measures volume between 0.0 and 1.0.\n * Listens to all p5sound by default, or use setInput()\n * to listen to a specific sound source. Accepts an optional\n * smoothing value, which defaults to 0.\n *\n * @class p5.Amplitude\n * @constructor\n * @param {Number} [smoothing] between 0.0 and .999 to smooth\n * amplitude readings (defaults to 0)\n * @example\n *
\n * var sound, amplitude, cnv;\n *\n * function preload(){\n * sound = loadSound('assets/beat.mp3');\n * }\n * function setup() {\n * cnv = createCanvas(100,100);\n * amplitude = new p5.Amplitude();\n *\n * // start / stop the sound when canvas is clicked\n * cnv.mouseClicked(function() {\n * if (sound.isPlaying() ){\n * sound.stop();\n * } else {\n * sound.play();\n * }\n * });\n * }\n * function draw() {\n * background(0);\n * fill(255);\n * var level = amplitude.getLevel();\n * var size = map(level, 0, 1, 0, 200);\n * ellipse(width/2, height/2, size, size);\n * }\n *\n *
\n */\n p5.Amplitude = function(smoothing) {\n\n // Set to 2048 for now. In future iterations, this should be inherited or parsed from p5sound's default\n this.bufferSize = 2048;\n\n // set audio context\n this.audiocontext = p5sound.audiocontext;\n this._workletNode = new AudioWorkletNode(this.audiocontext, processorNames.amplitudeProcessor, {\n outputChannelCount: [1],\n processorOptions: {\n normalize: false,\n smoothing: smoothing || 0\n }\n });\n\n this._workletNode.port.onmessage = function(event) {\n if (event.data.name === 'amplitude') {\n this.volume = event.data.volume;\n this.volNorm = event.data.volNorm;\n this.stereoVol = event.data.stereoVol;\n this.stereoVolNorm = event.data.stereoVolNorm;\n }\n }.bind(this);\n\n // for connections\n this.input = this._workletNode;\n\n this.output = this.audiocontext.createGain();\n\n // the variables to return\n this.volume = 0;\n this.volNorm = 0;\n this.stereoVol = [0, 0];\n this.stereoVolNorm = [0, 0];\n\n this.normalize = false;\n\n this._workletNode.connect(this.output);\n this.output.gain.value = 0;\n\n // this may only be necessary because of a Chrome bug\n this.output.connect(this.audiocontext.destination);\n\n // connect to p5sound master output by default, unless set by input()\n p5sound.meter.connect(this._workletNode);\n\n // add this p5.SoundFile to the soundArray\n p5sound.soundArray.push(this);\n };\n\n /**\n * Connects to the p5sound instance (master output) by default.\n * Optionally, you can pass in a specific source (i.e. a soundfile).\n *\n * @method setInput\n * @for p5.Amplitude\n * @param {soundObject|undefined} [snd] set the sound source\n * (optional, defaults to\n * master output)\n * @param {Number|undefined} [smoothing] a range between 0.0 and 1.0\n * to smooth amplitude readings\n * @example\n *
\n * function preload(){\n * sound1 = loadSound('assets/beat.mp3');\n * sound2 = loadSound('assets/drum.mp3');\n * }\n * function setup(){\n * amplitude = new p5.Amplitude();\n * sound1.play();\n * sound2.play();\n * amplitude.setInput(sound2);\n * }\n * function draw() {\n * background(0);\n * fill(255);\n * var level = amplitude.getLevel();\n * var size = map(level, 0, 1, 0, 200);\n * ellipse(width/2, height/2, size, size);\n * }\n * function mouseClicked(){\n * sound1.stop();\n * sound2.stop();\n * }\n *
\n */\n p5.Amplitude.prototype.setInput = function(source, smoothing) {\n\n p5sound.meter.disconnect();\n\n if (smoothing) {\n this._workletNode.parameters.get('smoothing').value = smoothing;\n }\n\n // connect to the master out of p5s instance if no snd is provided\n if (source == null) {\n console.log('Amplitude input source is not ready! Connecting to master output instead');\n p5sound.meter.connect(this._workletNode);\n }\n\n // if it is a p5.Signal\n else if (source instanceof p5.Signal) {\n source.output.connect(this._workletNode);\n }\n // connect to the sound if it is available\n else if (source) {\n source.connect(this._workletNode);\n this._workletNode.disconnect();\n this._workletNode.connect(this.output);\n }\n\n // otherwise, connect to the master out of p5s instance (default)\n else {\n p5sound.meter.connect(this._workletNode);\n }\n };\n\n p5.Amplitude.prototype.connect = function(unit) {\n if (unit) {\n if (unit.hasOwnProperty('input')) {\n this.output.connect(unit.input);\n } else {\n this.output.connect(unit);\n }\n } else {\n this.output.connect(this.panner.connect(p5sound.input));\n }\n };\n\n p5.Amplitude.prototype.disconnect = function() {\n if (this.output) {\n this.output.disconnect();\n }\n };\n\n /**\n * Returns a single Amplitude reading at the moment it is called.\n * For continuous readings, run in the draw loop.\n *\n * @method getLevel\n * @for p5.Amplitude\n * @param {Number} [channel] Optionally return only channel 0 (left) or 1 (right)\n * @return {Number} Amplitude as a number between 0.0 and 1.0\n * @example\n *
\n * function preload(){\n * sound = loadSound('assets/beat.mp3');\n * }\n * function setup() {\n * amplitude = new p5.Amplitude();\n * sound.play();\n * }\n * function draw() {\n * background(0);\n * fill(255);\n * var level = amplitude.getLevel();\n * var size = map(level, 0, 1, 0, 200);\n * ellipse(width/2, height/2, size, size);\n * }\n * function mouseClicked(){\n * sound.stop();\n * }\n *
\n */\n p5.Amplitude.prototype.getLevel = function(channel) {\n if (typeof channel !== 'undefined') {\n if (this.normalize) {\n return this.stereoVolNorm[channel];\n } else {\n return this.stereoVol[channel];\n }\n }\n else if (this.normalize) {\n return this.volNorm;\n }\n else {\n return this.volume;\n }\n };\n\n /**\n * Determines whether the results of Amplitude.process() will be\n * Normalized. To normalize, Amplitude finds the difference the\n * loudest reading it has processed and the maximum amplitude of\n * 1.0. Amplitude adds this difference to all values to produce\n * results that will reliably map between 0.0 and 1.0. However,\n * if a louder moment occurs, the amount that Normalize adds to\n * all the values will change. Accepts an optional boolean parameter\n * (true or false). Normalizing is off by default.\n *\n * @method toggleNormalize\n * @for p5.Amplitude\n * @param {boolean} [boolean] set normalize to true (1) or false (0)\n */\n p5.Amplitude.prototype.toggleNormalize = function(bool) {\n if (typeof bool === 'boolean') {\n this.normalize = bool;\n }\n else {\n this.normalize = !this.normalize;\n }\n this._workletNode.port.postMessage({ name: 'toggleNormalize', normalize: this.normalize });\n };\n\n /**\n * Smooth Amplitude analysis by averaging with the last analysis\n * frame. Off by default.\n *\n * @method smooth\n * @for p5.Amplitude\n * @param {Number} set smoothing from 0.0 <= 1\n */\n p5.Amplitude.prototype.smooth = function(s) {\n if (s >= 0 && s < 1) {\n this._workletNode.port.postMessage({ name: 'smoothing', smoothing: s });\n } else {\n console.log('Error: smoothing must be between 0 and 1');\n }\n };\n\n p5.Amplitude.prototype.dispose = function() {\n // remove reference from soundArray\n var index = p5sound.soundArray.indexOf(this);\n p5sound.soundArray.splice(index, 1);\n\n if (this.input) {\n this.input.disconnect();\n delete this.input;\n }\n if (this.output) {\n this.output.disconnect();\n delete this.output;\n }\n\n this._workletNode.disconnect();\n delete this._workletNode;\n };\n\n});\n","'use strict';\n\ndefine(function(require) {\n var p5sound = require('master');\n\n /**\n *
FFT (Fast Fourier Transform) is an analysis algorithm that\n * isolates individual\n * \n * audio frequencies within a waveform.
\n *\n *
Once instantiated, a p5.FFT object can return an array based on\n * two types of analyses: • FFT.waveform() computes\n * amplitude values along the time domain. The array indices correspond\n * to samples across a brief moment in time. Each value represents\n * amplitude of the waveform at that sample of time. \n * • FFT.analyze() computes amplitude values along the\n * frequency domain. The array indices correspond to frequencies (i.e.\n * pitches), from the lowest to the highest that humans can hear. Each\n * value represents amplitude at that slice of the frequency spectrum.\n * Use with getEnergy() to measure amplitude at specific\n * frequencies, or within a range of frequencies.
\n *\n *
FFT analyzes a very short snapshot of sound called a sample\n * buffer. It returns an array of amplitude measurements, referred\n * to as bins. The array is 1024 bins long by default.\n * You can change the bin array length, but it must be a power of 2\n * between 16 and 1024 in order for the FFT algorithm to function\n * correctly. The actual size of the FFT buffer is twice the\n * number of bins, so given a standard sample rate, the buffer is\n * 2048/44100 seconds long.
\n *\n *\n * @class p5.FFT\n * @constructor\n * @param {Number} [smoothing] Smooth results of Freq Spectrum.\n * 0.0 < smoothing < 1.0.\n * Defaults to 0.8.\n * @param {Number} [bins] Length of resulting array.\n * Must be a power of two between\n * 16 and 1024. Defaults to 1024.\n * @example\n *
\n * function preload(){\n * sound = loadSound('assets/Damscray_DancingTiger.mp3');\n * }\n *\n * function setup(){\n * var cnv = createCanvas(100,100);\n * cnv.mouseClicked(togglePlay);\n * fft = new p5.FFT();\n * sound.amp(0.2);\n * }\n *\n * function draw(){\n * background(0);\n *\n * var spectrum = fft.analyze();\n * noStroke();\n * fill(0,255,0); // spectrum is green\n * for (var i = 0; i< spectrum.length; i++){\n * var x = map(i, 0, spectrum.length, 0, width);\n * var h = -height + map(spectrum[i], 0, 255, height, 0);\n * rect(x, height, width / spectrum.length, h )\n * }\n *\n * var waveform = fft.waveform();\n * noFill();\n * beginShape();\n * stroke(255,0,0); // waveform is red\n * strokeWeight(1);\n * for (var i = 0; i< waveform.length; i++){\n * var x = map(i, 0, waveform.length, 0, width);\n * var y = map( waveform[i], -1, 1, 0, height);\n * vertex(x,y);\n * }\n * endShape();\n *\n * text('click to play/pause', 4, 10);\n * }\n *\n * // fade sound if mouse is over canvas\n * function togglePlay() {\n * if (sound.isPlaying()) {\n * sound.pause();\n * } else {\n * sound.loop();\n * }\n * }\n *
\n */\n p5.FFT = function(smoothing, bins) {\n this.input = this.analyser = p5sound.audiocontext.createAnalyser();\n\n Object.defineProperties(this, {\n bins: {\n get: function() {\n return this.analyser.fftSize / 2;\n },\n set: function(b) {\n this.analyser.fftSize = b * 2;\n },\n configurable: true,\n enumerable: true\n },\n smoothing: {\n get: function() {\n return this.analyser.smoothingTimeConstant;\n },\n set: function(s) {\n this.analyser.smoothingTimeConstant = s;\n },\n configurable: true,\n enumerable: true\n }\n });\n\n // set default smoothing and bins\n this.smooth(smoothing);\n this.bins = bins || 1024;\n\n // default connections to p5sound fftMeter\n p5sound.fftMeter.connect(this.analyser);\n\n this.freqDomain = new Uint8Array(this.analyser.frequencyBinCount);\n this.timeDomain = new Uint8Array(this.analyser.frequencyBinCount);\n\n // predefined frequency ranges, these will be tweakable\n this.bass = [20, 140];\n this.lowMid = [140, 400];\n this.mid = [400, 2600];\n this.highMid = [2600, 5200];\n this.treble = [5200, 14000];\n\n // add this p5.SoundFile to the soundArray\n p5sound.soundArray.push(this);\n };\n\n /**\n * Set the input source for the FFT analysis. If no source is\n * provided, FFT will analyze all sound in the sketch.\n *\n * @method setInput\n * @for p5.FFT\n * @param {Object} [source] p5.sound object (or web audio API source node)\n */\n p5.FFT.prototype.setInput = function(source) {\n if (!source) {\n p5sound.fftMeter.connect(this.analyser);\n } else {\n if (source.output) {\n source.output.connect(this.analyser);\n } else if (source.connect) {\n source.connect(this.analyser);\n }\n p5sound.fftMeter.disconnect();\n }\n };\n\n /**\n * Returns an array of amplitude values (between -1.0 and +1.0) that represent\n * a snapshot of amplitude readings in a single buffer. Length will be\n * equal to bins (defaults to 1024). Can be used to draw the waveform\n * of a sound.\n *\n * @method waveform\n * @for p5.FFT\n * @param {Number} [bins] Must be a power of two between\n * 16 and 1024. Defaults to 1024.\n * @param {String} [precision] If any value is provided, will return results\n * in a Float32 Array which is more precise\n * than a regular array.\n * @return {Array} Array Array of amplitude values (-1 to 1)\n * over time. Array length = bins.\n *\n */\n p5.FFT.prototype.waveform = function() {\n var bins, mode, normalArray;\n\n for (var i = 0; i < arguments.length; i++) {\n if (typeof arguments[i] === 'number') {\n bins = arguments[i];\n this.analyser.fftSize = bins * 2;\n }\n if (typeof arguments[i] === 'string') {\n mode = arguments[i];\n }\n }\n\n // getFloatFrequencyData doesnt work in Safari as of 5/2015\n if (mode && !p5.prototype._isSafari()) {\n timeToFloat(this, this.timeDomain);\n this.analyser.getFloatTimeDomainData(this.timeDomain);\n return this.timeDomain;\n } else {\n timeToInt(this, this.timeDomain);\n this.analyser.getByteTimeDomainData(this.timeDomain);\n var normalArray = new Array();\n for (var j = 0; j < this.timeDomain.length; j++) {\n var scaled = p5.prototype.map(this.timeDomain[j], 0, 255, -1, 1);\n normalArray.push(scaled);\n }\n return normalArray;\n }\n };\n\n /**\n * Returns an array of amplitude values (between 0 and 255)\n * across the frequency spectrum. Length is equal to FFT bins\n * (1024 by default). The array indices correspond to frequencies\n * (i.e. pitches), from the lowest to the highest that humans can\n * hear. Each value represents amplitude at that slice of the\n * frequency spectrum. Must be called prior to using\n * getEnergy().\n *\n * @method analyze\n * @for p5.FFT\n * @param {Number} [bins] Must be a power of two between\n * 16 and 1024. Defaults to 1024.\n * @param {Number} [scale] If \"dB,\" returns decibel\n * float measurements between\n * -140 and 0 (max).\n * Otherwise returns integers from 0-255.\n * @return {Array} spectrum Array of energy (amplitude/volume)\n * values across the frequency spectrum.\n * Lowest energy (silence) = 0, highest\n * possible is 255.\n * @example\n *
\n * var osc;\n * var fft;\n *\n * function setup(){\n * createCanvas(100,100);\n * osc = new p5.Oscillator();\n * osc.amp(0);\n * osc.start();\n * fft = new p5.FFT();\n * }\n *\n * function draw(){\n * background(0);\n *\n * var freq = map(mouseX, 0, 800, 20, 15000);\n * freq = constrain(freq, 1, 20000);\n * osc.freq(freq);\n *\n * var spectrum = fft.analyze();\n * noStroke();\n * fill(0,255,0); // spectrum is green\n * for (var i = 0; i< spectrum.length; i++){\n * var x = map(i, 0, spectrum.length, 0, width);\n * var h = -height + map(spectrum[i], 0, 255, height, 0);\n * rect(x, height, width / spectrum.length, h );\n * }\n *\n * stroke(255);\n * text('Freq: ' + round(freq)+'Hz', 10, 10);\n *\n * isMouseOverCanvas();\n * }\n *\n * // only play sound when mouse is over canvas\n * function isMouseOverCanvas() {\n * var mX = mouseX, mY = mouseY;\n * if (mX > 0 && mX < width && mY < height && mY > 0) {\n * osc.amp(0.5, 0.2);\n * } else {\n * osc.amp(0, 0.2);\n * }\n * }\n *
\n *\n *\n */\n p5.FFT.prototype.analyze = function() {\n var mode;\n\n for (var i = 0; i < arguments.length; i++) {\n if (typeof arguments[i] === 'number') {\n this.bins = arguments[i];\n this.analyser.fftSize = this.bins * 2;\n }\n if (typeof arguments[i] === 'string') {\n mode = arguments[i];\n }\n }\n\n if (mode && mode.toLowerCase() === 'db') {\n freqToFloat(this);\n this.analyser.getFloatFrequencyData(this.freqDomain);\n return this.freqDomain;\n } else {\n freqToInt(this, this.freqDomain);\n this.analyser.getByteFrequencyData(this.freqDomain);\n var normalArray = Array.apply([], this.freqDomain);\n \n return normalArray;\n }\n };\n\n /**\n * Returns the amount of energy (volume) at a specific\n * \n * frequency, or the average amount of energy between two\n * frequencies. Accepts Number(s) corresponding\n * to frequency (in Hz), or a String corresponding to predefined\n * frequency ranges (\"bass\", \"lowMid\", \"mid\", \"highMid\", \"treble\").\n * Returns a range between 0 (no energy/volume at that frequency) and\n * 255 (maximum energy).\n * NOTE: analyze() must be called prior to getEnergy(). Analyze()\n * tells the FFT to analyze frequency data, and getEnergy() uses\n * the results determine the value at a specific frequency or\n * range of frequencies.\n *\n * @method getEnergy\n * @for p5.FFT\n * @param {Number|String} frequency1 Will return a value representing\n * energy at this frequency. Alternately,\n * the strings \"bass\", \"lowMid\" \"mid\",\n * \"highMid\", and \"treble\" will return\n * predefined frequency ranges.\n * @param {Number} [frequency2] If a second frequency is given,\n * will return average amount of\n * energy that exists between the\n * two frequencies.\n * @return {Number} Energy Energy (volume/amplitude) from\n * 0 and 255.\n *\n */\n p5.FFT.prototype.getEnergy = function(frequency1, frequency2) {\n var nyquist = p5sound.audiocontext.sampleRate / 2;\n\n if (frequency1 === 'bass') {\n frequency1 = this.bass[0];\n frequency2 = this.bass[1];\n } else if (frequency1 === 'lowMid') {\n frequency1 = this.lowMid[0];\n frequency2 = this.lowMid[1];\n } else if (frequency1 === 'mid') {\n frequency1 = this.mid[0];\n frequency2 = this.mid[1];\n } else if (frequency1 === 'highMid') {\n frequency1 = this.highMid[0];\n frequency2 = this.highMid[1];\n } else if (frequency1 === 'treble') {\n frequency1 = this.treble[0];\n frequency2 = this.treble[1];\n }\n\n if (typeof frequency1 !== 'number') {\n throw 'invalid input for getEnergy()';\n } else if (!frequency2) {\n // if only one parameter:\n var index = Math.round(frequency1 / nyquist * this.freqDomain.length);\n return this.freqDomain[index];\n } else if (frequency1 && frequency2) {\n // if two parameters:\n // if second is higher than first\n if (frequency1 > frequency2) {\n var swap = frequency2;\n frequency2 = frequency1;\n frequency1 = swap;\n }\n var lowIndex = Math.round(frequency1 / nyquist * this.freqDomain.length);\n var highIndex = Math.round(frequency2 / nyquist * this.freqDomain.length);\n\n var total = 0;\n var numFrequencies = 0;\n // add up all of the values for the frequencies\n for (var i = lowIndex; i <= highIndex; i++) {\n total += this.freqDomain[i];\n numFrequencies += 1;\n }\n // divide by total number of frequencies\n var toReturn = total / numFrequencies;\n return toReturn;\n } else {\n throw 'invalid input for getEnergy()';\n }\n };\n\n // compatability with v.012, changed to getEnergy in v.0121. Will be deprecated...\n p5.FFT.prototype.getFreq = function(freq1, freq2) {\n console.log('getFreq() is deprecated. Please use getEnergy() instead.');\n var x = this.getEnergy(freq1, freq2);\n return x;\n };\n\n /**\n * Returns the\n * \n * spectral centroid of the input signal.\n * NOTE: analyze() must be called prior to getCentroid(). Analyze()\n * tells the FFT to analyze frequency data, and getCentroid() uses\n * the results determine the spectral centroid.\n *\n * @method getCentroid\n * @for p5.FFT\n * @return {Number} Spectral Centroid Frequency Frequency of the spectral centroid in Hz.\n *\n *\n * @example\n *
\n *\n *\n *function setup(){\n * cnv = createCanvas(100,100);\n * sound = new p5.AudioIn();\n * sound.start();\n * fft = new p5.FFT();\n * sound.connect(fft);\n *}\n *\n *\n *function draw(){\n *\n * var centroidplot = 0.0;\n * var spectralCentroid = 0;\n *\n *\n * background(0);\n * stroke(0,255,0);\n * var spectrum = fft.analyze();\n * fill(0,255,0); // spectrum is green\n *\n * //draw the spectrum\n * for (var i = 0; i< spectrum.length; i++){\n * var x = map(log(i), 0, log(spectrum.length), 0, width);\n * var h = map(spectrum[i], 0, 255, 0, height);\n * var rectangle_width = (log(i+1)-log(i))*(width/log(spectrum.length));\n * rect(x, height, rectangle_width, -h )\n * }\n\n * var nyquist = 22050;\n *\n * // get the centroid\n * spectralCentroid = fft.getCentroid();\n *\n * // the mean_freq_index calculation is for the display.\n * var mean_freq_index = spectralCentroid/(nyquist/spectrum.length);\n *\n * centroidplot = map(log(mean_freq_index), 0, log(spectrum.length), 0, width);\n *\n *\n * stroke(255,0,0); // the line showing where the centroid is will be red\n *\n * rect(centroidplot, 0, width / spectrum.length, height)\n * noStroke();\n * fill(255,255,255); // text is white\n * text(\"centroid: \", 10, 20);\n * text(round(spectralCentroid)+\" Hz\", 10, 40);\n *}\n *
\n */\n p5.FFT.prototype.getCentroid = function() {\n var nyquist = p5sound.audiocontext.sampleRate / 2;\n var cumulative_sum = 0;\n var centroid_normalization = 0;\n\n for (var i = 0; i < this.freqDomain.length; i++) {\n cumulative_sum += i * this.freqDomain[i];\n centroid_normalization += this.freqDomain[i];\n }\n\n var mean_freq_index = 0;\n\n if (centroid_normalization !== 0) {\n mean_freq_index = cumulative_sum / centroid_normalization;\n }\n\n var spec_centroid_freq =\n mean_freq_index * (nyquist / this.freqDomain.length);\n return spec_centroid_freq;\n };\n\n /**\n * Smooth FFT analysis by averaging with the last analysis frame.\n *\n * @method smooth\n * @param {Number} smoothing 0.0 < smoothing < 1.0.\n * Defaults to 0.8.\n */\n p5.FFT.prototype.smooth = function(s) {\n if (typeof s !== 'undefined') {\n this.smoothing = s;\n }\n return this.smoothing;\n };\n\n p5.FFT.prototype.dispose = function() {\n // remove reference from soundArray\n var index = p5sound.soundArray.indexOf(this);\n p5sound.soundArray.splice(index, 1);\n\n if (this.analyser) {\n this.analyser.disconnect();\n delete this.analyser;\n }\n };\n\n /**\n * Returns an array of average amplitude values for a given number\n * of frequency bands split equally. N defaults to 16.\n * NOTE: analyze() must be called prior to linAverages(). Analyze()\n * tells the FFT to analyze frequency data, and linAverages() uses\n * the results to group them into a smaller set of averages.\n *\n * @method linAverages\n * @for p5.FFT\n * @param {Number} N Number of returned frequency groups\n * @return {Array} linearAverages Array of average amplitude values for each group\n */\n p5.FFT.prototype.linAverages = function(N) {\n var N = N || 16; // This prevents undefined, null or 0 values of N\n\n var spectrum = this.freqDomain;\n var spectrumLength = spectrum.length;\n var spectrumStep = Math.floor(spectrumLength / N);\n\n var linearAverages = new Array(N);\n // Keep a second index for the current average group and place the values accordingly\n // with only one loop in the spectrum data\n var groupIndex = 0;\n\n for (var specIndex = 0; specIndex < spectrumLength; specIndex++) {\n linearAverages[groupIndex] =\n linearAverages[groupIndex] !== undefined\n ? (linearAverages[groupIndex] + spectrum[specIndex]) / 2\n : spectrum[specIndex];\n\n // Increase the group index when the last element of the group is processed\n if (specIndex % spectrumStep === spectrumStep - 1) {\n groupIndex++;\n }\n }\n\n return linearAverages;\n };\n\n /**\n * Returns an array of average amplitude values of the spectrum, for a given\n * set of \n * Octave Bands\n * NOTE: analyze() must be called prior to logAverages(). Analyze()\n * tells the FFT to analyze frequency data, and logAverages() uses\n * the results to group them into a smaller set of averages.\n *\n * @method logAverages\n * @for p5.FFT\n * @param {Array} octaveBands Array of Octave Bands objects for grouping\n * @return {Array} logAverages Array of average amplitude values for each group\n */\n p5.FFT.prototype.logAverages = function(octaveBands) {\n var nyquist = p5sound.audiocontext.sampleRate / 2;\n var spectrum = this.freqDomain;\n var spectrumLength = spectrum.length;\n\n var logAverages = new Array(octaveBands.length);\n // Keep a second index for the current average group and place the values accordingly\n // With only one loop in the spectrum data\n var octaveIndex = 0;\n\n for (var specIndex = 0; specIndex < spectrumLength; specIndex++) {\n var specIndexFrequency = Math.round(\n specIndex * nyquist / this.freqDomain.length\n );\n\n // Increase the group index if the current frequency exceeds the limits of the band\n if (specIndexFrequency > octaveBands[octaveIndex].hi) {\n octaveIndex++;\n }\n\n logAverages[octaveIndex] =\n logAverages[octaveIndex] !== undefined\n ? (logAverages[octaveIndex] + spectrum[specIndex]) / 2\n : spectrum[specIndex];\n }\n\n return logAverages;\n };\n\n /**\n * Calculates and Returns the 1/N\n * Octave Bands\n * N defaults to 3 and minimum central frequency to 15.625Hz.\n * (1/3 Octave Bands ~= 31 Frequency Bands)\n * Setting fCtr0 to a central value of a higher octave will ignore the lower bands\n * and produce less frequency groups.\n *\n * @method getOctaveBands\n * @for p5.FFT\n * @param {Number} N Specifies the 1/N type of generated octave bands\n * @param {Number} fCtr0 Minimum central frequency for the lowest band\n * @return {Array} octaveBands Array of octave band objects with their bounds\n */\n p5.FFT.prototype.getOctaveBands = function(N, fCtr0) {\n var N = N || 3; // Default to 1/3 Octave Bands\n var fCtr0 = fCtr0 || 15.625; // Minimum central frequency, defaults to 15.625Hz\n\n var octaveBands = [];\n var lastFrequencyBand = {\n lo: fCtr0 / Math.pow(2, 1 / (2 * N)),\n ctr: fCtr0,\n hi: fCtr0 * Math.pow(2, 1 / (2 * N))\n };\n octaveBands.push(lastFrequencyBand);\n\n var nyquist = p5sound.audiocontext.sampleRate / 2;\n while (lastFrequencyBand.hi < nyquist) {\n var newFrequencyBand = {};\n newFrequencyBand.lo = lastFrequencyBand.hi;\n newFrequencyBand.ctr = lastFrequencyBand.ctr * Math.pow(2, 1 / N);\n newFrequencyBand.hi = newFrequencyBand.ctr * Math.pow(2, 1 / (2 * N));\n\n octaveBands.push(newFrequencyBand);\n lastFrequencyBand = newFrequencyBand;\n }\n\n return octaveBands;\n };\n\n // helper methods to convert type from float (dB) to int (0-255)\n var freqToFloat = function(fft) {\n if (fft.freqDomain instanceof Float32Array === false) {\n fft.freqDomain = new Float32Array(fft.analyser.frequencyBinCount);\n }\n };\n var freqToInt = function(fft) {\n if (fft.freqDomain instanceof Uint8Array === false) {\n fft.freqDomain = new Uint8Array(fft.analyser.frequencyBinCount);\n }\n };\n var timeToFloat = function(fft) {\n if (fft.timeDomain instanceof Float32Array === false) {\n fft.timeDomain = new Float32Array(fft.analyser.frequencyBinCount);\n }\n };\n var timeToInt = function(fft) {\n if (fft.timeDomain instanceof Uint8Array === false) {\n fft.timeDomain = new Uint8Array(fft.analyser.frequencyBinCount);\n }\n };\n});\n","'use strict';\n\ndefine(function (require) {\n\n // Signal is built with the Tone.js signal by Yotam Mann\n // https://github.com/TONEnoTONE/Tone.js/\n var Signal = require('Tone/signal/Signal');\n var Add = require('Tone/signal/Add');\n var Mult = require('Tone/signal/Multiply');\n var Scale = require('Tone/signal/Scale');\n\n /**\n *
p5.Signal is a constant audio-rate signal used by p5.Oscillator\n * and p5.Envelope for modulation math.
\n *\n *
This is necessary because Web Audio is processed on a seprate clock.\n * For example, the p5 draw loop runs about 60 times per second. But\n * the audio clock must process samples 44100 times per second. If we\n * want to add a value to each of those samples, we can't do it in the\n * draw loop, but we can do it by adding a constant-rate audio signal.This class mostly functions behind the scenes in p5.sound, and returns\n * a Tone.Signal from the Tone.js library by Yotam Mann.\n * If you want to work directly with audio signals for modular\n * synthesis, check out\n * tone.js.
\n *\n * @class p5.Signal\n * @constructor\n * @return {Tone.Signal} A Signal object from the Tone.js library\n * @example\n *
\n * function setup() {\n * carrier = new p5.Oscillator('sine');\n * carrier.amp(1); // set amplitude\n * carrier.freq(220); // set frequency\n * carrier.start(); // start oscillating\n *\n * modulator = new p5.Oscillator('sawtooth');\n * modulator.disconnect();\n * modulator.amp(1);\n * modulator.freq(4);\n * modulator.start();\n *\n * // Modulator's default amplitude range is -1 to 1.\n * // Multiply it by -200, so the range is -200 to 200\n * // then add 220 so the range is 20 to 420\n * carrier.freq( modulator.mult(-200).add(220) );\n * }\n *
\n */\n p5.Signal = function(value) {\n var s = new Signal(value);\n // p5sound.soundArray.push(s);\n return s; // TODO: is this really a constructor?\n };\n\n /**\n * Fade to value, for smooth transitions\n *\n * @method fade\n * @for p5.Signal\n * @param {Number} value Value to set this signal\n * @param {Number} [secondsFromNow] Length of fade, in seconds from now\n */\n Signal.prototype.fade = Signal.prototype.linearRampToValueAtTime;\n Mult.prototype.fade = Signal.prototype.fade;\n Add.prototype.fade = Signal.prototype.fade;\n Scale.prototype.fade = Signal.prototype.fade;\n\n\n /**\n * Connect a p5.sound object or Web Audio node to this\n * p5.Signal so that its amplitude values can be scaled.\n *\n * @method setInput\n * @for p5.Signal\n * @param {Object} input\n */\n Signal.prototype.setInput = function(_input) {\n _input.connect(this);\n };\n Mult.prototype.setInput = Signal.prototype.setInput;\n Add.prototype.setInput = Signal.prototype.setInput;\n Scale.prototype.setInput = Signal.prototype.setInput;\n\n\n // signals can add / mult / scale themselves\n\n /**\n * Add a constant value to this audio signal,\n * and return the resulting audio signal. Does\n * not change the value of the original signal,\n * instead it returns a new p5.SignalAdd.\n *\n * @method add\n * @for p5.Signal\n * @param {Number} number\n * @return {p5.Signal} object\n */\n Signal.prototype.add = function(num) {\n var add = new Add(num);\n // add.setInput(this);\n this.connect(add);\n return add;\n };\n Mult.prototype.add = Signal.prototype.add;\n Add.prototype.add = Signal.prototype.add;\n Scale.prototype.add = Signal.prototype.add;\n\n /**\n * Multiply this signal by a constant value,\n * and return the resulting audio signal. Does\n * not change the value of the original signal,\n * instead it returns a new p5.SignalMult.\n *\n * @method mult\n * @for p5.Signal\n * @param {Number} number to multiply\n * @return {p5.Signal} object\n */\n Signal.prototype.mult = function(num) {\n var mult = new Mult(num);\n // mult.setInput(this);\n this.connect(mult);\n return mult;\n };\n Mult.prototype.mult = Signal.prototype.mult;\n Add.prototype.mult = Signal.prototype.mult;\n Scale.prototype.mult = Signal.prototype.mult;\n\n /**\n * Scale this signal value to a given range,\n * and return the result as an audio signal. Does\n * not change the value of the original signal,\n * instead it returns a new p5.SignalScale.\n *\n * @method scale\n * @for p5.Signal\n * @param {Number} number to multiply\n * @param {Number} inMin input range minumum\n * @param {Number} inMax input range maximum\n * @param {Number} outMin input range minumum\n * @param {Number} outMax input range maximum\n * @return {p5.Signal} object\n */\n Signal.prototype.scale = function(inMin, inMax, outMin, outMax) {\n var mapOutMin, mapOutMax;\n if (arguments.length === 4) {\n mapOutMin = p5.prototype.map(outMin, inMin, inMax, 0, 1) - 0.5;\n mapOutMax = p5.prototype.map(outMax, inMin, inMax, 0, 1) - 0.5;\n }\n else {\n mapOutMin = arguments[0];\n mapOutMax = arguments[1];\n }\n var scale = new Scale(mapOutMin, mapOutMax);\n this.connect(scale);\n return scale;\n };\n Mult.prototype.scale = Signal.prototype.scale;\n Add.prototype.scale = Signal.prototype.scale;\n Scale.prototype.scale = Signal.prototype.scale;\n\n});\n\n\n","define([\"Tone/core/Tone\", \"Tone/type/TimeBase\"], function (Tone) {\n\n\t/**\n\t * @class Tone.Frequency is a primitive type for encoding Frequency values. \n\t * Eventually all time values are evaluated to hertz\n\t * using the `eval` method. \n\t * @constructor\n\t * @extends {Tone.TimeBase}\n\t * @param {String|Number} val The time value.\n\t * @param {String=} units The units of the value.\n\t * @example\n\t * Tone.Frequency(\"C3\") // 261\n\t * Tone.Frequency(38, \"midi\") //\n\t * Tone.Frequency(\"C3\").transpose(4);\n\t */\n\tTone.Frequency = function(val, units){\n\t\tif (this instanceof Tone.Frequency){\n\t\t\t\n\t\t\tTone.TimeBase.call(this, val, units);\n\n\t\t} else {\n\t\t\treturn new Tone.Frequency(val, units);\n\t\t}\n\t};\n\n\tTone.extend(Tone.Frequency, Tone.TimeBase);\n\n\t///////////////////////////////////////////////////////////////////////////\n\t//\tAUGMENT BASE EXPRESSIONS\n\t///////////////////////////////////////////////////////////////////////////\n\n\t//clone the expressions so that \n\t//we can add more without modifying the original\n\tTone.Frequency.prototype._primaryExpressions = Object.create(Tone.TimeBase.prototype._primaryExpressions);\n\n\t/*\n\t * midi type primary expression\n\t * @type {Object}\n\t * @private\n\t */\n\tTone.Frequency.prototype._primaryExpressions.midi = {\n\t\tregexp : /^(\\d+(?:\\.\\d+)?midi)/,\n\t\tmethod : function(value){\n\t\t\treturn this.midiToFrequency(value);\n\t\t}\t\n\t};\n\n\t/*\n\t * note type primary expression\n\t * @type {Object}\n\t * @private\n\t */\n\tTone.Frequency.prototype._primaryExpressions.note = {\n\t\tregexp : /^([a-g]{1}(?:b|#|x|bb)?)(-?[0-9]+)/i,\n\t\tmethod : function(pitch, octave){\n\t\t\tvar index = noteToScaleIndex[pitch.toLowerCase()];\n\t\t\tvar noteNumber = index + (parseInt(octave) + 1) * 12;\n\t\t\treturn this.midiToFrequency(noteNumber);\n\t\t}\t\n\t};\n\n\t/*\n\t * BeatsBarsSixteenths type primary expression\n\t * @type {Object}\n\t * @private\n\t */\n\tTone.Frequency.prototype._primaryExpressions.tr = {\n\t\t\tregexp : /^(\\d+(?:\\.\\d+)?):(\\d+(?:\\.\\d+)?):?(\\d+(?:\\.\\d+)?)?/,\n\t\t\tmethod : function(m, q, s){\n\t\t\tvar total = 1;\n\t\t\tif (m && m !== \"0\"){\n\t\t\t\ttotal *= this._beatsToUnits(this._timeSignature() * parseFloat(m));\n\t\t\t}\n\t\t\tif (q && q !== \"0\"){\n\t\t\t\ttotal *= this._beatsToUnits(parseFloat(q));\n\t\t\t}\n\t\t\tif (s && s !== \"0\"){\n\t\t\t\ttotal *= this._beatsToUnits(parseFloat(s) / 4);\n\t\t\t}\n\t\t\treturn total;\n\t\t}\n\t};\n\n\t///////////////////////////////////////////////////////////////////////////\n\t//\tEXPRESSIONS\n\t///////////////////////////////////////////////////////////////////////////\n\n\t/**\n\t * Transposes the frequency by the given number of semitones.\n\t * @param {Interval} interval\n\t * @return {Tone.Frequency} this\n\t * @example\n\t * Tone.Frequency(\"A4\").transpose(3); //\"C5\"\n\t */\n\tTone.Frequency.prototype.transpose = function(interval){\n\t\tthis._expr = function(expr, interval){\n\t\t\tvar val = expr();\n\t\t\treturn val * this.intervalToFrequencyRatio(interval);\n\t\t}.bind(this, this._expr, interval);\n\t\treturn this;\n\t};\n\n\t/**\n\t * Takes an array of semitone intervals and returns\n\t * an array of frequencies transposed by those intervals.\n\t * @param {Array} intervals\n\t * @return {Tone.Frequency} this\n\t * @example\n\t * Tone.Frequency(\"A4\").harmonize([0, 3, 7]); //[\"A4\", \"C5\", \"E5\"]\n\t */\n\tTone.Frequency.prototype.harmonize = function(intervals){\n\t\tthis._expr = function(expr, intervals){\n\t\t\tvar val = expr();\n\t\t\tvar ret = [];\n\t\t\tfor (var i = 0; i < intervals.length; i++){\n\t\t\t\tret[i] = val * this.intervalToFrequencyRatio(intervals[i]);\n\t\t\t}\n\t\t\treturn ret;\n\t\t}.bind(this, this._expr, intervals);\n\t\treturn this;\n\t};\n\n\t///////////////////////////////////////////////////////////////////////////\n\t//\tUNIT CONVERSIONS\n\t///////////////////////////////////////////////////////////////////////////\n\n\t/**\n\t * Return the value of the frequency as a MIDI note\n\t * @return {MIDI}\n\t * @example\n\t * Tone.Frequency(\"C4\").toMidi(); //60\n\t */\n\tTone.Frequency.prototype.toMidi = function(){\n\t\treturn this.frequencyToMidi(this.valueOf());\n\t};\n\n\t/**\n\t * Return the value of the frequency in Scientific Pitch Notation\n\t * @return {Note}\n\t * @example\n\t * Tone.Frequency(69, \"midi\").toNote(); //\"A4\"\n\t */\n\tTone.Frequency.prototype.toNote = function(){\n\t\tvar freq = this.valueOf();\n\t\tvar log = Math.log(freq / Tone.Frequency.A4) / Math.LN2;\n\t\tvar noteNumber = Math.round(12 * log) + 57;\n\t\tvar octave = Math.floor(noteNumber/12);\n\t\tif(octave < 0){\n\t\t\tnoteNumber += -12 * octave;\n\t\t}\n\t\tvar noteName = scaleIndexToNote[noteNumber % 12];\n\t\treturn noteName + octave.toString();\n\t};\n\n\t/**\n\t * Return the duration of one cycle in seconds.\n\t * @return {Seconds}\n\t */\n\tTone.Frequency.prototype.toSeconds = function(){\n\t\treturn 1 / this.valueOf();\n\t};\n\n\t/**\n\t * Return the value in Hertz\n\t * @return {Frequency}\n\t */\n\tTone.Frequency.prototype.toFrequency = function(){\n\t\treturn this.valueOf();\n\t};\n\n\t/**\n\t * Return the duration of one cycle in ticks\n\t * @return {Ticks}\n\t */\n\tTone.Frequency.prototype.toTicks = function(){\n\t\tvar quarterTime = this._beatsToUnits(1);\n\t\tvar quarters = this.valueOf() / quarterTime;\n\t\treturn Math.floor(quarters * Tone.Transport.PPQ);\n\t};\n\n\t///////////////////////////////////////////////////////////////////////////\n\t//\tUNIT CONVERSIONS HELPERS\n\t///////////////////////////////////////////////////////////////////////////\n\n\t/**\n\t * Returns the value of a frequency in the current units\n\t * @param {Frequency} freq\n\t * @return {Number}\n\t * @private\n\t */\n\tTone.Frequency.prototype._frequencyToUnits = function(freq){\n\t\treturn freq;\n\t};\n\n\t/**\n\t * Returns the value of a tick in the current time units\n\t * @param {Ticks} ticks\n\t * @return {Number}\n\t * @private\n\t */\n\tTone.Frequency.prototype._ticksToUnits = function(ticks){\n\t\treturn 1 / ((ticks * 60) / (Tone.Transport.bpm.value * Tone.Transport.PPQ));\n\t};\n\n\t/**\n\t * Return the value of the beats in the current units\n\t * @param {Number} beats\n\t * @return {Number}\n\t * @private\n\t */\n\tTone.Frequency.prototype._beatsToUnits = function(beats){\n\t\treturn 1 / Tone.TimeBase.prototype._beatsToUnits.call(this, beats);\n\t};\n\n\t/**\n\t * Returns the value of a second in the current units\n\t * @param {Seconds} seconds\n\t * @return {Number}\n\t * @private\n\t */\n\tTone.Frequency.prototype._secondsToUnits = function(seconds){\n\t\treturn 1 / seconds;\n\t};\n\n\t/**\n\t * The default units if none are given.\n\t * @private\n\t */\n\tTone.Frequency.prototype._defaultUnits = \"hz\";\n\n\t///////////////////////////////////////////////////////////////////////////\n\t//\tFREQUENCY CONVERSIONS\n\t///////////////////////////////////////////////////////////////////////////\n\n\t/**\n\t * Note to scale index\n\t * @type {Object}\n\t */\n\tvar noteToScaleIndex = {\n\t\t\"cbb\" : -2, \"cb\" : -1, \"c\" : 0, \"c#\" : 1, \"cx\" : 2, \n\t\t\"dbb\" : 0, \"db\" : 1, \"d\" : 2, \"d#\" : 3, \"dx\" : 4,\n\t\t\"ebb\" : 2, \"eb\" : 3, \"e\" : 4, \"e#\" : 5, \"ex\" : 6, \n\t\t\"fbb\" : 3, \"fb\" : 4, \"f\" : 5, \"f#\" : 6, \"fx\" : 7,\n\t\t\"gbb\" : 5, \"gb\" : 6, \"g\" : 7, \"g#\" : 8, \"gx\" : 9,\n\t\t\"abb\" : 7, \"ab\" : 8, \"a\" : 9, \"a#\" : 10, \"ax\" : 11,\n\t\t\"bbb\" : 9, \"bb\" : 10, \"b\" : 11, \"b#\" : 12, \"bx\" : 13,\n\t};\n\n\t/**\n\t * scale index to note (sharps)\n\t * @type {Array}\n\t */\n\tvar scaleIndexToNote = [\"C\", \"C#\", \"D\", \"D#\", \"E\", \"F\", \"F#\", \"G\", \"G#\", \"A\", \"A#\", \"B\"];\n\n\t/**\n\t * The [concert pitch](https://en.wikipedia.org/wiki/Concert_pitch)\n\t * A4's values in Hertz. \n\t * @type {Frequency}\n\t * @static\n\t */\n\tTone.Frequency.A4 = 440;\n\n\t/**\n\t * Convert a MIDI note to frequency value. \n\t * @param {MIDI} midi The midi number to convert.\n\t * @return {Frequency} the corresponding frequency value\n\t * @example\n\t * tone.midiToFrequency(69); // returns 440\n\t */\n\tTone.Frequency.prototype.midiToFrequency = function(midi){\n\t\treturn Tone.Frequency.A4 * Math.pow(2, (midi - 69) / 12);\n\t};\n\n\t/**\n\t * Convert a frequency value to a MIDI note.\n\t * @param {Frequency} frequency The value to frequency value to convert.\n\t * @returns {MIDI}\n\t * @example\n\t * tone.midiToFrequency(440); // returns 69\n\t */\n\tTone.Frequency.prototype.frequencyToMidi = function(frequency){\n\t\treturn 69 + 12 * Math.log(frequency / Tone.Frequency.A4) / Math.LN2;\n\t};\n\n\treturn Tone.Frequency;\n});","define([\"Tone/core/Tone\", \"Tone/type/Time\"], function (Tone) {\n\n\t/**\n\t * @class Tone.TransportTime is a the time along the Transport's\n\t * timeline. It is similar to Tone.Time, but instead of evaluating\n\t * against the AudioContext's clock, it is evaluated against\n\t * the Transport's position. See [TransportTime wiki](https://github.com/Tonejs/Tone.js/wiki/TransportTime).\n\t * @constructor\n\t * @param {Time} val The time value as a number or string\n\t * @param {String=} units Unit values\n\t * @extends {Tone.Time}\n\t */\n\tTone.TransportTime = function(val, units){\n\t\tif (this instanceof Tone.TransportTime){\n\t\t\t\n\t\t\tTone.Time.call(this, val, units);\n\n\t\t} else {\n\t\t\treturn new Tone.TransportTime(val, units);\n\t\t}\n\t};\n\n\tTone.extend(Tone.TransportTime, Tone.Time);\n\n\t//clone the expressions so that \n\t//we can add more without modifying the original\n\tTone.TransportTime.prototype._unaryExpressions = Object.create(Tone.Time.prototype._unaryExpressions);\n\n\t/**\n\t * Adds an additional unary expression\n\t * which quantizes values to the next subdivision\n\t * @type {Object}\n\t * @private\n\t */\n\tTone.TransportTime.prototype._unaryExpressions.quantize = {\n\t\tregexp : /^@/,\n\t\tmethod : function(rh){\n\t\t\tvar subdivision = this._secondsToTicks(rh());\n\t\t\tvar multiple = Math.ceil(Tone.Transport.ticks / subdivision);\n\t\t\treturn this._ticksToUnits(multiple * subdivision);\n\t\t}\n\t};\n\n\t/**\n\t * Convert seconds into ticks\n\t * @param {Seconds} seconds\n\t * @return {Ticks}\n\t * @private\n\t */\n\tTone.TransportTime.prototype._secondsToTicks = function(seconds){\n\t\tvar quarterTime = this._beatsToUnits(1);\n\t\tvar quarters = seconds / quarterTime;\n\t\treturn Math.round(quarters * Tone.Transport.PPQ);\n\t};\n\n\t/**\n\t * Evaluate the time expression. Returns values in ticks\n\t * @return {Ticks}\n\t */\n\tTone.TransportTime.prototype.valueOf = function(){\n\t\tvar val = this._secondsToTicks(this._expr());\n\t\treturn val + (this._plusNow ? Tone.Transport.ticks : 0);\n\t};\n\n\t/**\n\t * Return the time in ticks.\n\t * @return {Ticks}\n\t */\n\tTone.TransportTime.prototype.toTicks = function(){\n\t\treturn this.valueOf();\n\t};\n\n\t/**\n\t * Return the time in seconds.\n\t * @return {Seconds}\n\t */\n\tTone.TransportTime.prototype.toSeconds = function(){\n\t\tvar val = this._expr();\n\t\treturn val + (this._plusNow ? Tone.Transport.seconds : 0);\n\t};\n\n\t/**\n\t * Return the time as a frequency value\n\t * @return {Frequency} \n\t */\n\tTone.TransportTime.prototype.toFrequency = function(){\n\t\treturn 1/this.toSeconds();\n\t};\n\n\treturn Tone.TransportTime;\n});","'use strict';\n\ndefine(function (require) {\n\n var p5sound = require('master');\n var Add = require('Tone/signal/Add');\n var Mult = require('Tone/signal/Multiply');\n var Scale = require('Tone/signal/Scale');\n var TimelineSignal = require('Tone/signal/TimelineSignal');\n\n /**\n *
Envelopes are pre-defined amplitude distribution over time.\n * Typically, envelopes are used to control the output volume\n * of an object, a series of fades referred to as Attack, Decay,\n * Sustain and Release (\n * ADSR\n * ). Envelopes can also control other Web Audio Parameters—for example, a p5.Envelope can\n * control an Oscillator's frequency like this: osc.freq(env).
\n *
Use setRange to change the attack/release level.\n * Use setADSR to change attackTime, decayTime, sustainPercent and releaseTime.
\n *
Use the play method to play the entire envelope,\n * the ramp method for a pingable trigger,\n * or triggerAttack/\n * triggerRelease to trigger noteOn/noteOff.
\n * var attackLevel = 1.0;\n * var releaseLevel = 0;\n *\n * var attackTime = 0.001;\n * var decayTime = 0.2;\n * var susPercent = 0.2;\n * var releaseTime = 0.5;\n *\n * var env, triOsc;\n *\n * function setup() {\n * var cnv = createCanvas(100, 100);\n *\n * textAlign(CENTER);\n * text('click to play', width/2, height/2);\n *\n * env = new p5.Envelope();\n * env.setADSR(attackTime, decayTime, susPercent, releaseTime);\n * env.setRange(attackLevel, releaseLevel);\n *\n * triOsc = new p5.Oscillator('triangle');\n * triOsc.amp(env);\n * triOsc.start();\n * triOsc.freq(220);\n *\n * cnv.mousePressed(playEnv);\n * }\n *\n * function playEnv() {\n * env.play();\n * }\n *
\n */\n p5.Envelope = function(t1, l1, t2, l2, t3, l3) {\n /**\n * Time until envelope reaches attackLevel\n * @property attackTime\n */\n this.aTime = t1 || 0.1;\n /**\n * Level once attack is complete.\n * @property attackLevel\n */\n this.aLevel = l1 || 1;\n /**\n * Time until envelope reaches decayLevel.\n * @property decayTime\n */\n this.dTime = t2 || 0.5;\n /**\n * Level after decay. The envelope will sustain here until it is released.\n * @property decayLevel\n */\n this.dLevel = l2 || 0;\n /**\n * Duration of the release portion of the envelope.\n * @property releaseTime\n */\n this.rTime = t3 || 0;\n /**\n * Level at the end of the release.\n * @property releaseLevel\n */\n this.rLevel = l3 || 0;\n\n this._rampHighPercentage = 0.98;\n\n this._rampLowPercentage = 0.02;\n\n\n this.output = p5sound.audiocontext.createGain();\n\n this.control = new TimelineSignal();\n\n this._init(); // this makes sure the envelope starts at zero\n\n this.control.connect(this.output); // connect to the output\n\n this.connection = null; // store connection\n\n //array of math operation signal chaining\n this.mathOps = [this.control];\n\n //whether envelope should be linear or exponential curve\n this.isExponential = false;\n\n // oscillator or buffer source to clear on env complete\n // to save resources if/when it is retriggered\n this.sourceToClear = null;\n\n // set to true if attack is set, then false on release\n this.wasTriggered = false;\n\n\n // add to the soundArray so we can dispose of the env later\n p5sound.soundArray.push(this);\n };\n\n // this init function just smooths the starting value to zero and gives a start point for the timeline\n // - it was necessary to remove glitches at the beginning.\n p5.Envelope.prototype._init = function () {\n var now = p5sound.audiocontext.currentTime;\n var t = now;\n this.control.setTargetAtTime(0.00001, t, .001);\n //also, compute the correct time constants\n this._setRampAD(this.aTime, this.dTime);\n };\n\n /**\n * Reset the envelope with a series of time/value pairs.\n *\n * @method set\n * @for p5.Envelope\n * @param {Number} attackTime Time (in seconds) before level\n * reaches attackLevel\n * @param {Number} attackLevel Typically an amplitude between\n * 0.0 and 1.0\n * @param {Number} decayTime Time\n * @param {Number} decayLevel Amplitude (In a standard ADSR envelope,\n * decayLevel = sustainLevel)\n * @param {Number} releaseTime Release Time (in seconds)\n * @param {Number} releaseLevel Amplitude\n * @example\n *
\n * var t1 = 0.1; // attack time in seconds\n * var l1 = 0.7; // attack level 0.0 to 1.0\n * var t2 = 0.3; // decay time in seconds\n * var l2 = 0.1; // decay level 0.0 to 1.0\n * var t3 = 0.2; // sustain time in seconds\n * var l3 = 0.5; // sustain level 0.0 to 1.0\n * // release level defaults to zero\n *\n * var env;\n * var triOsc;\n *\n * function setup() {\n * background(0);\n * noStroke();\n * fill(255);\n * textAlign(CENTER);\n * text('click to play', width/2, height/2);\n *\n * env = new p5.Envelope(t1, l1, t2, l2, t3, l3);\n * triOsc = new p5.Oscillator('triangle');\n * triOsc.amp(env); // give the env control of the triOsc's amp\n * triOsc.start();\n * }\n *\n * // mouseClick triggers envelope if over canvas\n * function mouseClicked() {\n * // is mouse over canvas?\n * if (mouseX > 0 && mouseX < width && mouseY > 0 && mouseY < height) {\n * env.play(triOsc);\n * }\n * }\n *
\n *\n */\n p5.Envelope.prototype.set = function(t1, l1, t2, l2, t3, l3) {\n this.aTime = t1;\n this.aLevel = l1;\n this.dTime = t2 || 0;\n this.dLevel = l2 || 0;\n this.rTime = t3 || 0;\n this.rLevel = l3 || 0;\n\n // set time constants for ramp\n this._setRampAD(t1, t2);\n };\n\n /**\n * Set values like a traditional\n * \n * ADSR envelope\n * .\n *\n * @method setADSR\n * @for p5.Envelope\n * @param {Number} attackTime Time (in seconds before envelope\n * reaches Attack Level\n * @param {Number} [decayTime] Time (in seconds) before envelope\n * reaches Decay/Sustain Level\n * @param {Number} [susRatio] Ratio between attackLevel and releaseLevel, on a scale from 0 to 1,\n * where 1.0 = attackLevel, 0.0 = releaseLevel.\n * The susRatio determines the decayLevel and the level at which the\n * sustain portion of the envelope will sustain.\n * For example, if attackLevel is 0.4, releaseLevel is 0,\n * and susAmt is 0.5, the decayLevel would be 0.2. If attackLevel is\n * increased to 1.0 (using setRange),\n * then decayLevel would increase proportionally, to become 0.5.\n * @param {Number} [releaseTime] Time in seconds from now (defaults to 0)\n * @example\n *
\n * var attackLevel = 1.0;\n * var releaseLevel = 0;\n *\n * var attackTime = 0.001;\n * var decayTime = 0.2;\n * var susPercent = 0.2;\n * var releaseTime = 0.5;\n *\n * var env, triOsc;\n *\n * function setup() {\n * var cnv = createCanvas(100, 100);\n *\n * textAlign(CENTER);\n * text('click to play', width/2, height/2);\n *\n * env = new p5.Envelope();\n * env.setADSR(attackTime, decayTime, susPercent, releaseTime);\n * env.setRange(attackLevel, releaseLevel);\n *\n * triOsc = new p5.Oscillator('triangle');\n * triOsc.amp(env);\n * triOsc.start();\n * triOsc.freq(220);\n *\n * cnv.mousePressed(playEnv);\n * }\n *\n * function playEnv() {\n * env.play();\n * }\n *
\n */\n p5.Envelope.prototype.setADSR = function(aTime, dTime, sPercent, rTime) {\n this.aTime = aTime;\n this.dTime = dTime || 0;\n\n // lerp\n this.sPercent = sPercent || 0;\n this.dLevel = typeof sPercent !== 'undefined' ? sPercent * (this.aLevel - this.rLevel) + this.rLevel : 0;\n\n this.rTime = rTime || 0;\n\n // also set time constants for ramp\n this._setRampAD(aTime, dTime);\n };\n\n /**\n * Set max (attackLevel) and min (releaseLevel) of envelope.\n *\n * @method setRange\n * @for p5.Envelope\n * @param {Number} aLevel attack level (defaults to 1)\n * @param {Number} rLevel release level (defaults to 0)\n * @example\n *
\n * var attackLevel = 1.0;\n * var releaseLevel = 0;\n *\n * var attackTime = 0.001;\n * var decayTime = 0.2;\n * var susPercent = 0.2;\n * var releaseTime = 0.5;\n *\n * var env, triOsc;\n *\n * function setup() {\n * var cnv = createCanvas(100, 100);\n *\n * textAlign(CENTER);\n * text('click to play', width/2, height/2);\n *\n * env = new p5.Envelope();\n * env.setADSR(attackTime, decayTime, susPercent, releaseTime);\n * env.setRange(attackLevel, releaseLevel);\n *\n * triOsc = new p5.Oscillator('triangle');\n * triOsc.amp(env);\n * triOsc.start();\n * triOsc.freq(220);\n *\n * cnv.mousePressed(playEnv);\n * }\n *\n * function playEnv() {\n * env.play();\n * }\n *
\n */\n p5.Envelope.prototype.setRange = function(aLevel, rLevel) {\n this.aLevel = aLevel || 1;\n this.rLevel = rLevel || 0;\n\n // not sure if this belongs here:\n\n // {Number} [dLevel] decay/sustain level (optional)\n // if (typeof(dLevel) !== 'undefined') {\n // this.dLevel = dLevel\n // } else if (this.sPercent) {\n // this.dLevel = this.sPercent ? this.sPercent * (this.aLevel - this.rLevel) + this.rLevel : 0;\n // }\n };\n\n // private (undocumented) method called when ADSR is set to set time constants for ramp\n //\n // Set the \n // time constants for simple exponential ramps.\n // The larger the time constant value, the slower the\n // transition will be.\n //\n // method _setRampAD\n // param {Number} attackTimeConstant attack time constant\n // param {Number} decayTimeConstant decay time constant\n //\n p5.Envelope.prototype._setRampAD = function(t1, t2) {\n this._rampAttackTime = this.checkExpInput(t1);\n this._rampDecayTime = this.checkExpInput(t2);\n\n var TCDenominator = 1.0;\n /// Aatish Bhatia's calculation for time constant for rise(to adjust 1/1-e calculation to any percentage)\n TCDenominator = Math.log(1.0 / this.checkExpInput(1.0 - this._rampHighPercentage));\n this._rampAttackTC = t1 / this.checkExpInput(TCDenominator);\n TCDenominator = Math.log(1.0 / this._rampLowPercentage);\n this._rampDecayTC = t2 / this.checkExpInput(TCDenominator);\n };\n\n // private method\n p5.Envelope.prototype.setRampPercentages = function(p1, p2) {\n //set the percentages that the simple exponential ramps go to\n this._rampHighPercentage = this.checkExpInput(p1);\n this._rampLowPercentage = this.checkExpInput(p2);\n var TCDenominator = 1.0;\n //now re-compute the time constants based on those percentages\n /// Aatish Bhatia's calculation for time constant for rise(to adjust 1/1-e calculation to any percentage)\n TCDenominator = Math.log(1.0 / this.checkExpInput(1.0 - this._rampHighPercentage));\n this._rampAttackTC = this._rampAttackTime / this.checkExpInput(TCDenominator);\n TCDenominator = Math.log(1.0 / this._rampLowPercentage);\n this._rampDecayTC = this._rampDecayTime / this.checkExpInput(TCDenominator);\n };\n\n\n /**\n * Assign a parameter to be controlled by this envelope.\n * If a p5.Sound object is given, then the p5.Envelope will control its\n * output gain. If multiple inputs are provided, the env will\n * control all of them.\n *\n * @method setInput\n * @for p5.Envelope\n * @param {Object} [...inputs] A p5.sound object or\n * Web Audio Param.\n */\n p5.Envelope.prototype.setInput = function() {\n for (var i = 0; i\n * Web Audio Audio Param.\n *\n * @method play\n * @for p5.Envelope\n * @param {Object} unit A p5.sound object or\n * Web Audio Param.\n * @param {Number} [startTime] time from now (in seconds) at which to play\n * @param {Number} [sustainTime] time to sustain before releasing the envelope\n * @example\n *
\n * var attackLevel = 1.0;\n * var releaseLevel = 0;\n *\n * var attackTime = 0.001;\n * var decayTime = 0.2;\n * var susPercent = 0.2;\n * var releaseTime = 0.5;\n *\n * var env, triOsc;\n *\n * function setup() {\n * var cnv = createCanvas(100, 100);\n *\n * textAlign(CENTER);\n * text('click to play', width/2, height/2);\n *\n * env = new p5.Envelope();\n * env.setADSR(attackTime, decayTime, susPercent, releaseTime);\n * env.setRange(attackLevel, releaseLevel);\n *\n * triOsc = new p5.Oscillator('triangle');\n * triOsc.amp(env);\n * triOsc.start();\n * triOsc.freq(220);\n *\n * cnv.mousePressed(playEnv);\n * }\n *\n * function playEnv() {\n * // trigger env on triOsc, 0 seconds from now\n * // After decay, sustain for 0.2 seconds before release\n * env.play(triOsc, 0, 0.2);\n * }\n *
\n */\n p5.Envelope.prototype.play = function(unit, secondsFromNow, susTime) {\n var tFromNow = secondsFromNow || 0;\n var susTime = susTime || 0;\n\n if (unit) {\n if (this.connection !== unit) {\n this.connect(unit);\n }\n }\n\n this.triggerAttack(unit, tFromNow);\n\n this.triggerRelease(unit, tFromNow + this.aTime + this.dTime + susTime);\n\n };\n\n /**\n * Trigger the Attack, and Decay portion of the Envelope.\n * Similar to holding down a key on a piano, but it will\n * hold the sustain level until you let go. Input can be\n * any p5.sound object, or a \n * Web Audio Param.\n *\n * @method triggerAttack\n * @for p5.Envelope\n * @param {Object} unit p5.sound Object or Web Audio Param\n * @param {Number} secondsFromNow time from now (in seconds)\n * @example\n *
\n *\n * var attackLevel = 1.0;\n * var releaseLevel = 0;\n *\n * var attackTime = 0.001;\n * var decayTime = 0.3;\n * var susPercent = 0.4;\n * var releaseTime = 0.5;\n *\n * var env, triOsc;\n *\n * function setup() {\n * var cnv = createCanvas(100, 100);\n * background(200);\n * textAlign(CENTER);\n * text('click to play', width/2, height/2);\n *\n * env = new p5.Envelope();\n * env.setADSR(attackTime, decayTime, susPercent, releaseTime);\n * env.setRange(attackLevel, releaseLevel);\n *\n * triOsc = new p5.Oscillator('triangle');\n * triOsc.amp(env);\n * triOsc.start();\n * triOsc.freq(220);\n *\n * cnv.mousePressed(envAttack);\n * }\n *\n * function envAttack() {\n * console.log('trigger attack');\n * env.triggerAttack();\n *\n * background(0,255,0);\n * text('attack!', width/2, height/2);\n * }\n *\n * function mouseReleased() {\n * env.triggerRelease();\n *\n * background(200);\n * text('click to play', width/2, height/2);\n * }\n *
\n */\n p5.Envelope.prototype.triggerAttack = function(unit, secondsFromNow) {\n var now = p5sound.audiocontext.currentTime;\n var tFromNow = secondsFromNow || 0;\n var t = now + tFromNow;\n this.lastAttack = t;\n this.wasTriggered = true;\n\n if (unit) {\n if (this.connection !== unit) {\n this.connect(unit);\n }\n }\n\n // get and set value (with linear ramp) to anchor automation\n var valToSet = this.control.getValueAtTime(t);\n\n if (this.isExponential === true)\n {\n this.control.exponentialRampToValueAtTime(this.checkExpInput(valToSet), t);\n }\n else\n {\n this.control.linearRampToValueAtTime(valToSet, t);\n }\n\n // after each ramp completes, cancel scheduled values\n // (so they can be overridden in case env has been re-triggered)\n // then, set current value (with linearRamp to avoid click)\n // then, schedule the next automation...\n\n // attack\n t += this.aTime;\n if (this.isExponential === true)\n {\n this.control.exponentialRampToValueAtTime(this.checkExpInput(this.aLevel), t);\n valToSet = this.checkExpInput(this.control.getValueAtTime(t));\n this.control.cancelScheduledValues(t);\n this.control.exponentialRampToValueAtTime(valToSet, t);\n }\n else\n {\n this.control.linearRampToValueAtTime(this.aLevel, t);\n valToSet = this.control.getValueAtTime(t);\n this.control.cancelScheduledValues(t);\n this.control.linearRampToValueAtTime(valToSet, t);\n\n }\n\n // decay to decay level (if using ADSR, then decay level == sustain level)\n t += this.dTime;\n if (this.isExponential === true)\n {\n this.control.exponentialRampToValueAtTime(this.checkExpInput(this.dLevel), t);\n valToSet = this.checkExpInput(this.control.getValueAtTime(t));\n this.control.cancelScheduledValues(t);\n this.control.exponentialRampToValueAtTime(valToSet, t);\n }\n else\n {\n this.control.linearRampToValueAtTime(this.dLevel, t);\n valToSet = this.control.getValueAtTime(t);\n this.control.cancelScheduledValues(t);\n this.control.linearRampToValueAtTime(valToSet, t);\n }\n };\n\n /**\n * Trigger the Release of the Envelope. This is similar to releasing\n * the key on a piano and letting the sound fade according to the\n * release level and release time.\n *\n * @method triggerRelease\n * @for p5.Envelope\n * @param {Object} unit p5.sound Object or Web Audio Param\n * @param {Number} secondsFromNow time to trigger the release\n * @example\n *
\n *\n * var attackLevel = 1.0;\n * var releaseLevel = 0;\n *\n * var attackTime = 0.001;\n * var decayTime = 0.3;\n * var susPercent = 0.4;\n * var releaseTime = 0.5;\n *\n * var env, triOsc;\n *\n * function setup() {\n * var cnv = createCanvas(100, 100);\n * background(200);\n * textAlign(CENTER);\n * text('click to play', width/2, height/2);\n *\n * env = new p5.Envelope();\n * env.setADSR(attackTime, decayTime, susPercent, releaseTime);\n * env.setRange(attackLevel, releaseLevel);\n *\n * triOsc = new p5.Oscillator('triangle');\n * triOsc.amp(env);\n * triOsc.start();\n * triOsc.freq(220);\n *\n * cnv.mousePressed(envAttack);\n * }\n *\n * function envAttack() {\n * console.log('trigger attack');\n * env.triggerAttack();\n *\n * background(0,255,0);\n * text('attack!', width/2, height/2);\n * }\n *\n * function mouseReleased() {\n * env.triggerRelease();\n *\n * background(200);\n * text('click to play', width/2, height/2);\n * }\n *
\n */\n p5.Envelope.prototype.triggerRelease = function(unit, secondsFromNow) {\n\n // only trigger a release if an attack was triggered\n if (!this.wasTriggered) {\n // this currently causes a bit of trouble:\n // if a later release has been scheduled (via the play function)\n // a new earlier release won't interrupt it, because\n // this.wasTriggered has already been set to false.\n // If we want new earlier releases to override, then we need to\n // keep track of the last release time, and if the new release time is\n // earlier, then use it.\n return;\n }\n\n var now = p5sound.audiocontext.currentTime;\n var tFromNow = secondsFromNow || 0;\n var t = now + tFromNow;\n\n if (unit) {\n if (this.connection !== unit) {\n this.connect(unit);\n }\n }\n\n // get and set value (with linear or exponential ramp) to anchor automation\n var valToSet = this.control.getValueAtTime(t);\n if (this.isExponential === true)\n {\n this.control.exponentialRampToValueAtTime(this.checkExpInput(valToSet), t);\n }\n else\n {\n this.control.linearRampToValueAtTime(valToSet, t);\n }\n\n // release\n t += this.rTime;\n\n if (this.isExponential === true)\n {\n this.control.exponentialRampToValueAtTime(this.checkExpInput(this.rLevel), t);\n valToSet = this.checkExpInput(this.control.getValueAtTime(t));\n this.control.cancelScheduledValues(t);\n this.control.exponentialRampToValueAtTime(valToSet, t);\n }\n else\n {\n this.control.linearRampToValueAtTime(this.rLevel, t);\n valToSet = this.control.getValueAtTime(t);\n this.control.cancelScheduledValues(t);\n this.control.linearRampToValueAtTime(valToSet, t);\n }\n\n this.wasTriggered = false;\n };\n\n /**\n * Exponentially ramp to a value using the first two\n * values from setADSR(attackTime, decayTime)\n * as \n * time constants for simple exponential ramps.\n * If the value is higher than current value, it uses attackTime,\n * while a decrease uses decayTime.\n *\n * @method ramp\n * @for p5.Envelope\n * @param {Object} unit p5.sound Object or Web Audio Param\n * @param {Number} secondsFromNow When to trigger the ramp\n * @param {Number} v Target value\n * @param {Number} [v2] Second target value (optional)\n * @example\n *
\n * var env, osc, amp, cnv;\n *\n * var attackTime = 0.001;\n * var decayTime = 0.2;\n * var attackLevel = 1;\n * var decayLevel = 0;\n *\n * function setup() {\n * cnv = createCanvas(100, 100);\n * fill(0,255,0);\n * noStroke();\n *\n * env = new p5.Envelope();\n * env.setADSR(attackTime, decayTime);\n *\n * osc = new p5.Oscillator();\n * osc.amp(env);\n * osc.start();\n *\n * amp = new p5.Amplitude();\n *\n * cnv.mousePressed(triggerRamp);\n * }\n *\n * function triggerRamp() {\n * env.ramp(osc, 0, attackLevel, decayLevel);\n * }\n *\n * function draw() {\n * background(20,20,20);\n * text('click me', 10, 20);\n * var h = map(amp.getLevel(), 0, 0.4, 0, height);;\n *\n * rect(0, height, width, -h);\n * }\n *
\n */\n p5.Envelope.prototype.ramp = function(unit, secondsFromNow, v1, v2) {\n\n var now = p5sound.audiocontext.currentTime;\n var tFromNow = secondsFromNow || 0;\n var t = now + tFromNow;\n var destination1 = this.checkExpInput(v1);\n var destination2 = typeof v2 !== 'undefined' ? this.checkExpInput(v2) : undefined;\n\n // connect env to unit if not already connected\n if (unit) {\n if (this.connection !== unit) {\n this.connect(unit);\n }\n }\n\n //get current value\n var currentVal = this.checkExpInput(this.control.getValueAtTime(t));\n // this.control.cancelScheduledValues(t);\n\n //if it's going up\n if (destination1 > currentVal) {\n this.control.setTargetAtTime(destination1, t, this._rampAttackTC);\n t += this._rampAttackTime;\n }\n\n //if it's going down\n else if (destination1 < currentVal) {\n this.control.setTargetAtTime(destination1, t, this._rampDecayTC);\n t += this._rampDecayTime;\n }\n\n // Now the second part of envelope begins\n if (destination2 === undefined) return;\n\n //if it's going up\n if (destination2 > destination1) {\n this.control.setTargetAtTime(destination2, t, this._rampAttackTC);\n }\n\n //if it's going down\n else if (destination2 < destination1) {\n this.control.setTargetAtTime(destination2, t, this._rampDecayTC);\n }\n };\n\n\n p5.Envelope.prototype.connect = function(unit) {\n this.connection = unit;\n\n // assume we're talking about output gain\n // unless given a different audio param\n if (unit instanceof p5.Oscillator ||\n unit instanceof p5.SoundFile ||\n unit instanceof p5.AudioIn ||\n unit instanceof p5.Reverb ||\n unit instanceof p5.Noise ||\n unit instanceof p5.Filter ||\n unit instanceof p5.Delay\n ) {\n unit = unit.output.gain;\n }\n if (unit instanceof AudioParam) {\n //set the initial value\n unit.setValueAtTime(0, p5sound.audiocontext.currentTime);\n }\n if (unit instanceof p5.Signal) {\n unit.setValue(0);\n }\n this.output.connect(unit);\n };\n\n p5.Envelope.prototype.disconnect = function() {\n if (this.output) {\n this.output.disconnect();\n }\n };\n\n\n // Signal Math\n\n /**\n * Add a value to the p5.Oscillator's output amplitude,\n * and return the oscillator. Calling this method\n * again will override the initial add() with new values.\n *\n * @method add\n * @for p5.Envelope\n * @param {Number} number Constant number to add\n * @return {p5.Envelope} Envelope Returns this envelope\n * with scaled output\n */\n p5.Envelope.prototype.add = function(num) {\n var add = new Add(num);\n var thisChain = this.mathOps.length;\n var nextChain = this.output;\n return p5.prototype._mathChain(this, add, thisChain, nextChain, Add);\n };\n\n /**\n * Multiply the p5.Envelope's output amplitude\n * by a fixed value. Calling this method\n * again will override the initial mult() with new values.\n *\n * @method mult\n * @for p5.Envelope\n * @param {Number} number Constant number to multiply\n * @return {p5.Envelope} Envelope Returns this envelope\n * with scaled output\n */\n p5.Envelope.prototype.mult = function(num) {\n var mult = new Mult(num);\n var thisChain = this.mathOps.length;\n var nextChain = this.output;\n return p5.prototype._mathChain(this, mult, thisChain, nextChain, Mult);\n };\n\n /**\n * Scale this envelope's amplitude values to a given\n * range, and return the envelope. Calling this method\n * again will override the initial scale() with new values.\n *\n * @method scale\n * @for p5.Envelope\n * @param {Number} inMin input range minumum\n * @param {Number} inMax input range maximum\n * @param {Number} outMin input range minumum\n * @param {Number} outMax input range maximum\n * @return {p5.Envelope} Envelope Returns this envelope\n * with scaled output\n */\n p5.Envelope.prototype.scale = function(inMin, inMax, outMin, outMax) {\n var scale = new Scale(inMin, inMax, outMin, outMax);\n var thisChain = this.mathOps.length;\n var nextChain = this.output;\n return p5.prototype._mathChain(this, scale, thisChain, nextChain, Scale);\n };\n\n\n // get rid of the oscillator\n p5.Envelope.prototype.dispose = function() {\n // remove reference from soundArray\n var index = p5sound.soundArray.indexOf(this);\n p5sound.soundArray.splice(index, 1);\n\n this.disconnect();\n if (this.control) {\n this.control.dispose();\n this.control = null;\n }\n for (var i = 1; i < this.mathOps.length; i++) {\n this.mathOps[i].dispose();\n }\n };\n\n // Different name for backwards compatibility, replicates p5.Envelope class\n p5.Env = function(t1, l1, t2, l2, t3, l3) {\n console.warn('WARNING: p5.Env is now deprecated and may be removed in future versions. ' +\n 'Please use the new p5.Envelope instead.');\n p5.Envelope.call(this, t1, l1, t2, l2, t3, l3);\n };\n p5.Env.prototype = Object.create(p5.Envelope.prototype);\n\n});\n","'use strict';\n\ndefine(function (require) {\n\n var p5sound = require('master');\n require('oscillator');\n\n /**\n * Creates a Pulse object, an oscillator that implements\n * Pulse Width Modulation.\n * The pulse is created with two oscillators.\n * Accepts a parameter for frequency, and to set the\n * width between the pulses. See \n * p5.Oscillator for a full list of methods.\n *\n * @class p5.Pulse\n * @extends p5.Oscillator\n * @constructor\n * @param {Number} [freq] Frequency in oscillations per second (Hz)\n * @param {Number} [w] Width between the pulses (0 to 1.0,\n * defaults to 0)\n * @example\n *
Note: This uses the getUserMedia/\n * Stream API, which is not supported by certain browsers. Access in Chrome browser\n * is limited to localhost and https, but access over http may be limited.
\n *\n * @class p5.AudioIn\n * @constructor\n * @param {Function} [errorCallback] A function to call if there is an error\n * accessing the AudioIn. For example,\n * Safari and iOS devices do not\n * currently allow microphone access.\n * @example\n *
\n * var mic;\n * function setup(){\n * mic = new p5.AudioIn()\n * mic.start();\n * }\n * function draw(){\n * background(0);\n * micLevel = mic.getLevel();\n * ellipse(width/2, constrain(height-micLevel*height*5, 0, height), 10, 10);\n * }\n *
\n */\n p5.AudioIn = function(errorCallback) {\n // set up audio input\n /**\n * @property {GainNode} input\n */\n this.input = p5sound.audiocontext.createGain();\n /**\n * @property {GainNode} output\n */\n this.output = p5sound.audiocontext.createGain();\n\n /**\n * @property {MediaStream|null} stream\n */\n this.stream = null;\n /**\n * @property {MediaStreamAudioSourceNode|null} mediaStream\n */\n this.mediaStream = null;\n /**\n * @property {Number|null} currentSource\n */\n this.currentSource = null;\n\n /**\n * Client must allow browser to access their microphone / audioin source.\n * Default: false. Will become true when the client enables acces.\n *\n * @property {Boolean} enabled\n */\n this.enabled = false;\n\n /**\n * Input amplitude, connect to it by default but not to master out\n *\n * @property {p5.Amplitude} amplitude\n */\n this.amplitude = new p5.Amplitude();\n this.output.connect(this.amplitude.input);\n\n if (!window.MediaStreamTrack || !window.navigator.mediaDevices || !window.navigator.mediaDevices.getUserMedia) {\n errorCallback ? errorCallback() : window.alert('This browser does not support MediaStreamTrack and mediaDevices');\n }\n\n // add to soundArray so we can dispose on close\n p5sound.soundArray.push(this);\n };\n\n /**\n * Start processing audio input. This enables the use of other\n * AudioIn methods like getLevel(). Note that by default, AudioIn\n * is not connected to p5.sound's output. So you won't hear\n * anything unless you use the connect() method. \n *\n * Certain browsers limit access to the user's microphone. For example,\n * Chrome only allows access from localhost and over https. For this reason,\n * you may want to include an errorCallback—a function that is called in case\n * the browser won't provide mic access.\n *\n * @method start\n * @for p5.AudioIn\n * @param {Function} [successCallback] Name of a function to call on\n * success.\n * @param {Function} [errorCallback] Name of a function to call if\n * there was an error. For example,\n * some browsers do not support\n * getUserMedia.\n */\n p5.AudioIn.prototype.start = function(successCallback, errorCallback) {\n var self = this;\n\n if (this.stream) {\n this.stop();\n }\n\n // set the audio source\n var audioSource = p5sound.inputSources[self.currentSource];\n var constraints = {\n audio: {\n sampleRate: p5sound.audiocontext.sampleRate,\n echoCancellation: false\n }\n };\n\n // if developers determine which source to use\n if (p5sound.inputSources[this.currentSource]) {\n constraints.audio.deviceId = audioSource.deviceId;\n }\n\n window.navigator.mediaDevices.getUserMedia( constraints )\n .then( function(stream) {\n self.stream = stream;\n self.enabled = true;\n // Wrap a MediaStreamSourceNode around the live input\n self.mediaStream = p5sound.audiocontext.createMediaStreamSource(stream);\n self.mediaStream.connect(self.output);\n // only send to the Amplitude reader, so we can see it but not hear it.\n self.amplitude.setInput(self.output);\n if (successCallback) successCallback();\n })\n .catch( function(err) {\n if (errorCallback) errorCallback(err);\n else console.error(err);\n });\n };\n\n /**\n * Turn the AudioIn off. If the AudioIn is stopped, it cannot getLevel().\n * If re-starting, the user may be prompted for permission access.\n *\n * @method stop\n * @for p5.AudioIn\n */\n p5.AudioIn.prototype.stop = function() {\n if (this.stream) {\n this.stream.getTracks().forEach(function(track) {\n track.stop();\n });\n\n this.mediaStream.disconnect();\n\n delete this.mediaStream;\n delete this.stream;\n }\n };\n\n /**\n * Connect to an audio unit. If no parameter is provided, will\n * connect to the master output (i.e. your speakers). \n *\n * @method connect\n * @for p5.AudioIn\n * @param {Object} [unit] An object that accepts audio input,\n * such as an FFT\n */\n p5.AudioIn.prototype.connect = function(unit) {\n if (unit) {\n if (unit.hasOwnProperty('input')) {\n this.output.connect(unit.input);\n }\n else if (unit.hasOwnProperty('analyser')) {\n this.output.connect(unit.analyser);\n }\n else {\n this.output.connect(unit);\n }\n }\n else {\n this.output.connect(p5sound.input);\n }\n };\n\n /**\n * Disconnect the AudioIn from all audio units. For example, if\n * connect() had been called, disconnect() will stop sending\n * signal to your speakers. \n *\n * @method disconnect\n * @for p5.AudioIn\n */\n p5.AudioIn.prototype.disconnect = function() {\n if (this.output) {\n this.output.disconnect();\n // stay connected to amplitude even if not outputting to p5\n this.output.connect(this.amplitude.input);\n }\n };\n\n /**\n * Read the Amplitude (volume level) of an AudioIn. The AudioIn\n * class contains its own instance of the Amplitude class to help\n * make it easy to get a microphone's volume level. Accepts an\n * optional smoothing value (0.0 < 1.0). NOTE: AudioIn must\n * .start() before using .getLevel(). \n *\n * @method getLevel\n * @for p5.AudioIn\n * @param {Number} [smoothing] Smoothing is 0.0 by default.\n * Smooths values based on previous values.\n * @return {Number} Volume level (between 0.0 and 1.0)\n */\n p5.AudioIn.prototype.getLevel = function(smoothing) {\n if (smoothing) {\n this.amplitude.smoothing = smoothing;\n }\n return this.amplitude.getLevel();\n };\n\n /**\n * Set amplitude (volume) of a mic input between 0 and 1.0. \n *\n * @method amp\n * @for p5.AudioIn\n * @param {Number} vol between 0 and 1.0\n * @param {Number} [time] ramp time (optional)\n */\n p5.AudioIn.prototype.amp = function(vol, t) {\n if (t) {\n var rampTime = t || 0;\n var currentVol = this.output.gain.value;\n this.output.gain.cancelScheduledValues(p5sound.audiocontext.currentTime);\n this.output.gain.setValueAtTime(currentVol, p5sound.audiocontext.currentTime);\n this.output.gain.linearRampToValueAtTime(vol, rampTime + p5sound.audiocontext.currentTime);\n } else {\n this.output.gain.cancelScheduledValues(p5sound.audiocontext.currentTime);\n this.output.gain.setValueAtTime(vol, p5sound.audiocontext.currentTime);\n }\n };\n\n /**\n * Returns a list of available input sources. This is a wrapper\n * for and it returns a Promise.\n *\n * @method getSources\n * @for p5.AudioIn\n * @param {Function} [successCallback] This callback function handles the sources when they\n * have been enumerated. The callback function\n * receives the deviceList array as its only argument\n * @param {Function} [errorCallback] This optional callback receives the error\n * message as its argument.\n * @returns {Promise} Returns a Promise that can be used in place of the callbacks, similar\n * to the enumerateDevices() method\n * @example\n *
\n */\n p5.AudioIn.prototype.getSources = function (onSuccess, onError) {\n return new Promise( function(resolve, reject) {\n window.navigator.mediaDevices.enumerateDevices()\n .then( function(devices) {\n p5sound.inputSources = devices.filter(function(device) {\n return device.kind === 'audioinput';\n });\n resolve(p5sound.inputSources);\n if (onSuccess) {\n onSuccess(p5sound.inputSources);\n }\n })\n .catch( function(error) {\n reject(error);\n if (onError) {\n onError(error);\n } else {\n console.error('This browser does not support MediaStreamTrack.getSources()');\n }\n });\n });\n };\n\n /**\n * Set the input source. Accepts a number representing a\n * position in the array returned by getSources().\n * This is only available in browsers that support\n * navigator.mediaDevices.enumerateDevices(). \n *\n * @method setSource\n * @for p5.AudioIn\n * @param {number} num position of input source in the array\n */\n p5.AudioIn.prototype.setSource = function(num) {\n if (p5sound.inputSources.length > 0 && num < p5sound.inputSources.length) {\n // set the current source\n this.currentSource = num;\n console.log('set source to ', p5sound.inputSources[this.currentSource]);\n } else {\n console.log('unable to set input source');\n }\n\n // restart stream if currently active\n if (this.stream && this.stream.active) {\n this.start();\n }\n };\n\n // private method\n p5.AudioIn.prototype.dispose = function() {\n // remove reference from soundArray\n var index = p5sound.soundArray.indexOf(this);\n p5sound.soundArray.splice(index, 1);\n\n this.stop();\n\n if (this.output) {\n this.output.disconnect();\n }\n if (this.amplitude) {\n this.amplitude.disconnect();\n }\n delete this.amplitude;\n delete this.output;\n };\n\n});\n","define([\"Tone/core/Tone\", \"Tone/signal/Signal\", \"Tone/signal/Expr\", \n\t\"Tone/signal/EqualPowerGain\", \"Tone/core/Gain\"], function(Tone){\n\n\t\"use strict\";\n\n\t/**\n\t * @class Tone.Crossfade provides equal power fading between two inputs. \n\t * More on crossfading technique [here](https://en.wikipedia.org/wiki/Fade_(audio_engineering)#Crossfading).\n\t *\n\t * @constructor\n\t * @extends {Tone}\n\t * @param {NormalRange} [initialFade=0.5]\n\t * @example\n\t * var crossFade = new Tone.CrossFade(0.5);\n\t * //connect effect A to crossfade from\n\t * //effect output 0 to crossfade input 0\n\t * effectA.connect(crossFade, 0, 0);\n\t * //connect effect B to crossfade from\n\t * //effect output 0 to crossfade input 1\n\t * effectB.connect(crossFade, 0, 1);\n\t * crossFade.fade.value = 0;\n\t * // ^ only effectA is output\n\t * crossFade.fade.value = 1;\n\t * // ^ only effectB is output\n\t * crossFade.fade.value = 0.5;\n\t * // ^ the two signals are mixed equally. \n\t */\t\t\n\tTone.CrossFade = function(initialFade){\n\n\t\tthis.createInsOuts(2, 1);\n\n\t\t/**\n\t\t * Alias for input[0]. \n\t\t * @type {Tone.Gain}\n\t\t */\n\t\tthis.a = this.input[0] = new Tone.Gain();\n\n\t\t/**\n\t\t * Alias for input[1]. \n\t\t * @type {Tone.Gain}\n\t\t */\n\t\tthis.b = this.input[1] = new Tone.Gain();\n\n\t\t/**\n\t\t * \tThe mix between the two inputs. A fade value of 0\n\t\t * \twill output 100% input[0] and \n\t\t * \ta value of 1 will output 100% input[1]. \n\t\t * @type {NormalRange}\n\t\t * @signal\n\t\t */\n\t\tthis.fade = new Tone.Signal(this.defaultArg(initialFade, 0.5), Tone.Type.NormalRange);\n\n\t\t/**\n\t\t * equal power gain cross fade\n\t\t * @private\n\t\t * @type {Tone.EqualPowerGain}\n\t\t */\n\t\tthis._equalPowerA = new Tone.EqualPowerGain();\n\n\t\t/**\n\t\t * equal power gain cross fade\n\t\t * @private\n\t\t * @type {Tone.EqualPowerGain}\n\t\t */\n\t\tthis._equalPowerB = new Tone.EqualPowerGain();\n\t\t\n\t\t/**\n\t\t * invert the incoming signal\n\t\t * @private\n\t\t * @type {Tone}\n\t\t */\n\t\tthis._invert = new Tone.Expr(\"1 - $0\");\n\n\t\t//connections\n\t\tthis.a.connect(this.output);\n\t\tthis.b.connect(this.output);\n\t\tthis.fade.chain(this._equalPowerB, this.b.gain);\n\t\tthis.fade.chain(this._invert, this._equalPowerA, this.a.gain);\n\t\tthis._readOnly(\"fade\");\n\t};\n\n\tTone.extend(Tone.CrossFade);\n\n\t/**\n\t * clean up\n\t * @returns {Tone.CrossFade} this\n\t */\n\tTone.CrossFade.prototype.dispose = function(){\n\t\tTone.prototype.dispose.call(this);\n\t\tthis._writable(\"fade\");\n\t\tthis._equalPowerA.dispose();\n\t\tthis._equalPowerA = null;\n\t\tthis._equalPowerB.dispose();\n\t\tthis._equalPowerB = null;\n\t\tthis.fade.dispose();\n\t\tthis.fade = null;\n\t\tthis._invert.dispose();\n\t\tthis._invert = null;\n\t\tthis.a.dispose();\n\t\tthis.a = null;\n\t\tthis.b.dispose();\n\t\tthis.b = null;\n\t\treturn this;\n\t};\n\n\treturn Tone.CrossFade;\n});\n","define([\"Tone/core/Tone\", \"Tone/signal/Add\", \"Tone/signal/Subtract\", \"Tone/signal/Multiply\", \n\t\"Tone/signal/GreaterThan\", \"Tone/signal/GreaterThanZero\", \"Tone/signal/Abs\", \"Tone/signal/Negate\", \n\t\"Tone/signal/Modulo\", \"Tone/signal/Pow\", \"Tone/signal/AudioToGain\"], \n\tfunction(Tone){\n\n\t\"use strict\";\n\n\t/**\n\t * @class Evaluate an expression at audio rate.
\n\t * Parsing code modified from https://code.google.com/p/tapdigit/\n\t * Copyright 2011 2012 Ariya Hidayat, New BSD License\n\t *\n\t * @extends {Tone.SignalBase}\n\t * @constructor\n\t * @param {string} expr the expression to generate\n\t * @example\n\t * //adds the signals from input[0] and input[1].\n\t * var expr = new Tone.Expr(\"$0 + $1\");\n\t */\n\tTone.Expr = function(){\n\n\t\tvar expr = this._replacements(Array.prototype.slice.call(arguments));\n\t\tvar inputCount = this._parseInputs(expr);\n\n\t\t/**\n\t\t * hold onto all of the nodes for disposal\n\t\t * @type {Array}\n\t\t * @private\n\t\t */\n\t\tthis._nodes = [];\n\n\t\t/**\n\t\t * The inputs. The length is determined by the expression. \n\t\t * @type {Array}\n\t\t */\n\t\tthis.input = new Array(inputCount);\n\n\t\t//create a gain for each input\n\t\tfor (var i = 0; i < inputCount; i++){\n\t\t\tthis.input[i] = this.context.createGain();\n\t\t}\n\n\t\t//parse the syntax tree\n\t\tvar tree = this._parseTree(expr);\n\t\t//evaluate the results\n\t\tvar result;\n\t\ttry {\n\t\t\tresult = this._eval(tree);\n\t\t} catch (e){\n\t\t\tthis._disposeNodes();\n\t\t\tthrow new Error(\"Tone.Expr: Could evaluate expression: \"+expr);\n\t\t}\n\n\t\t/**\n\t\t * The output node is the result of the expression\n\t\t * @type {Tone}\n\t\t */\n\t\tthis.output = result;\n\t};\n\n\tTone.extend(Tone.Expr, Tone.SignalBase);\n\n\t//some helpers to cut down the amount of code\n\tfunction applyBinary(Constructor, args, self){\n\t\tvar op = new Constructor();\n\t\tself._eval(args[0]).connect(op, 0, 0);\n\t\tself._eval(args[1]).connect(op, 0, 1);\n\t\treturn op;\n\t}\n\tfunction applyUnary(Constructor, args, self){\n\t\tvar op = new Constructor();\n\t\tself._eval(args[0]).connect(op, 0, 0);\n\t\treturn op;\n\t}\n\tfunction getNumber(arg){\n\t\treturn arg ? parseFloat(arg) : undefined;\n\t}\n\tfunction literalNumber(arg){\n\t\treturn arg && arg.args ? parseFloat(arg.args) : undefined;\n\t}\n\n\t/*\n\t * the Expressions that Tone.Expr can parse.\n\t *\n\t * each expression belongs to a group and contains a regexp \n\t * for selecting the operator as well as that operators method\n\t * \n\t * @type {Object}\n\t * @private\n\t */\n\tTone.Expr._Expressions = {\n\t\t//values\n\t\t\"value\" : {\n\t\t\t\"signal\" : {\n\t\t\t\tregexp : /^\\d+\\.\\d+|^\\d+/,\n\t\t\t\tmethod : function(arg){\n\t\t\t\t\tvar sig = new Tone.Signal(getNumber(arg));\n\t\t\t\t\treturn sig;\n\t\t\t\t}\n\t\t\t},\n\t\t\t\"input\" : {\n\t\t\t\tregexp : /^\\$\\d/,\n\t\t\t\tmethod : function(arg, self){\n\t\t\t\t\treturn self.input[getNumber(arg.substr(1))];\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\t\t//syntactic glue\n\t\t\"glue\" : {\n\t\t\t\"(\" : {\n\t\t\t\tregexp : /^\\(/,\n\t\t\t},\n\t\t\t\")\" : {\n\t\t\t\tregexp : /^\\)/,\n\t\t\t},\n\t\t\t\",\" : {\n\t\t\t\tregexp : /^,/,\n\t\t\t}\n\t\t},\n\t\t//functions\n\t\t\"func\" : {\n\t\t\t\"abs\" : {\n\t\t\t\tregexp : /^abs/,\n\t\t\t\tmethod : applyUnary.bind(this, Tone.Abs)\n\t\t\t},\n\t\t\t\"mod\" : {\n\t\t\t\tregexp : /^mod/,\n\t\t\t\tmethod : function(args, self){\n\t\t\t\t\tvar modulus = literalNumber(args[1]);\n\t\t\t\t\tvar op = new Tone.Modulo(modulus);\n\t\t\t\t\tself._eval(args[0]).connect(op);\n\t\t\t\t\treturn op;\n\t\t\t\t}\n\t\t\t},\n\t\t\t\"pow\" : {\n\t\t\t\tregexp : /^pow/,\n\t\t\t\tmethod : function(args, self){\n\t\t\t\t\tvar exp = literalNumber(args[1]);\n\t\t\t\t\tvar op = new Tone.Pow(exp);\n\t\t\t\t\tself._eval(args[0]).connect(op);\n\t\t\t\t\treturn op;\n\t\t\t\t}\n\t\t\t},\n\t\t\t\"a2g\" : {\n\t\t\t\tregexp : /^a2g/,\n\t\t\t\tmethod : function(args, self){\n\t\t\t\t\tvar op = new Tone.AudioToGain();\n\t\t\t\t\tself._eval(args[0]).connect(op);\n\t\t\t\t\treturn op;\n\t\t\t\t}\n\t\t\t},\n\t\t},\n\t\t//binary expressions\n\t\t\"binary\" : {\n\t\t\t\"+\" : {\n\t\t\t\tregexp : /^\\+/,\n\t\t\t\tprecedence : 1,\n\t\t\t\tmethod : applyBinary.bind(this, Tone.Add)\n\t\t\t},\n\t\t\t\"-\" : {\n\t\t\t\tregexp : /^\\-/,\n\t\t\t\tprecedence : 1,\n\t\t\t\tmethod : function(args, self){\n\t\t\t\t\t//both unary and binary op\n\t\t\t\t\tif (args.length === 1){\n\t\t\t\t\t\treturn applyUnary(Tone.Negate, args, self);\n\t\t\t\t\t} else {\n\t\t\t\t\t\treturn applyBinary(Tone.Subtract, args, self);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t},\n\t\t\t\"*\" : {\n\t\t\t\tregexp : /^\\*/,\n\t\t\t\tprecedence : 0,\n\t\t\t\tmethod : applyBinary.bind(this, Tone.Multiply)\n\t\t\t}\n\t\t},\n\t\t//unary expressions\n\t\t\"unary\" : {\n\t\t\t\"-\" : {\n\t\t\t\tregexp : /^\\-/,\n\t\t\t\tmethod : applyUnary.bind(this, Tone.Negate)\n\t\t\t},\n\t\t\t\"!\" : {\n\t\t\t\tregexp : /^\\!/,\n\t\t\t\tmethod : applyUnary.bind(this, Tone.NOT)\n\t\t\t},\n\t\t},\n\t};\n\t\t\n\t/**\n\t * @param {string} expr the expression string\n\t * @return {number} the input count\n\t * @private\n\t */\n\tTone.Expr.prototype._parseInputs = function(expr){\n\t\tvar inputArray = expr.match(/\\$\\d/g);\n\t\tvar inputMax = 0;\n\t\tif (inputArray !== null){\n\t\t\tfor (var i = 0; i < inputArray.length; i++){\n\t\t\t\tvar inputNum = parseInt(inputArray[i].substr(1)) + 1;\n\t\t\t\tinputMax = Math.max(inputMax, inputNum);\n\t\t\t}\n\t\t}\n\t\treturn inputMax;\n\t};\n\n\t/**\n\t * @param {Array} args \tan array of arguments\n\t * @return {string} the results of the replacements being replaced\n\t * @private\n\t */\n\tTone.Expr.prototype._replacements = function(args){\n\t\tvar expr = args.shift();\n\t\tfor (var i = 0; i < args.length; i++){\n\t\t\texpr = expr.replace(/\\%/i, args[i]);\n\t\t}\n\t\treturn expr;\n\t};\n\n\t/**\n\t * tokenize the expression based on the Expressions object\n\t * @param {string} expr \n\t * @return {Object} returns two methods on the tokenized list, next and peek\n\t * @private\n\t */\n\tTone.Expr.prototype._tokenize = function(expr){\n\t\tvar position = -1;\n\t\tvar tokens = [];\n\n\t\twhile(expr.length > 0){\n\t\t\texpr = expr.trim();\n\t\t\tvar token = getNextToken(expr);\n\t\t\ttokens.push(token);\n\t\t\texpr = expr.substr(token.value.length);\n\t\t}\n\n\t\tfunction getNextToken(expr){\n\t\t\tfor (var type in Tone.Expr._Expressions){\n\t\t\t\tvar group = Tone.Expr._Expressions[type];\n\t\t\t\tfor (var opName in group){\n\t\t\t\t\tvar op = group[opName];\n\t\t\t\t\tvar reg = op.regexp;\n\t\t\t\t\tvar match = expr.match(reg);\n\t\t\t\t\tif (match !== null){\n\t\t\t\t\t\treturn {\n\t\t\t\t\t\t\ttype : type,\n\t\t\t\t\t\t\tvalue : match[0],\n\t\t\t\t\t\t\tmethod : op.method\n\t\t\t\t\t\t};\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\tthrow new SyntaxError(\"Tone.Expr: Unexpected token \"+expr);\n\t\t}\n\n\t\treturn {\n\t\t\tnext : function(){\n\t\t\t\treturn tokens[++position];\n\t\t\t},\n\t\t\tpeek : function(){\n\t\t\t\treturn tokens[position + 1];\n\t\t\t}\n\t\t};\n\t};\n\n\t/**\n\t * recursively parse the string expression into a syntax tree\n\t * \n\t * @param {string} expr \n\t * @return {Object}\n\t * @private\n\t */\n\tTone.Expr.prototype._parseTree = function(expr){\n\t\tvar lexer = this._tokenize(expr);\n\t\tvar isUndef = this.isUndef.bind(this);\n\n\t\tfunction matchSyntax(token, syn) {\n\t\t\treturn !isUndef(token) && \n\t\t\t\ttoken.type === \"glue\" &&\n\t\t\t\ttoken.value === syn;\n\t\t}\n\n\t\tfunction matchGroup(token, groupName, prec) {\n\t\t\tvar ret = false;\n\t\t\tvar group = Tone.Expr._Expressions[groupName];\n\t\t\tif (!isUndef(token)){\n\t\t\t\tfor (var opName in group){\n\t\t\t\t\tvar op = group[opName];\n\t\t\t\t\tif (op.regexp.test(token.value)){\n\t\t\t\t\t\tif (!isUndef(prec)){\n\t\t\t\t\t\t\tif(op.precedence === prec){\t\n\t\t\t\t\t\t\t\treturn true;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\treturn true;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn ret;\n\t\t}\n\n\t\tfunction parseExpression(precedence) {\n\t\t\tif (isUndef(precedence)){\n\t\t\t\tprecedence = 5;\n\t\t\t}\n\t\t\tvar expr;\n\t\t\tif (precedence < 0){\n\t\t\t\texpr = parseUnary();\n\t\t\t} else {\n\t\t\t\texpr = parseExpression(precedence-1);\n\t\t\t}\n\t\t\tvar token = lexer.peek();\n\t\t\twhile (matchGroup(token, \"binary\", precedence)) {\n\t\t\t\ttoken = lexer.next();\n\t\t\t\texpr = {\n\t\t\t\t\toperator: token.value,\n\t\t\t\t\tmethod : token.method,\n\t\t\t\t\targs : [\n\t\t\t\t\t\texpr,\n\t\t\t\t\t\tparseExpression(precedence-1)\n\t\t\t\t\t]\n\t\t\t\t};\n\t\t\t\ttoken = lexer.peek();\n\t\t\t}\n\t\t\treturn expr;\n\t\t}\n\n\t\tfunction parseUnary() {\n\t\t\tvar token, expr;\n\t\t\ttoken = lexer.peek();\n\t\t\tif (matchGroup(token, \"unary\")) {\n\t\t\t\ttoken = lexer.next();\n\t\t\t\texpr = parseUnary();\n\t\t\t\treturn {\n\t\t\t\t\toperator: token.value,\n\t\t\t\t\tmethod : token.method,\n\t\t\t\t\targs : [expr]\n\t\t\t\t};\n\t\t\t}\n\t\t\treturn parsePrimary();\n\t\t}\n\n\t\tfunction parsePrimary() {\n\t\t\tvar token, expr;\n\t\t\ttoken = lexer.peek();\n\t\t\tif (isUndef(token)) {\n\t\t\t\tthrow new SyntaxError(\"Tone.Expr: Unexpected termination of expression\");\n\t\t\t}\n\t\t\tif (token.type === \"func\") {\n\t\t\t\ttoken = lexer.next();\n\t\t\t\treturn parseFunctionCall(token);\n\t\t\t}\n\t\t\tif (token.type === \"value\") {\n\t\t\t\ttoken = lexer.next();\n\t\t\t\treturn {\n\t\t\t\t\tmethod : token.method,\n\t\t\t\t\targs : token.value\n\t\t\t\t};\n\t\t\t}\n\t\t\tif (matchSyntax(token, \"(\")) {\n\t\t\t\tlexer.next();\n\t\t\t\texpr = parseExpression();\n\t\t\t\ttoken = lexer.next();\n\t\t\t\tif (!matchSyntax(token, \")\")) {\n\t\t\t\t\tthrow new SyntaxError(\"Expected )\");\n\t\t\t\t}\n\t\t\t\treturn expr;\n\t\t\t}\n\t\t\tthrow new SyntaxError(\"Tone.Expr: Parse error, cannot process token \" + token.value);\n\t\t}\n\n\t\tfunction parseFunctionCall(func) {\n\t\t\tvar token, args = [];\n\t\t\ttoken = lexer.next();\n\t\t\tif (!matchSyntax(token, \"(\")) {\n\t\t\t\tthrow new SyntaxError(\"Tone.Expr: Expected ( in a function call \\\"\" + func.value + \"\\\"\");\n\t\t\t}\n\t\t\ttoken = lexer.peek();\n\t\t\tif (!matchSyntax(token, \")\")) {\n\t\t\t\targs = parseArgumentList();\n\t\t\t}\n\t\t\ttoken = lexer.next();\n\t\t\tif (!matchSyntax(token, \")\")) {\n\t\t\t\tthrow new SyntaxError(\"Tone.Expr: Expected ) in a function call \\\"\" + func.value + \"\\\"\");\n\t\t\t}\n\t\t\treturn {\n\t\t\t\tmethod : func.method,\n\t\t\t\targs : args,\n\t\t\t\tname : name\n\t\t\t};\n\t\t}\n\n\t\tfunction parseArgumentList() {\n\t\t\tvar token, expr, args = [];\n\t\t\twhile (true) {\n\t\t\t\texpr = parseExpression();\n\t\t\t\tif (isUndef(expr)) {\n\t\t\t\t\t// TODO maybe throw exception?\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\targs.push(expr);\n\t\t\t\ttoken = lexer.peek();\n\t\t\t\tif (!matchSyntax(token, \",\")) {\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tlexer.next();\n\t\t\t}\n\t\t\treturn args;\n\t\t}\n\n\t\treturn parseExpression();\n\t};\n\n\t/**\n\t * recursively evaluate the expression tree\n\t * @param {Object} tree \n\t * @return {AudioNode} the resulting audio node from the expression\n\t * @private\n\t */\n\tTone.Expr.prototype._eval = function(tree){\n\t\tif (!this.isUndef(tree)){\n\t\t\tvar node = tree.method(tree.args, this);\n\t\t\tthis._nodes.push(node);\n\t\t\treturn node;\n\t\t} \n\t};\n\n\t/**\n\t * dispose all the nodes\n\t * @private\n\t */\n\tTone.Expr.prototype._disposeNodes = function(){\n\t\tfor (var i = 0; i < this._nodes.length; i++){\n\t\t\tvar node = this._nodes[i];\n\t\t\tif (this.isFunction(node.dispose)) {\n\t\t\t\tnode.dispose();\n\t\t\t} else if (this.isFunction(node.disconnect)) {\n\t\t\t\tnode.disconnect();\n\t\t\t}\n\t\t\tnode = null;\n\t\t\tthis._nodes[i] = null;\n\t\t}\n\t\tthis._nodes = null;\n\t};\n\n\t/**\n\t * clean up\n\t */\n\tTone.Expr.prototype.dispose = function(){\n\t\tTone.prototype.dispose.call(this);\n\t\tthis._disposeNodes();\n\t};\n\n\treturn Tone.Expr;\n});","define([\"Tone/core/Tone\", \"Tone/signal/GreaterThanZero\", \"Tone/signal/Subtract\", \"Tone/signal/Signal\"], \n\tfunction(Tone){\n\n\t\"use strict\";\n\n\t/**\n\t * @class Output 1 if the signal is greater than the value, otherwise outputs 0.\n\t * can compare two signals or a signal and a number. \n\t * \n\t * @constructor\n\t * @extends {Tone.Signal}\n\t * @param {number} [value=0] the value to compare to the incoming signal\n\t * @example\n\t * var gt = new Tone.GreaterThan(2);\n\t * var sig = new Tone.Signal(4).connect(gt);\n\t * //output of gt is equal 1. \n\t */\n\tTone.GreaterThan = function(value){\n\n\t\tthis.createInsOuts(2, 0);\n\t\t\n\t\t/**\n\t\t * subtract the amount from the incoming signal\n\t\t * @type {Tone.Subtract}\n\t\t * @private\n\t\t */\n\t\tthis._param = this.input[0] = new Tone.Subtract(value);\n\t\tthis.input[1] = this._param.input[1];\n\n\t\t/**\n\t\t * compare that amount to zero\n\t\t * @type {Tone.GreaterThanZero}\n\t\t * @private\n\t\t */\n\t\tthis._gtz = this.output = new Tone.GreaterThanZero();\n\n\t\t//connect\n\t\tthis._param.connect(this._gtz);\n\t};\n\n\tTone.extend(Tone.GreaterThan, Tone.Signal);\n\n\t/**\n\t * dispose method\n\t * @returns {Tone.GreaterThan} this\n\t */\n\tTone.GreaterThan.prototype.dispose = function(){\n\t\tTone.prototype.dispose.call(this);\n\t\tthis._param.dispose();\n\t\tthis._param = null;\n\t\tthis._gtz.dispose();\n\t\tthis._gtz = null;\n\t\treturn this;\n\t};\n\n\treturn Tone.GreaterThan;\n});","define([\"Tone/core/Tone\", \"Tone/signal/WaveShaper\", \"Tone/signal/SignalBase\"], \nfunction(Tone){\n\n\t\"use strict\";\n\n\t/**\n\t * @class Return the absolute value of an incoming signal. \n\t * \n\t * @constructor\n\t * @extends {Tone.SignalBase}\n\t * @example\n\t * var signal = new Tone.Signal(-1);\n\t * var abs = new Tone.Abs();\n\t * signal.connect(abs);\n\t * //the output of abs is 1. \n\t */\n\tTone.Abs = function(){\n\t\t/**\n\t\t * @type {Tone.LessThan}\n\t\t * @private\n\t\t */\n\t\tthis._abs = this.input = this.output = new Tone.WaveShaper(function(val){\n\t\t\tif (val === 0){\n\t\t\t\treturn 0;\n\t\t\t} else {\n\t\t\t\treturn Math.abs(val);\n\t\t\t}\n\t\t}, 127);\n\t};\n\n\tTone.extend(Tone.Abs, Tone.SignalBase);\n\n\t/**\n\t * dispose method\n\t * @returns {Tone.Abs} this\n\t */\n\tTone.Abs.prototype.dispose = function(){\n\t\tTone.prototype.dispose.call(this);\n\t\tthis._abs.dispose();\n\t\tthis._abs = null;\n\t\treturn this;\n\t}; \n\n\treturn Tone.Abs;\n});","define([\"Tone/core/Tone\", \"Tone/signal/WaveShaper\", \"Tone/signal/Multiply\", \"Tone/signal/Subtract\"], \nfunction(Tone){\n\n\t\"use strict\";\n\n\t/**\n\t * @class Signal-rate modulo operator. Only works in AudioRange [-1, 1] and for modulus\n\t * values in the NormalRange. \n\t *\n\t * @constructor\n\t * @extends {Tone.SignalBase}\n\t * @param {NormalRange} modulus The modulus to apply.\n\t * @example\n\t * var mod = new Tone.Modulo(0.2)\n\t * var sig = new Tone.Signal(0.5).connect(mod);\n\t * //mod outputs 0.1\n\t */\n\tTone.Modulo = function(modulus){\n\n\t\tthis.createInsOuts(1, 0);\n\n\t\t/**\n\t\t * A waveshaper gets the integer multiple of \n\t\t * the input signal and the modulus.\n\t\t * @private\n\t\t * @type {Tone.WaveShaper}\n\t\t */\n\t\tthis._shaper = new Tone.WaveShaper(Math.pow(2, 16));\n\n\t\t/**\n\t\t * the integer multiple is multiplied by the modulus\n\t\t * @type {Tone.Multiply}\n\t\t * @private\n\t\t */\n\t\tthis._multiply = new Tone.Multiply();\n\n\t\t/**\n\t\t * and subtracted from the input signal\n\t\t * @type {Tone.Subtract}\n\t\t * @private\n\t\t */\n\t\tthis._subtract = this.output = new Tone.Subtract();\n\n\t\t/**\n\t\t * the modulus signal\n\t\t * @type {Tone.Signal}\n\t\t * @private\n\t\t */\n\t\tthis._modSignal = new Tone.Signal(modulus);\n\n\t\t//connections\n\t\tthis.input.fan(this._shaper, this._subtract);\n\t\tthis._modSignal.connect(this._multiply, 0, 0);\n\t\tthis._shaper.connect(this._multiply, 0, 1);\n\t\tthis._multiply.connect(this._subtract, 0, 1);\n\t\tthis._setWaveShaper(modulus);\n\t};\n\n\tTone.extend(Tone.Modulo, Tone.SignalBase);\n\n\t/**\n\t * @param {number} mod the modulus to apply\n\t * @private\n\t */\n\tTone.Modulo.prototype._setWaveShaper = function(mod){\n\t\tthis._shaper.setMap(function(val){\n\t\t\tvar multiple = Math.floor((val + 0.0001) / mod);\n\t\t\treturn multiple;\n\t\t});\n\t};\n\n\t/**\n\t * The modulus value.\n\t * @memberOf Tone.Modulo#\n\t * @type {NormalRange}\n\t * @name value\n\t */\n\tObject.defineProperty(Tone.Modulo.prototype, \"value\", {\n\t\tget : function(){\n\t\t\treturn this._modSignal.value;\n\t\t},\n\t\tset : function(mod){\n\t\t\tthis._modSignal.value = mod;\n\t\t\tthis._setWaveShaper(mod);\n\t\t}\n\t});\n\n\t/**\n\t * clean up\n\t * @returns {Tone.Modulo} this\n\t */\n\tTone.Modulo.prototype.dispose = function(){\n\t\tTone.prototype.dispose.call(this);\n\t\tthis._shaper.dispose();\n\t\tthis._shaper = null;\n\t\tthis._multiply.dispose();\n\t\tthis._multiply = null;\n\t\tthis._subtract.dispose();\n\t\tthis._subtract = null;\n\t\tthis._modSignal.dispose();\n\t\tthis._modSignal = null;\n\t\treturn this;\n\t};\n\n\treturn Tone.Modulo;\n});","define([\"Tone/core/Tone\", \"Tone/signal/WaveShaper\"], function(Tone){\n\n\t\"use strict\";\n\n\t/**\n\t * @class Pow applies an exponent to the incoming signal. The incoming signal\n\t * must be AudioRange.\n\t *\n\t * @extends {Tone.SignalBase}\n\t * @constructor\n\t * @param {Positive} exp The exponent to apply to the incoming signal, must be at least 2. \n\t * @example\n\t * var pow = new Tone.Pow(2);\n\t * var sig = new Tone.Signal(0.5).connect(pow);\n\t * //output of pow is 0.25. \n\t */\n\tTone.Pow = function(exp){\n\n\t\t/**\n\t\t * the exponent\n\t\t * @private\n\t\t * @type {number}\n\t\t */\n\t\tthis._exp = this.defaultArg(exp, 1);\n\n\t\t/**\n\t\t * @type {WaveShaperNode}\n\t\t * @private\n\t\t */\n\t\tthis._expScaler = this.input = this.output = new Tone.WaveShaper(this._expFunc(this._exp), 8192);\n\t};\n\n\tTone.extend(Tone.Pow, Tone.SignalBase);\n\n\t/**\n\t * The value of the exponent.\n\t * @memberOf Tone.Pow#\n\t * @type {number}\n\t * @name value\n\t */\n\tObject.defineProperty(Tone.Pow.prototype, \"value\", {\n\t\tget : function(){\n\t\t\treturn this._exp;\n\t\t},\n\t\tset : function(exp){\n\t\t\tthis._exp = exp;\n\t\t\tthis._expScaler.setMap(this._expFunc(this._exp));\n\t\t}\n\t});\n\n\n\t/**\n\t * the function which maps the waveshaper\n\t * @param {number} exp\n\t * @return {function}\n\t * @private\n\t */\n\tTone.Pow.prototype._expFunc = function(exp){\n\t\treturn function(val){\n\t\t\treturn Math.pow(Math.abs(val), exp);\n\t\t};\n\t};\n\n\t/**\n\t * Clean up.\n\t * @returns {Tone.Pow} this\n\t */\n\tTone.Pow.prototype.dispose = function(){\n\t\tTone.prototype.dispose.call(this);\n\t\tthis._expScaler.dispose();\n\t\tthis._expScaler = null;\n\t\treturn this;\n\t};\n\n\treturn Tone.Pow;\n});","define([\"Tone/core/Tone\", \"Tone/signal/WaveShaper\", \"Tone/signal/Signal\"], function(Tone){\n\n\t\"use strict\";\n\n\t/**\n\t * @class AudioToGain converts an input in AudioRange [-1,1] to NormalRange [0,1]. \n\t * See Tone.GainToAudio.\n\t *\n\t * @extends {Tone.SignalBase}\n\t * @constructor\n\t * @example\n\t * var a2g = new Tone.AudioToGain();\n\t */\n\tTone.AudioToGain = function(){\n\n\t\t/**\n\t\t * @type {WaveShaperNode}\n\t\t * @private\n\t\t */\n\t\tthis._norm = this.input = this.output = new Tone.WaveShaper(function(x){\n\t\t\treturn (x + 1) / 2;\n\t\t});\n\t};\n\n\tTone.extend(Tone.AudioToGain, Tone.SignalBase);\n\n\t/**\n\t * clean up\n\t * @returns {Tone.AudioToGain} this\n\t */\n\tTone.AudioToGain.prototype.dispose = function(){\n\t\tTone.prototype.dispose.call(this);\n\t\tthis._norm.dispose();\n\t\tthis._norm = null;\n\t\treturn this;\n\t};\n\n\treturn Tone.AudioToGain;\n});","define([\"Tone/core/Tone\", \"Tone/signal/WaveShaper\"], function(Tone){\n\n\t\"use strict\";\n\n\t/**\n\t * @class Convert an incoming signal between 0, 1 to an equal power gain scale.\n\t *\n\t * @extends {Tone.SignalBase}\n\t * @constructor\n\t * @example\n\t * var eqPowGain = new Tone.EqualPowerGain();\n\t */\n\tTone.EqualPowerGain = function(){\n\n\t\t/**\n\t\t * @type {Tone.WaveShaper}\n\t\t * @private\n\t\t */\n\t\tthis._eqPower = this.input = this.output = new Tone.WaveShaper(function(val){\n\t\t\tif (Math.abs(val) < 0.001){\n\t\t\t\t//should output 0 when input is 0\n\t\t\t\treturn 0;\n\t\t\t} else {\n\t\t\t\treturn this.equalPowerScale(val);\n\t\t\t}\n\t\t}.bind(this), 4096);\n\t};\n\n\tTone.extend(Tone.EqualPowerGain, Tone.SignalBase);\n\n\t/**\n\t * clean up\n\t * @returns {Tone.EqualPowerGain} this\n\t */\n\tTone.EqualPowerGain.prototype.dispose = function(){\n\t\tTone.prototype.dispose.call(this);\n\t\tthis._eqPower.dispose();\n\t\tthis._eqPower = null;\n\t\treturn this;\n\t};\n\n\treturn Tone.EqualPowerGain;\n});","'use strict';\n\ndefine(function (require) {\n\n var Effect = require('effect');\n var EQFilter = require('eqFilter');\n\n /**\n * p5.EQ is an audio effect that performs the function of a multiband\n * audio equalizer. Equalization is used to adjust the balance of\n * frequency compoenents of an audio signal. This process is commonly used\n * in sound production and recording to change the waveform before it reaches\n * a sound output device. EQ can also be used as an audio effect to create\n * interesting distortions by filtering out parts of the spectrum. p5.EQ is\n * built using a chain of Web Audio Biquad Filter Nodes and can be\n * instantiated with 3 or 8 bands. Bands can be added or removed from\n * the EQ by directly modifying p5.EQ.bands (the array that stores filters).\n *\n * This class extends p5.Effect.\n * Methods amp(), chain(),\n * drywet(), connect(), and\n * disconnect() are available.\n *\n * @class p5.EQ\n * @constructor\n * @extends p5.Effect\n * @param {Number} [_eqsize] Constructor will accept 3 or 8, defaults to 3\n * @return {Object} p5.EQ object\n *\n * @example\n *
\n * var eq;\n * var band_names;\n * var band_index;\n *\n * var soundFile, play;\n *\n * function preload() {\n * soundFormats('mp3', 'ogg');\n * soundFile = loadSound('assets/beat');\n * }\n *\n * function setup() {\n * eq = new p5.EQ(3);\n * soundFile.disconnect();\n * eq.process(soundFile);\n *\n * band_names = ['lows','mids','highs'];\n * band_index = 0;\n * play = false;\n * textAlign(CENTER);\n * }\n *\n * function draw() {\n * background(30);\n * noStroke();\n * fill(255);\n * text('click to kill',50,25);\n *\n * fill(255, 40, 255);\n * textSize(26);\n * text(band_names[band_index],50,55);\n *\n * fill(255);\n * textSize(9);\n * text('space = play/pause',50,80);\n * }\n *\n * //If mouse is over canvas, cycle to the next band and kill the frequency\n * function mouseClicked() {\n * for (var i = 0; i < eq.bands.length; i++) {\n * eq.bands[i].gain(0);\n * }\n * eq.bands[band_index].gain(-40);\n * if (mouseX > 0 && mouseX < width && mouseY < height && mouseY > 0) {\n * band_index === 2 ? band_index = 0 : band_index++;\n * }\n * }\n *\n * //use space bar to trigger play / pause\n * function keyPressed() {\n * if (key===' ') {\n * play = !play\n * play ? soundFile.loop() : soundFile.pause();\n * }\n * }\n *
\n */\n p5.EQ = function(_eqsize) {\n Effect.call(this);\n\n //p5.EQ can be of size (3) or (8), defaults to 3\n _eqsize = _eqsize === 3 || _eqsize === 8 ? _eqsize : 3;\n\n var factor;\n _eqsize === 3 ? factor = Math.pow(2,3) : factor = 2;\n\n /**\n * The p5.EQ is built with abstracted p5.Filter objects.\n * To modify any bands, use methods of the \n * p5.Filter API, especially `gain` and `freq`.\n * Bands are stored in an array, with indices 0 - 3, or 0 - 7\n * @property {Array} bands\n *\n */\n this.bands = [];\n\n\n var freq, res;\n for (var i = 0; i < _eqsize; i++) {\n if (i === _eqsize - 1) {\n freq = 21000;\n res = .01;\n } else if (i === 0) {\n freq = 100;\n res = .1;\n }\n else if (i===1) {\n freq = _eqsize === 3 ? 360 * factor : 360;\n res = 1;\n }else {\n freq = this.bands[i-1].freq() * factor;\n res = 1;\n }\n this.bands[i] = this._newBand(freq, res);\n\n if (i>0) {\n this.bands[i-1].connect(this.bands[i].biquad);\n } else {\n this.input.connect(this.bands[i].biquad);\n }\n }\n this.bands[_eqsize-1].connect(this.output);\n };\n p5.EQ.prototype = Object.create(Effect.prototype);\n\n /**\n * Process an input by connecting it to the EQ\n * @method process\n * @param {Object} src Audio source\n */\n p5.EQ.prototype.process = function (src) {\n src.connect(this.input);\n };\n\n // /**\n // * Set the frequency and gain of each band in the EQ. This method should be\n // * called with 3 or 8 frequency and gain pairs, depending on the size of the EQ.\n // * ex. eq.set(freq0, gain0, freq1, gain1, freq2, gain2);\n // *\n // * @method set\n // * @for p5.EQ\n // * @param {Number} [freq0] Frequency value for band with index 0\n // * @param {Number} [gain0] Gain value for band with index 0\n // * @param {Number} [freq1] Frequency value for band with index 1\n // * @param {Number} [gain1] Gain value for band with index 1\n // * @param {Number} [freq2] Frequency value for band with index 2\n // * @param {Number} [gain2] Gain value for band with index 2\n // * @param {Number} [freq3] Frequency value for band with index 3\n // * @param {Number} [gain3] Gain value for band with index 3\n // * @param {Number} [freq4] Frequency value for band with index 4\n // * @param {Number} [gain4] Gain value for band with index 4\n // * @param {Number} [freq5] Frequency value for band with index 5\n // * @param {Number} [gain5] Gain value for band with index 5\n // * @param {Number} [freq6] Frequency value for band with index 6\n // * @param {Number} [gain6] Gain value for band with index 6\n // * @param {Number} [freq7] Frequency value for band with index 7\n // * @param {Number} [gain7] Gain value for band with index 7\n // */\n p5.EQ.prototype.set = function() {\n if (arguments.length === this.bands.length * 2) {\n for (var i = 0; i < arguments.length; i+=2) {\n this.bands[i/2].freq(arguments[i]);\n this.bands[i/2].gain(arguments[i+1]);\n }\n }\n else {\n console.error('Argument mismatch. .set() should be called with ' + this.bands.length*2 +\n ' arguments. (one frequency and gain value pair for each band of the eq)');\n }\n };\n\n /**\n * Add a new band. Creates a p5.Filter and strips away everything but\n * the raw biquad filter. This method returns an abstracted p5.Filter,\n * which can be added to p5.EQ.bands, in order to create new EQ bands.\n * @private\n * @for p5.EQ\n * @method _newBand\n * @param {Number} freq\n * @param {Number} res\n * @return {Object} Abstracted Filter\n */\n p5.EQ.prototype._newBand = function(freq, res) {\n return new EQFilter(freq, res);\n };\n\n p5.EQ.prototype.dispose = function () {\n Effect.prototype.dispose.apply(this);\n\n if (this.bands) {\n while (this.bands.length > 0) {\n delete this.bands.pop().dispose();\n }\n delete this.bands;\n }\n };\n\n return p5.EQ;\n});\n","'use strict';\n\ndefine(function (require) {\n var Filter = require('filter');\n var p5sound = require('master');\n\n /**\n * EQFilter extends p5.Filter with constraints\n * necessary for the p5.EQ\n *\n * @private\n */\n var EQFilter = function(freq, res) {\n Filter.call(this, 'peaking');\n this.disconnect();\n this.set(freq, res);\n this.biquad.gain.value = 0;\n delete this.input;\n delete this.output;\n delete this._drywet;\n delete this.wet;\n\n };\n EQFilter.prototype = Object.create(Filter.prototype);\n\n EQFilter.prototype.amp = function() {\n console.warn('`amp()` is not available for p5.EQ bands. Use `.gain()`');\n };\n EQFilter.prototype.drywet = function() {\n console.warn('`drywet()` is not available for p5.EQ bands.');\n };\n EQFilter.prototype.connect = function(unit) {\n var u = unit || p5.soundOut.input;\n if (this.biquad) {\n this.biquad.connect(u.input ? u.input : u);\n } else {\n this.output.connect(u.input ? u.input : u);\n }\n };\n\n EQFilter.prototype.disconnect = function() {\n if (this.biquad) {\n this.biquad.disconnect();\n }\n };\n EQFilter.prototype.dispose = function() {\n // remove reference form soundArray\n var index = p5sound.soundArray.indexOf(this);\n p5sound.soundArray.splice(index, 1);\n this.disconnect();\n delete this.biquad;\n };\n\n return EQFilter;\n});\n","'use strict'\n\ndefine(function (require) {\n var p5sound = require('master');\n var Effect = require('effect');\n\n /**\n * Panner3D is based on the \n * Web Audio Spatial Panner Node.\n * This panner is a spatial processing node that allows audio to be positioned\n * and oriented in 3D space.\n *\n * The position is relative to an \n * Audio Context Listener, which can be accessed\n * by p5.soundOut.audiocontext.listener\n *\n *\n * @class p5.Panner3D\n * @constructor\n */\n\tp5.Panner3D = function() {\n Effect.call(this);\n\n /**\n * \n * Web Audio Spatial Panner Node\n *\n * Properties include\n * - panningModel: \"equal power\" or \"HRTF\"\n * - distanceModel: \"linear\", \"inverse\", or \"exponential\"\n *\n * @property {AudioNode} panner\n *\n */\n this.panner = this.ac.createPanner();\n this.panner.panningModel = 'HRTF';\n this.panner.distanceModel = 'linear';\n this.panner.connect(this.output);\n this.input.connect(this.panner);\n\t};\n\n p5.Panner3D.prototype = Object.create(Effect.prototype);\n\n\n /**\n * Connect an audio sorce\n *\n * @method process\n * @for p5.Panner3D\n * @param {Object} src Input source\n */\n p5.Panner3D.prototype.process = function(src) {\n src.connect(this.input);\n }\n /**\n * Set the X,Y,Z position of the Panner\n * @method set\n * @for p5.Panner3D\n * @param {Number} xVal\n * @param {Number} yVal\n * @param {Number} zVal\n * @param {Number} time\n * @return {Array} Updated x, y, z values as an array\n */\n p5.Panner3D.prototype.set = function(xVal, yVal, zVal, time) {\n this.positionX(xVal,time);\n this.positionY(yVal,time);\n this.positionZ(zVal,time);\n return [this.panner.positionX.value,\n this.panner.positionY.value,\n this.panner.positionZ.value];\n };\n\n /**\n * Getter and setter methods for position coordinates\n * @method positionX\n * @for p5.Panner3D\n * @return {Number} updated coordinate value\n */\n /**\n * Getter and setter methods for position coordinates\n * @method positionY\n * @for p5.Panner3D\n * @return {Number} updated coordinate value\n */\n /**\n * Getter and setter methods for position coordinates\n * @method positionZ\n * @for p5.Panner3D\n * @return {Number} updated coordinate value\n */\n p5.Panner3D.prototype.positionX = function(xVal, time) {\n var t = time || 0;\n if (typeof xVal === 'number') {\n this.panner.positionX.value = xVal;\n this.panner.positionX.cancelScheduledValues(this.ac.currentTime + 0.01 + t);\n this.panner.positionX.linearRampToValueAtTime(xVal, this.ac.currentTime + 0.02 + t);\n } else if (xVal) {\n xVal.connect(this.panner.positionX);\n }\n return this.panner.positionX.value;\n };\n p5.Panner3D.prototype.positionY = function(yVal, time) {\n var t = time || 0;\n if (typeof yVal === 'number') {\n this.panner.positionY.value = yVal;\n this.panner.positionY.cancelScheduledValues(this.ac.currentTime + 0.01 + t);\n this.panner.positionY.linearRampToValueAtTime(yVal, this.ac.currentTime + 0.02 + t);\n } else if (yVal) {\n yVal.connect(this.panner.positionY);\n }\n return this.panner.positionY.value;\n };\n p5.Panner3D.prototype.positionZ = function(zVal, time) {\n var t = time || 0;\n if (typeof zVal === 'number') {\n this.panner.positionZ.value = zVal;\n this.panner.positionZ.cancelScheduledValues(this.ac.currentTime + 0.01 + t);\n this.panner.positionZ.linearRampToValueAtTime(zVal, this.ac.currentTime + 0.02 + t);\n } else if (zVal) {\n zVal.connect(this.panner.positionZ);\n }\n return this.panner.positionZ.value;\n };\n\n /**\n * Set the X,Y,Z position of the Panner\n * @method orient\n * @for p5.Panner3D\n * @param {Number} xVal\n * @param {Number} yVal\n * @param {Number} zVal\n * @param {Number} time\n * @return {Array} Updated x, y, z values as an array\n */\n p5.Panner3D.prototype.orient = function(xVal, yVal, zVal, time) {\n this.orientX(xVal,time);\n this.orientY(yVal,time);\n this.orientZ(zVal,time);\n return [this.panner.orientationX.value,\n this.panner.orientationY.value,\n this.panner.orientationZ.value];\n };\n\n /**\n * Getter and setter methods for orient coordinates\n * @method orientX\n * @for p5.Panner3D\n * @return {Number} updated coordinate value\n */\n /**\n * Getter and setter methods for orient coordinates\n * @method orientY\n * @for p5.Panner3D\n * @return {Number} updated coordinate value\n */\n /**\n * Getter and setter methods for orient coordinates\n * @method orientZ\n * @for p5.Panner3D\n * @return {Number} updated coordinate value\n */\n p5.Panner3D.prototype.orientX = function(xVal, time) {\n var t = time || 0;\n if (typeof xVal === 'number') {\n this.panner.orientationX.value = xVal;\n this.panner.orientationX.cancelScheduledValues(this.ac.currentTime + 0.01 + t);\n this.panner.orientationX.linearRampToValueAtTime(xVal, this.ac.currentTime + 0.02 + t);\n } else if (xVal) {\n xVal.connect(this.panner.orientationX);\n }\n return this.panner.orientationX.value;\n };\n p5.Panner3D.prototype.orientY = function(yVal, time) {\n var t = time || 0;\n if (typeof yVal === 'number') {\n this.panner.orientationY.value = yVal;\n this.panner.orientationY.cancelScheduledValues(this.ac.currentTime + 0.01 + t);\n this.panner.orientationY.linearRampToValueAtTime(yVal, this.ac.currentTime + 0.02 + t);\n } else if (yVal) {\n yVal.connect(this.panner.orientationY);\n }\n return this.panner.orientationY.value;\n };\n p5.Panner3D.prototype.orientZ = function(zVal, time) {\n var t = time || 0;\n if (typeof zVal === 'number') {\n this.panner.orientationZ.value = zVal;\n this.panner.orientationZ.cancelScheduledValues(this.ac.currentTime + 0.01 + t);\n this.panner.orientationZ.linearRampToValueAtTime(zVal, this.ac.currentTime + 0.02 + t);\n } else if (zVal) {\n zVal.connect(this.panner.orientationZ);\n }\n return this.panner.orientationZ.value;\n };\n\n /**\n * Set the rolloff factor and max distance\n * @method setFalloff\n * @for p5.Panner3D\n * @param {Number} [maxDistance]\n * @param {Number} [rolloffFactor]\n */\n p5.Panner3D.prototype.setFalloff = function(maxDistance, rolloffFactor) {\n this.maxDist(maxDistance);\n this.rolloff(rolloffFactor);\n };\n /**\n * Maxium distance between the source and the listener\n * @method maxDist\n * @for p5.Panner3D\n * @param {Number} maxDistance\n * @return {Number} updated value\n */\n p5.Panner3D.prototype.maxDist = function(maxDistance){\n if (typeof maxDistance === 'number') {\n this.panner.maxDistance = maxDistance;\n }\n return this.panner.maxDistance;\n };\n\n /**\n * How quickly the volume is reduced as the source moves away from the listener\n * @method rollof\n * @for p5.Panner3D\n * @param {Number} rolloffFactor\n * @return {Number} updated value\n */\n p5.Panner3D.prototype.rolloff = function(rolloffFactor){\n if (typeof rolloffFactor === 'number') {\n this.panner.rolloffFactor = rolloffFactor;\n }\n return this.panner.rolloffFactor;\n };\n\n p5.Panner3D.dispose = function() {\n Effect.prototype.dispose.apply(this);\n if (this.panner) {\n this.panner.disconnect();\n delete this.panner;\n }\n };\n\n return p5.Panner3D;\n\n});\n","'use strict'\n\ndefine(function (require) {\n var p5sound = require('master');\n var Effect = require('effect');\n\n// /**\n// * listener is a class that can construct both a Spatial Panner\n// * and a Spatial Listener. The panner is based on the \n// * Web Audio Spatial Panner Node\n// * https://www.w3.org/TR/webaudio/#the-listenernode-interface\n// * This panner is a spatial processing node that allows audio to be positioned\n// * and oriented in 3D space. \n// *\n// * The Listener modifies the properties of the Audio Context Listener. \n// * Both objects types use the same methods. The default is a spatial panner.\n// *\n// * p5.Panner3D - Constructs a Spatial Panner \n// * p5.Listener3D - Constructs a Spatial Listener \n// *\n// * @class listener\n// * @constructor\n// * @return {Object} p5.Listener3D Object\n// *\n// * @param {Web Audio Node} listener Web Audio Spatial Panning Node\n// * @param {AudioParam} listener.panningModel \"equal power\" or \"HRTF\"\n// * @param {AudioParam} listener.distanceModel \"linear\", \"inverse\", or \"exponential\"\n// * @param {String} [type] [Specify construction of a spatial panner or listener]\n// */\n \n\tp5.Listener3D = function(type) {\n this.ac = p5sound.audiocontext;\n this.listener = this.ac.listener;\n\t}; \n\n// /**\n// * Connect an audio sorce\n// * @param {Object} src Input source\n// */\n p5.Listener3D.prototype.process = function(src) {\n src.connect(this.input);\n }\n// /**\n// * Set the X,Y,Z position of the Panner\n// * @param {[Number]} xVal\n// * @param {[Number]} yVal\n// * @param {[Number]} zVal\n// * @param {[Number]} time\n// * @return {[Array]} [Updated x, y, z values as an array]\n// */\n p5.Listener3D.prototype.position = function(xVal, yVal, zVal, time) {\n this.positionX(xVal,time);\n this.positionY(yVal,time);\n this.positionZ(zVal,time);\n return [this.listener.positionX.value, \n this.listener.positionY.value,\n this.listener.positionZ.value];\n };\n\n// /**\n// * Getter and setter methods for position coordinates\n// * @return {Number} [updated coordinate value]\n// */\n p5.Listener3D.prototype.positionX = function(xVal, time) {\n var t = time || 0;\n if (typeof xVal === 'number') {\n this.listener.positionX.value = xVal;\n this.listener.positionX.cancelScheduledValues(this.ac.currentTime + 0.01 + t);\n this.listener.positionX.linearRampToValueAtTime(xVal, this.ac.currentTime + 0.02 + t);\n } else if (xVal) {\n xVal.connect(this.listener.positionX);\n }\n return this.listener.positionX.value;\n };\n p5.Listener3D.prototype.positionY = function(yVal, time) {\n var t = time || 0;\n if (typeof yVal === 'number') {\n this.listener.positionY.value = yVal;\n this.listener.positionY.cancelScheduledValues(this.ac.currentTime + 0.01 + t);\n this.listener.positionY.linearRampToValueAtTime(yVal, this.ac.currentTime + 0.02 + t);\n } else if (yVal) {\n yVal.connect(this.listener.positionY);\n }\n return this.listener.positionY.value;\n };\n p5.Listener3D.prototype.positionZ = function(zVal, time) {\n var t = time || 0;\n if (typeof zVal === 'number') {\n this.listener.positionZ.value = zVal;\n this.listener.positionZ.cancelScheduledValues(this.ac.currentTime + 0.01 + t);\n this.listener.positionZ.linearRampToValueAtTime(zVal, this.ac.currentTime + 0.02 + t);\n } else if (zVal) {\n zVal.connect(this.listener.positionZ);\n }\n return this.listener.positionZ.value;\n };\n\n// cannot define method when class definition is commented\n// /**\n// * Overrides the listener orient() method because Listener has slightly\n// * different params. In human terms, Forward vectors are the direction the \n// * nose is pointing. Up vectors are the direction of the top of the head.\n// *\n// * @method orient\n// * @param {Number} xValF Forward vector X direction\n// * @param {Number} yValF Forward vector Y direction\n// * @param {Number} zValF Forward vector Z direction\n// * @param {Number} xValU Up vector X direction\n// * @param {Number} yValU Up vector Y direction\n// * @param {Number} zValU Up vector Z direction\n// * @param {Number} time \n// * @return {Array} All orienation params\n// */\n p5.Listener3D.prototype.orient = function(xValF, yValF, zValF, \n xValU, yValU, zValU, time) {\n\n if (arguments.length === 3 || arguments.length === 4) {\n time = arguments[3];\n this.orientForward(xValF, yValF, zValF, time);\n } else if (arguments.length === 6 || arguments === 7) {\n this.orientForward(xValF, yValF, zValF);\n this.orientUp(xValU, yValU, zValU, time);\n }\n \n return [this.listener.forwardX.value, \n this.listener.forwardY.value,\n this.listener.forwardZ.value,\n this.listener.upX.value,\n this.listener.upY.value,\n this.listener.upZ.value];\n };\n\n\n p5.Listener3D.prototype.orientForward = function(xValF, yValF, zValF, time) {\n this.forwardX(xValF,time);\n this.forwardY(yValF,time);\n this.forwardZ(zValF,time);\n\n return [this.listener.forwardX, \n this.listener.forwardY,\n this.listener.forwardZ];\n };\n\n p5.Listener3D.prototype.orientUp = function(xValU, yValU, zValU, time) {\n this.upX(xValU,time);\n this.upY(yValU,time);\n this.upZ(zValU,time);\n\n return [this.listener.upX, \n this.listener.upY,\n this.listener.upZ];\n };\n// /**\n// * Getter and setter methods for orient coordinates\n// * @return {Number} [updated coordinate value]\n// */\n p5.Listener3D.prototype.forwardX = function(xVal, time) {\n var t = time || 0;\n if (typeof xVal === 'number') {\n this.listener.forwardX.value = xVal;\n this.listener.forwardX.cancelScheduledValues(this.ac.currentTime + 0.01 + t);\n this.listener.forwardX.linearRampToValueAtTime(xVal, this.ac.currentTime + 0.02 + t);\n } else if (xVal) {\n xVal.connect(this.listener.forwardX);\n }\n return this.listener.forwardX.value;\n };\n p5.Listener3D.prototype.forwardY = function(yVal, time) {\n var t = time || 0;\n if (typeof yVal === 'number') {\n this.listener.forwardY.value = yVal;\n this.listener.forwardY.cancelScheduledValues(this.ac.currentTime + 0.01 + t);\n this.listener.forwardY.linearRampToValueAtTime(yVal, this.ac.currentTime + 0.02 + t);\n } else if (yVal) {\n yVal.connect(this.listener.forwardY);\n }\n return this.listener.forwardY.value;\n };\n p5.Listener3D.prototype.forwardZ = function(zVal, time) {\n var t = time || 0;\n if (typeof zVal === 'number') {\n this.listener.forwardZ.value = zVal;\n this.listener.forwardZ.cancelScheduledValues(this.ac.currentTime + 0.01 + t);\n this.listener.forwardZ.linearRampToValueAtTime(zVal, this.ac.currentTime + 0.02 + t);\n } else if (zVal) {\n zVal.connect(this.listener.forwardZ);\n }\n return this.listener.forwardZ.value;\n };\n p5.Listener3D.prototype.upX = function(xVal, time) {\n var t = time || 0;\n if (typeof xVal === 'number') {\n this.listener.upX.value = xVal;\n this.listener.upX.cancelScheduledValues(this.ac.currentTime + 0.01 + t);\n this.listener.upX.linearRampToValueAtTime(xVal, this.ac.currentTime + 0.02 + t);\n } else if (xVal) {\n xVal.connect(this.listener.upX);\n }\n return this.listener.upX.value;\n };\n p5.Listener3D.prototype.upY = function(yVal, time) {\n var t = time || 0;\n if (typeof yVal === 'number') {\n this.listener.upY.value = yVal;\n this.listener.upY.cancelScheduledValues(this.ac.currentTime + 0.01 + t);\n this.listener.upY.linearRampToValueAtTime(yVal, this.ac.currentTime + 0.02 + t);\n } else if (yVal) {\n yVal.connect(this.listener.upY);\n }\n return this.listener.upY.value;\n };\n p5.Listener3D.prototype.upZ = function(zVal, time) {\n var t = time || 0;\n if (typeof zVal === 'number') {\n this.listener.upZ.value = zVal;\n this.listener.upZ.cancelScheduledValues(this.ac.currentTime + 0.01 + t);\n this.listener.upZ.linearRampToValueAtTime(zVal, this.ac.currentTime + 0.02 + t);\n } else if (zVal) {\n zVal.connect(this.listener.upZ);\n }\n return this.listener.upZ.value;\n };\n \n return p5.Listener3D;\n\n});","'use strict';\n\ndefine(function (require) {\n var Filter = require('filter');\n var Effect = require('effect');\n\n /**\n * Delay is an echo effect. It processes an existing sound source,\n * and outputs a delayed version of that sound. The p5.Delay can\n * produce different effects depending on the delayTime, feedback,\n * filter, and type. In the example below, a feedback of 0.5 (the\n * defaul value) will produce a looping delay that decreases in\n * volume by 50% each repeat. A filter will cut out the high\n * frequencies so that the delay does not sound as piercing as the\n * original source.\n *\n *\n * This class extends p5.Effect.\n * Methods amp(), chain(),\n * drywet(), connect(), and\n * disconnect() are available.\n * @class p5.Delay\n * @extends p5.Effect\n * @constructor\n * @example\n *
\n * var noise, env, delay;\n *\n * function setup() {\n * background(0);\n * noStroke();\n * fill(255);\n * textAlign(CENTER);\n * text('click to play', width/2, height/2);\n *\n * noise = new p5.Noise('brown');\n * noise.amp(0);\n * noise.start();\n *\n * delay = new p5.Delay();\n *\n * // delay.process() accepts 4 parameters:\n * // source, delayTime, feedback, filter frequency\n * // play with these numbers!!\n * delay.process(noise, .12, .7, 2300);\n *\n * // play the noise with an envelope,\n * // a series of fades ( time / value pairs )\n * env = new p5.Envelope(.01, 0.2, .2, .1);\n * }\n *\n * // mouseClick triggers envelope\n * function mouseClicked() {\n * // is mouse over canvas?\n * if (mouseX > 0 && mouseX < width && mouseY > 0 && mouseY < height) {\n * env.play(noise);\n * }\n * }\n *
\n */\n p5.Delay = function() {\n \tEffect.call(this);\n\n this._split = this.ac.createChannelSplitter(2);\n this._merge = this.ac.createChannelMerger(2);\n\n this._leftGain = this.ac.createGain();\n this._rightGain = this.ac.createGain();\n\n /**\n * The p5.Delay is built with two\n * \n * Web Audio Delay Nodes, one for each stereo channel.\n *\n * @property {DelayNode} leftDelay\n */\n this.leftDelay = this.ac.createDelay();\n /**\n * The p5.Delay is built with two\n * \n * Web Audio Delay Nodes, one for each stereo channel.\n *\n * @property {DelayNode} rightDelay\n */\n this.rightDelay = this.ac.createDelay();\n\n this._leftFilter = new Filter();\n this._rightFilter = new Filter();\n this._leftFilter.disconnect();\n this._rightFilter.disconnect();\n\n this._leftFilter.biquad.frequency.setValueAtTime(1200, this.ac.currentTime);\n this._rightFilter.biquad.frequency.setValueAtTime(1200, this.ac.currentTime);\n this._leftFilter.biquad.Q.setValueAtTime(0.3, this.ac.currentTime);\n this._rightFilter.biquad.Q.setValueAtTime(0.3, this.ac.currentTime);\n\n // graph routing\n this.input.connect(this._split);\n this.leftDelay.connect(this._leftGain);\n this.rightDelay.connect(this._rightGain);\n this._leftGain.connect(this._leftFilter.input);\n this._rightGain.connect(this._rightFilter.input);\n this._merge.connect(this.wet);\n\n\n this._leftFilter.biquad.gain.setValueAtTime(1, this.ac.currentTime);\n this._rightFilter.biquad.gain.setValueAtTime(1, this.ac.currentTime);\n\n // default routing\n this.setType(0);\n\n this._maxDelay = this.leftDelay.delayTime.maxValue;\n\n // set initial feedback to 0.5\n this.feedback(0.5);\n\n\n };\n\n p5.Delay.prototype = Object.create(Effect.prototype);\n /**\n * Add delay to an audio signal according to a set\n * of delay parameters.\n *\n * @method process\n * @for p5.Delay\n * @param {Object} Signal An object that outputs audio\n * @param {Number} [delayTime] Time (in seconds) of the delay/echo.\n * Some browsers limit delayTime to\n * 1 second.\n * @param {Number} [feedback] sends the delay back through itself\n * in a loop that decreases in volume\n * each time.\n * @param {Number} [lowPass] Cutoff frequency. Only frequencies\n * below the lowPass will be part of the\n * delay.\n */\n p5.Delay.prototype.process = function(src, _delayTime, _feedback, _filter) {\n var feedback = _feedback || 0;\n var delayTime = _delayTime || 0;\n if (feedback >= 1.0) {\n throw new Error('Feedback value will force a positive feedback loop.');\n }\n if (delayTime >= this._maxDelay) {\n throw new Error('Delay Time exceeds maximum delay time of ' + this._maxDelay + ' second.');\n }\n\n src.connect(this.input);\n this.leftDelay.delayTime.setValueAtTime(delayTime, this.ac.currentTime);\n this.rightDelay.delayTime.setValueAtTime(delayTime, this.ac.currentTime);\n this._leftGain.gain.value = feedback;\n this._rightGain.gain.value = feedback;\n\n if (_filter) {\n this._leftFilter.freq(_filter);\n this._rightFilter.freq(_filter);\n }\n };\n\n /**\n * Set the delay (echo) time, in seconds. Usually this value will be\n * a floating point number between 0.0 and 1.0.\n *\n * @method delayTime\n * @for p5.Delay\n * @param {Number} delayTime Time (in seconds) of the delay\n */\n p5.Delay.prototype.delayTime = function(t) {\n // if t is an audio node...\n if (typeof t !== 'number') {\n t.connect(this.leftDelay.delayTime);\n t.connect(this.rightDelay.delayTime);\n }\n\n else {\n this.leftDelay.delayTime.cancelScheduledValues(this.ac.currentTime);\n this.rightDelay.delayTime.cancelScheduledValues(this.ac.currentTime);\n this.leftDelay.delayTime.linearRampToValueAtTime(t, this.ac.currentTime);\n this.rightDelay.delayTime.linearRampToValueAtTime(t, this.ac.currentTime);\n }\n };\n\n /**\n * Feedback occurs when Delay sends its signal back through its input\n * in a loop. The feedback amount determines how much signal to send each\n * time through the loop. A feedback greater than 1.0 is not desirable because\n * it will increase the overall output each time through the loop,\n * creating an infinite feedback loop. The default value is 0.5\n *\n * @method feedback\n * @for p5.Delay\n * @param {Number|Object} feedback 0.0 to 1.0, or an object such as an\n * Oscillator that can be used to\n * modulate this param\n * @returns {Number} Feedback value\n *\n */\n p5.Delay.prototype.feedback = function(f) {\n // if f is an audio node...\n if (f && typeof f !== 'number') {\n f.connect(this._leftGain.gain);\n f.connect(this._rightGain.gain);\n }\n else if (f >= 1.0) {\n throw new Error('Feedback value will force a positive feedback loop.');\n }\n else if (typeof f === 'number') {\n this._leftGain.gain.value = f;\n this._rightGain.gain.value = f;\n }\n\n // return value of feedback\n return this._leftGain.gain.value;\n };\n\n /**\n * Set a lowpass filter frequency for the delay. A lowpass filter\n * will cut off any frequencies higher than the filter frequency.\n *\n * @method filter\n * @for p5.Delay\n * @param {Number|Object} cutoffFreq A lowpass filter will cut off any\n * frequencies higher than the filter frequency.\n * @param {Number|Object} res Resonance of the filter frequency\n * cutoff, or an object (i.e. a p5.Oscillator)\n * that can be used to modulate this parameter.\n * High numbers (i.e. 15) will produce a resonance,\n * low numbers (i.e. .2) will produce a slope.\n */\n p5.Delay.prototype.filter = function(freq, q) {\n this._leftFilter.set(freq, q);\n this._rightFilter.set(freq, q);\n };\n\n\n /**\n * Choose a preset type of delay. 'pingPong' bounces the signal\n * from the left to the right channel to produce a stereo effect.\n * Any other parameter will revert to the default delay setting.\n *\n * @method setType\n * @for p5.Delay\n * @param {String|Number} type 'pingPong' (1) or 'default' (0)\n */\n p5.Delay.prototype.setType = function(t) {\n if (t === 1) {\n t = 'pingPong';\n }\n this._split.disconnect();\n this._leftFilter.disconnect();\n this._rightFilter.disconnect();\n this._split.connect(this.leftDelay, 0);\n this._split.connect(this.rightDelay, 1);\n switch(t) {\n case 'pingPong':\n this._rightFilter.setType( this._leftFilter.biquad.type );\n this._leftFilter.output.connect(this._merge, 0, 0);\n this._rightFilter.output.connect(this._merge, 0, 1);\n this._leftFilter.output.connect(this.rightDelay);\n this._rightFilter.output.connect(this.leftDelay);\n break;\n default:\n this._leftFilter.output.connect(this._merge, 0, 0);\n this._rightFilter.output.connect(this._merge, 0, 1);\n this._leftFilter.output.connect(this.leftDelay);\n this._rightFilter.output.connect(this.rightDelay);\n }\n };\n\n // DocBlocks for methods inherited from p5.Effect\n /**\n * Set the output level of the delay effect.\n *\n * @method amp\n * @for p5.Delay\n * @param {Number} volume amplitude between 0 and 1.0\n * @param {Number} [rampTime] create a fade that lasts rampTime\n * @param {Number} [timeFromNow] schedule this event to happen\n * seconds from now\n */\n /**\n * Send output to a p5.sound or web audio object\n *\n * @method connect\n * @for p5.Delay\n * @param {Object} unit\n */\n /**\n * Disconnect all output.\n *\n * @method disconnect\n * @for p5.Delay\n */\n\n p5.Delay.prototype.dispose = function() {\n\n Effect.prototype.dispose.apply(this);\n\n this._split.disconnect();\n this._leftFilter.dispose();\n this._rightFilter.dispose();\n this._merge.disconnect();\n this._leftGain.disconnect();\n this._rightGain.disconnect();\n this.leftDelay.disconnect();\n this.rightDelay.disconnect();\n\n this._split = undefined;\n this._leftFilter = undefined;\n this._rightFilter = undefined;\n this._merge = undefined;\n this._leftGain = undefined;\n this._rightGain = undefined;\n this.leftDelay = undefined;\n this.rightDelay = undefined;\n };\n\n});\n","'use strict';\n\ndefine(function (require) {\n var CustomError = require('errorHandler');\n var Effect = require('effect');\n\n /**\n * Reverb adds depth to a sound through a large number of decaying\n * echoes. It creates the perception that sound is occurring in a\n * physical space. The p5.Reverb has paramters for Time (how long does the\n * reverb last) and decayRate (how much the sound decays with each echo)\n * that can be set with the .set() or .process() methods. The p5.Convolver\n * extends p5.Reverb allowing you to recreate the sound of actual physical\n * spaces through convolution.\n *\n * This class extends p5.Effect.\n * Methods amp(), chain(),\n * drywet(), connect(), and\n * disconnect() are available.\n *\n * @class p5.Reverb\n * @extends p5.Effect\n * @constructor\n * @example\n *
\n * var soundFile, reverb;\n * function preload() {\n * soundFile = loadSound('assets/Damscray_DancingTiger.mp3');\n * }\n *\n * function setup() {\n * reverb = new p5.Reverb();\n * soundFile.disconnect(); // so we'll only hear reverb...\n *\n * // connect soundFile to reverb, process w/\n * // 3 second reverbTime, decayRate of 2%\n * reverb.process(soundFile, 3, 2);\n * soundFile.play();\n * }\n *
\n */\n\n\n p5.Reverb = function() {\n Effect.call(this);\n\n this._initConvolverNode();\n\n // otherwise, Safari distorts\n this.input.gain.value = 0.5;\n\n // default params\n this._seconds = 3;\n this._decay = 2;\n this._reverse = false;\n\n this._buildImpulse();\n\n };\n\n p5.Reverb.prototype = Object.create(Effect.prototype);\n\n p5.Reverb.prototype._initConvolverNode = function() {\n this.convolverNode = this.ac.createConvolver();\n this.input.connect(this.convolverNode);\n this.convolverNode.connect(this.wet);\n };\n\n p5.Reverb.prototype._teardownConvolverNode = function() {\n if (this.convolverNode) {\n this.convolverNode.disconnect();\n delete this.convolverNode;\n }\n };\n\n p5.Reverb.prototype._setBuffer = function(audioBuffer) {\n this._teardownConvolverNode();\n this._initConvolverNode();\n this.convolverNode.buffer = audioBuffer;\n };\n /**\n * Connect a source to the reverb, and assign reverb parameters.\n *\n * @method process\n * @for p5.Reverb\n * @param {Object} src p5.sound / Web Audio object with a sound\n * output.\n * @param {Number} [seconds] Duration of the reverb, in seconds.\n * Min: 0, Max: 10. Defaults to 3.\n * @param {Number} [decayRate] Percentage of decay with each echo.\n * Min: 0, Max: 100. Defaults to 2.\n * @param {Boolean} [reverse] Play the reverb backwards or forwards.\n */\n p5.Reverb.prototype.process = function(src, seconds, decayRate, reverse) {\n src.connect(this.input);\n var rebuild = false;\n if (seconds) {\n this._seconds = seconds;\n rebuild = true;\n }\n if (decayRate) {\n this._decay = decayRate;\n }\n if (reverse) {\n this._reverse = reverse;\n }\n if (rebuild) {\n this._buildImpulse();\n }\n };\n\n /**\n * Set the reverb settings. Similar to .process(), but without\n * assigning a new input.\n *\n * @method set\n * @for p5.Reverb\n * @param {Number} [seconds] Duration of the reverb, in seconds.\n * Min: 0, Max: 10. Defaults to 3.\n * @param {Number} [decayRate] Percentage of decay with each echo.\n * Min: 0, Max: 100. Defaults to 2.\n * @param {Boolean} [reverse] Play the reverb backwards or forwards.\n */\n p5.Reverb.prototype.set = function(seconds, decayRate, reverse) {\n var rebuild = false;\n if (seconds) {\n this._seconds = seconds;\n rebuild = true;\n }\n if (decayRate) {\n this._decay = decayRate;\n }\n if (reverse) {\n this._reverse = reverse;\n }\n if (rebuild) {\n this._buildImpulse();\n }\n };\n\n // DocBlocks for methods inherited from p5.Effect\n /**\n * Set the output level of the reverb effect.\n *\n * @method amp\n * @for p5.Reverb\n * @param {Number} volume amplitude between 0 and 1.0\n * @param {Number} [rampTime] create a fade that lasts rampTime\n * @param {Number} [timeFromNow] schedule this event to happen\n * seconds from now\n */\n /**\n * Send output to a p5.sound or web audio object\n *\n * @method connect\n * @for p5.Reverb\n * @param {Object} unit\n */\n /**\n * Disconnect all output.\n *\n * @method disconnect\n * @for p5.Reverb\n */\n\n /**\n * Inspired by Simple Reverb by Jordan Santell\n * https://github.com/web-audio-components/simple-reverb/blob/master/index.js\n *\n * Utility function for building an impulse response\n * based on the module parameters.\n *\n * @private\n */\n p5.Reverb.prototype._buildImpulse = function() {\n var rate = this.ac.sampleRate;\n var length = rate*this._seconds;\n var decay = this._decay;\n var impulse = this.ac.createBuffer(2, length, rate);\n var impulseL = impulse.getChannelData(0);\n var impulseR = impulse.getChannelData(1);\n var n, i;\n for (i = 0; i < length; i++) {\n n = this._reverse ? length - i : i;\n impulseL[i] = (Math.random() * 2 - 1) * Math.pow(1 - n / length, decay);\n impulseR[i] = (Math.random() * 2 - 1) * Math.pow(1 - n / length, decay);\n }\n this._setBuffer(impulse);\n };\n\n p5.Reverb.prototype.dispose = function() {\n Effect.prototype.dispose.apply(this);\n this._teardownConvolverNode();\n };\n\n // =======================================================================\n // *** p5.Convolver ***\n // =======================================================================\n\n /**\n *
p5.Convolver extends p5.Reverb. It can emulate the sound of real\n * physical spaces through a process called \n * convolution.
\n *\n *
Convolution multiplies any audio input by an \"impulse response\"\n * to simulate the dispersion of sound over time. The impulse response is\n * generated from an audio file that you provide. One way to\n * generate an impulse response is to pop a balloon in a reverberant space\n * and record the echo. Convolution can also be used to experiment with\n * sound.
\n *\n *
Use the method createConvolution(path) to instantiate a\n * p5.Convolver with a path to your impulse response audio file.
\n *\n * @class p5.Convolver\n * @extends p5.Effect\n * @constructor\n * @param {String} path path to a sound file\n * @param {Function} [callback] function to call when loading succeeds\n * @param {Function} [errorCallback] function to call if loading fails.\n * This function will receive an error or\n * XMLHttpRequest object with information\n * about what went wrong.\n * @example\n *
\n * var cVerb, sound;\n * function preload() {\n * // We have both MP3 and OGG versions of all sound assets\n * soundFormats('ogg', 'mp3');\n *\n * // Try replacing 'bx-spring' with other soundfiles like\n * // 'concrete-tunnel' 'small-plate' 'drum' 'beatbox'\n * cVerb = createConvolver('assets/bx-spring.mp3');\n *\n * // Try replacing 'Damscray_DancingTiger' with\n * // 'beat', 'doorbell', lucky_dragons_-_power_melody'\n * sound = loadSound('assets/Damscray_DancingTiger.mp3');\n * }\n *\n * function setup() {\n * // disconnect from master output...\n * sound.disconnect();\n *\n * // ...and process with cVerb\n * // so that we only hear the convolution\n * cVerb.process(sound);\n *\n * sound.play();\n * }\n *
\n */\n p5.Convolver = function(path, callback, errorCallback) {\n \t p5.Reverb.call(this);\n\n /**\n * Internally, the p5.Convolver uses the a\n * \n * Web Audio Convolver Node.\n *\n * @property {ConvolverNode} convolverNode\n */\n this._initConvolverNode();\n\n // otherwise, Safari distorts\n this.input.gain.value = 0.5;\n\n if (path) {\n this.impulses = [];\n this._loadBuffer(path, callback, errorCallback);\n }\n else {\n // parameters\n this._seconds = 3;\n this._decay = 2;\n this._reverse = false;\n\n this._buildImpulse();\n }\n\n };\n\n p5.Convolver.prototype = Object.create(p5.Reverb.prototype);\n\n p5.prototype.registerPreloadMethod('createConvolver', p5.prototype);\n\n /**\n * Create a p5.Convolver. Accepts a path to a soundfile\n * that will be used to generate an impulse response.\n *\n * @method createConvolver\n * @for p5\n * @param {String} path path to a sound file\n * @param {Function} [callback] function to call if loading is successful.\n * The object will be passed in as the argument\n * to the callback function.\n * @param {Function} [errorCallback] function to call if loading is not successful.\n * A custom error will be passed in as the argument\n * to the callback function.\n * @return {p5.Convolver}\n * @example\n *
\n * var cVerb, sound;\n * function preload() {\n * // We have both MP3 and OGG versions of all sound assets\n * soundFormats('ogg', 'mp3');\n *\n * // Try replacing 'bx-spring' with other soundfiles like\n * // 'concrete-tunnel' 'small-plate' 'drum' 'beatbox'\n * cVerb = createConvolver('assets/bx-spring.mp3');\n *\n * // Try replacing 'Damscray_DancingTiger' with\n * // 'beat', 'doorbell', lucky_dragons_-_power_melody'\n * sound = loadSound('assets/Damscray_DancingTiger.mp3');\n * }\n *\n * function setup() {\n * // disconnect from master output...\n * sound.disconnect();\n *\n * // ...and process with cVerb\n * // so that we only hear the convolution\n * cVerb.process(sound);\n *\n * sound.play();\n * }\n *
\n */\n p5.prototype.createConvolver = function(path, callback, errorCallback) {\n // if loading locally without a server\n if (window.location.origin.indexOf('file://') > -1 && window.cordova === 'undefined') {\n alert('This sketch may require a server to load external files. Please see http://bit.ly/1qcInwS');\n }\n var self = this;\n var cReverb = new p5.Convolver(path, function(buffer) {\n if (typeof callback === 'function') {\n callback(buffer);\n }\n\n if (typeof self._decrementPreload === 'function') {\n self._decrementPreload();\n }\n }, errorCallback);\n cReverb.impulses = [];\n return cReverb;\n };\n\n /**\n * Private method to load a buffer as an Impulse Response,\n * assign it to the convolverNode, and add to the Array of .impulses.\n *\n * @param {String} path\n * @param {Function} callback\n * @param {Function} errorCallback\n * @private\n */\n p5.Convolver.prototype._loadBuffer = function(path, callback, errorCallback) {\n var path = p5.prototype._checkFileFormats(path);\n var self = this;\n var errorTrace = new Error().stack;\n var ac = p5.prototype.getAudioContext();\n\n var request = new XMLHttpRequest();\n request.open('GET', path, true);\n request.responseType = 'arraybuffer';\n\n request.onload = function() {\n if (request.status === 200) {\n // on success loading file:\n ac.decodeAudioData(request.response,\n function(buff) {\n var buffer = {};\n var chunks = path.split('/');\n buffer.name = chunks[chunks.length - 1];\n buffer.audioBuffer = buff;\n self.impulses.push(buffer);\n self._setBuffer(buffer.audioBuffer);\n if (callback) {\n callback(buffer);\n }\n },\n // error decoding buffer. \"e\" is undefined in Chrome 11/22/2015\n function() {\n var err = new CustomError('decodeAudioData', errorTrace, self.url);\n var msg = 'AudioContext error at decodeAudioData for ' + self.url;\n if (errorCallback) {\n err.msg = msg;\n errorCallback(err);\n } else {\n console.error(msg +'\\n The error stack trace includes: \\n' + err.stack);\n }\n }\n );\n }\n // if request status != 200, it failed\n else {\n var err = new CustomError('loadConvolver', errorTrace, self.url);\n var msg = 'Unable to load ' + self.url +\n '. The request status was: ' + request.status + ' (' + request.statusText + ')';\n\n if (errorCallback) {\n err.message = msg;\n errorCallback(err);\n } else {\n console.error(msg +'\\n The error stack trace includes: \\n' + err.stack);\n }\n }\n };\n\n // if there is another error, aside from 404...\n request.onerror = function() {\n var err = new CustomError('loadConvolver', errorTrace, self.url);\n var msg = 'There was no response from the server at ' + self.url + '. Check the url and internet connectivity.';\n\n if (errorCallback) {\n err.message = msg;\n errorCallback(err);\n } else {\n console.error(msg +'\\n The error stack trace includes: \\n' + err.stack);\n }\n };\n request.send();\n };\n\n p5.Convolver.prototype.set = null;\n\n /**\n * Connect a source to the reverb, and assign reverb parameters.\n *\n * @method process\n * @for p5.Convolver\n * @param {Object} src p5.sound / Web Audio object with a sound\n * output.\n * @example\n *
\n * var cVerb, sound;\n * function preload() {\n * soundFormats('ogg', 'mp3');\n *\n * cVerb = createConvolver('assets/concrete-tunnel.mp3');\n *\n * sound = loadSound('assets/beat.mp3');\n * }\n *\n * function setup() {\n * // disconnect from master output...\n * sound.disconnect();\n *\n * // ...and process with (i.e. connect to) cVerb\n * // so that we only hear the convolution\n * cVerb.process(sound);\n *\n * sound.play();\n * }\n *
\n */\n p5.Convolver.prototype.process = function(src) {\n src.connect(this.input);\n };\n\n /**\n * If you load multiple impulse files using the .addImpulse method,\n * they will be stored as Objects in this Array. Toggle between them\n * with the toggleImpulse(id) method.\n *\n * @property {Array} impulses\n * @for p5.Convolver\n */\n p5.Convolver.prototype.impulses = [];\n\n /**\n * Load and assign a new Impulse Response to the p5.Convolver.\n * The impulse is added to the .impulses array. Previous\n * impulses can be accessed with the .toggleImpulse(id)\n * method.\n *\n * @method addImpulse\n * @for p5.Convolver\n * @param {String} path path to a sound file\n * @param {Function} callback function (optional)\n * @param {Function} errorCallback function (optional)\n */\n p5.Convolver.prototype.addImpulse = function(path, callback, errorCallback) {\n // if loading locally without a server\n if (window.location.origin.indexOf('file://') > -1 && window.cordova === 'undefined') {\n alert('This sketch may require a server to load external files. Please see http://bit.ly/1qcInwS');\n }\n this._loadBuffer(path, callback, errorCallback);\n };\n\n /**\n * Similar to .addImpulse, except that the .impulses\n * Array is reset to save memory. A new .impulses\n * array is created with this impulse as the only item.\n *\n * @method resetImpulse\n * @for p5.Convolver\n * @param {String} path path to a sound file\n * @param {Function} callback function (optional)\n * @param {Function} errorCallback function (optional)\n */\n p5.Convolver.prototype.resetImpulse = function(path, callback, errorCallback) {\n // if loading locally without a server\n if (window.location.origin.indexOf('file://') > -1 && window.cordova === 'undefined') {\n alert('This sketch may require a server to load external files. Please see http://bit.ly/1qcInwS');\n }\n this.impulses = [];\n this._loadBuffer(path, callback, errorCallback);\n };\n\n /**\n * If you have used .addImpulse() to add multiple impulses\n * to a p5.Convolver, then you can use this method to toggle between\n * the items in the .impulses Array. Accepts a parameter\n * to identify which impulse you wish to use, identified either by its\n * original filename (String) or by its position in the .impulses\n * Array (Number). \n * You can access the objects in the .impulses Array directly. Each\n * Object has two attributes: an .audioBuffer (type:\n * Web Audio \n * AudioBuffer) and a .name, a String that corresponds\n * with the original filename.\n *\n * @method toggleImpulse\n * @for p5.Convolver\n * @param {String|Number} id Identify the impulse by its original filename\n * (String), or by its position in the\n * .impulses Array (Number).\n */\n p5.Convolver.prototype.toggleImpulse = function(id) {\n if (typeof id === 'number' && id < this.impulses.length) {\n this._setBuffer(this.impulses[id].audioBuffer);\n }\n if (typeof id === 'string') {\n for (var i = 0; i < this.impulses.length; i++) {\n if (this.impulses[i].name === id) {\n this._setBuffer(this.impulses[i].audioBuffer);\n break;\n }\n }\n }\n };\n\n p5.Convolver.prototype.dispose = function() {\n p5.Reverb.prototype.dispose.apply(this);\n\n // remove all the Impulse Response buffers\n for (var i in this.impulses) {\n if (this.impulses[i]) {\n this.impulses[i] = null;\n }\n }\n };\n\n});\n","'use strict';\n\ndefine(function (require) {\n var p5sound = require('master');\n\n // requires the Tone.js library's Clock (MIT license, Yotam Mann)\n // https://github.com/TONEnoTONE/Tone.js/\n var Clock = require('Tone/core/Clock');\n\n p5.Metro = function() {\n this.clock = new Clock({\n 'callback': this.ontick.bind(this)\n });\n this.syncedParts = [];\n this.bpm = 120; // gets overridden by p5.Part\n this._init();\n\n this.prevTick = 0;\n this.tatumTime = 0;\n\n this.tickCallback = function() {};\n };\n\n p5.Metro.prototype.ontick = function(tickTime) {\n var elapsedTime = tickTime - this.prevTick;\n var secondsFromNow = tickTime - p5sound.audiocontext.currentTime;\n if (elapsedTime - this.tatumTime <= -0.02) {\n return;\n } else {\n // console.log('ok', this.syncedParts[0].phrases[0].name);\n this.prevTick = tickTime;\n\n // for all of the active things on the metro:\n var self = this;\n this.syncedParts.forEach(function(thisPart) {\n if (!thisPart.isPlaying) return;\n thisPart.incrementStep(secondsFromNow);\n // each synced source keeps track of its own beat number\n thisPart.phrases.forEach(function(thisPhrase) {\n var phraseArray = thisPhrase.sequence;\n var bNum = self.metroTicks % phraseArray.length;\n if (phraseArray[bNum] !== 0 && (self.metroTicks < phraseArray.length || !thisPhrase.looping) ) {\n thisPhrase.callback(secondsFromNow, phraseArray[bNum]);\n }\n });\n });\n this.metroTicks += 1;\n this.tickCallback(secondsFromNow);\n }\n };\n\n p5.Metro.prototype.setBPM = function(bpm, rampTime) {\n var beatTime = 60 / (bpm*this.tatums);\n var now = p5sound.audiocontext.currentTime;\n this.tatumTime = beatTime;\n\n var rampTime = rampTime || 0;\n this.clock.frequency.setValueAtTime(this.clock.frequency.value, now);\n this.clock.frequency.linearRampToValueAtTime(bpm, now + rampTime);\n this.bpm = bpm;\n };\n\n p5.Metro.prototype.getBPM = function() {\n return this.clock.getRate() / this.tatums * 60;\n };\n\n p5.Metro.prototype._init = function() {\n this.metroTicks = 0;\n // this.setBPM(120);\n };\n\n // clear existing synced parts, add only this one\n p5.Metro.prototype.resetSync = function(part) {\n this.syncedParts = [part];\n };\n\n // push a new synced part to the array\n p5.Metro.prototype.pushSync = function(part) {\n this.syncedParts.push(part);\n };\n\n p5.Metro.prototype.start = function(timeFromNow) {\n var t = timeFromNow || 0;\n var now = p5sound.audiocontext.currentTime;\n this.clock.start(now + t);\n this.setBPM(this.bpm);\n };\n\n p5.Metro.prototype.stop = function(timeFromNow) {\n var t = timeFromNow || 0;\n var now = p5sound.audiocontext.currentTime;\n this.clock.stop(now + t);\n };\n\n p5.Metro.prototype.beatLength = function(tatums) {\n this.tatums = 1/tatums / 4; // lowest possible division of a beat\n };\n\n});\n","define([\"Tone/core/Tone\", \"Tone/core/Timeline\", \"Tone/type/Type\"], function (Tone) {\n\n\t\"use strict\";\n\n\t/**\n\t * @class A Timeline State. Provides the methods: setStateAtTime(\"state\", time)\n\t * and getValueAtTime(time).\n\t *\n\t * @extends {Tone.Timeline}\n\t * @param {String} initial The initial state of the TimelineState. \n\t * Defaults to undefined\n\t */\n\tTone.TimelineState = function(initial){\n\n\t\tTone.Timeline.call(this);\n\n\t\t/**\n\t\t * The initial state\n\t\t * @private\n\t\t * @type {String}\n\t\t */\n\t\tthis._initial = initial;\n\t};\n\n\tTone.extend(Tone.TimelineState, Tone.Timeline);\n\n\t/**\n\t * Returns the scheduled state scheduled before or at\n\t * the given time.\n\t * @param {Number} time The time to query.\n\t * @return {String} The name of the state input in setStateAtTime.\n\t */\n\tTone.TimelineState.prototype.getValueAtTime = function(time){\n\t\tvar event = this.get(time);\n\t\tif (event !== null){\n\t\t\treturn event.state;\n\t\t} else {\n\t\t\treturn this._initial;\n\t\t}\n\t};\n\n\t/**\n\t * Returns the scheduled state scheduled before or at\n\t * the given time.\n\t * @param {String} state The name of the state to set.\n\t * @param {Number} time The time to query.\n\t */\n\tTone.TimelineState.prototype.setStateAtTime = function(state, time){\n\t\tthis.add({\n\t\t\t\"state\" : state,\n\t\t\t\"time\" : time\n\t\t});\n\t};\n\n\treturn Tone.TimelineState;\n});","'use strict';\n\ndefine(function(require) {\n var p5sound = require('master');\n\n var BPM = 120;\n\n /**\n * Set the global tempo, in beats per minute, for all\n * p5.Parts. This method will impact all active p5.Parts.\n *\n * @method setBPM\n * @for p5\n * @param {Number} BPM Beats Per Minute\n * @param {Number} rampTime Seconds from now\n */\n p5.prototype.setBPM = function(bpm, rampTime) {\n BPM = bpm;\n for (var i in p5sound.parts) {\n if (p5sound.parts[i]) {\n p5sound.parts[i].setBPM(bpm, rampTime);\n }\n }\n };\n\n /**\n *
A phrase is a pattern of musical events over time, i.e.\n * a series of notes and rests.
\n *\n *
Phrases must be added to a p5.Part for playback, and\n * each part can play multiple phrases at the same time.\n * For example, one Phrase might be a kick drum, another\n * could be a snare, and another could be the bassline.
\n *\n *
The first parameter is a name so that the phrase can be\n * modified or deleted later. The callback is a a function that\n * this phrase will call at every step—for example it might be\n * called playNote(value){}. The array determines\n * which value is passed into the callback at each step of the\n * phrase. It can be numbers, an object with multiple numbers,\n * or a zero (0) indicates a rest so the callback won't be called).
\n *\n * @class p5.Phrase\n * @constructor\n * @param {String} name Name so that you can access the Phrase.\n * @param {Function} callback The name of a function that this phrase\n * will call. Typically it will play a sound,\n * and accept two parameters: a time at which\n * to play the sound (in seconds from now),\n * and a value from the sequence array. The\n * time should be passed into the play() or\n * start() method to ensure precision.\n * @param {Array} sequence Array of values to pass into the callback\n * at each step of the phrase.\n * @example\n *
\n */\n p5.Phrase = function(name, callback, sequence) {\n this.phraseStep = 0;\n this.name = name;\n this.callback = callback;\n /**\n * Array of values to pass into the callback\n * at each step of the phrase. Depending on the callback\n * function's requirements, these values may be numbers,\n * strings, or an object with multiple parameters.\n * Zero (0) indicates a rest.\n *\n * @property {Array} sequence\n */\n this.sequence = sequence;\n };\n\n /**\n *
A p5.Part plays back one or more p5.Phrases. Instantiate a part\n * with steps and tatums. By default, each step represents a 1/16th note.
\n *\n *
See p5.Phrase for more about musical timing.
\n *\n * @class p5.Part\n * @constructor\n * @param {Number} [steps] Steps in the part\n * @param {Number} [tatums] Divisions of a beat, e.g. use 1/4, or 0.25 for a quater note (default is 1/16, a sixteenth note)\n * @example\n *
\n * var box, drum, myPart;\n * var boxPat = [1,0,0,2,0,2,0,0];\n * var drumPat = [0,1,1,0,2,0,1,0];\n * var msg = 'click to play';\n *\n * function preload() {\n * box = loadSound('assets/beatbox.mp3');\n * drum = loadSound('assets/drum.mp3');\n * }\n *\n * function setup() {\n * noStroke();\n * fill(255);\n * textAlign(CENTER);\n * masterVolume(0.1);\n *\n * var boxPhrase = new p5.Phrase('box', playBox, boxPat);\n * var drumPhrase = new p5.Phrase('drum', playDrum, drumPat);\n * myPart = new p5.Part();\n * myPart.addPhrase(boxPhrase);\n * myPart.addPhrase(drumPhrase);\n * myPart.setBPM(60);\n * masterVolume(0.1);\n * }\n *\n * function draw() {\n * background(0);\n * text(msg, width/2, height/2);\n * }\n *\n * function playBox(time, playbackRate) {\n * box.rate(playbackRate);\n * box.play(time);\n * }\n *\n * function playDrum(time, playbackRate) {\n * drum.rate(playbackRate);\n * drum.play(time);\n * }\n *\n * function mouseClicked() {\n * if (mouseX > 0 && mouseX < width && mouseY > 0 && mouseY < height) {\n * myPart.start();\n * msg = 'playing part';\n * }\n * }\n *
\n */\n p5.Part = function(steps, bLength) {\n this.length = steps || 0; // how many beats\n this.partStep = 0;\n this.phrases = [];\n this.isPlaying = false;\n this.noLoop();\n this.tatums = bLength || 0.0625; // defaults to quarter note\n\n this.metro = new p5.Metro();\n this.metro._init();\n this.metro.beatLength(this.tatums);\n this.metro.setBPM(BPM);\n p5sound.parts.push(this);\n this.callback = function() {};\n };\n\n /**\n * Set the tempo of this part, in Beats Per Minute.\n *\n * @method setBPM\n * @for p5.Part\n * @param {Number} BPM Beats Per Minute\n * @param {Number} [rampTime] Seconds from now\n */\n p5.Part.prototype.setBPM = function(tempo, rampTime) {\n this.metro.setBPM(tempo, rampTime);\n };\n\n /**\n * Returns the tempo, in Beats Per Minute, of this part.\n *\n * @method getBPM\n * @for p5.Part\n * @return {Number}\n */\n p5.Part.prototype.getBPM = function() {\n return this.metro.getBPM();\n };\n\n /**\n * Start playback of this part. It will play\n * through all of its phrases at a speed\n * determined by setBPM.\n *\n * @method start\n * @for p5.Part\n * @param {Number} [time] seconds from now\n */\n p5.Part.prototype.start = function(time) {\n if (!this.isPlaying) {\n this.isPlaying = true;\n this.metro.resetSync(this);\n var t = time || 0;\n this.metro.start(t);\n }\n };\n\n /**\n * Loop playback of this part. It will begin\n * looping through all of its phrases at a speed\n * determined by setBPM.\n *\n * @method loop\n * @for p5.Part\n * @param {Number} [time] seconds from now\n */\n p5.Part.prototype.loop = function(time) {\n this.looping = true;\n // rest onended function\n this.onended = function() {\n this.partStep = 0;\n };\n var t = time || 0;\n this.start(t);\n };\n\n /**\n * Tell the part to stop looping.\n *\n * @method noLoop\n * @for p5.Part\n */\n p5.Part.prototype.noLoop = function() {\n this.looping = false;\n // rest onended function\n this.onended = function() {\n this.stop();\n };\n };\n\n /**\n * Stop the part and cue it to step 0. Playback will resume from the begining of the Part when it is played again.\n *\n * @method stop\n * @for p5.Part\n * @param {Number} [time] seconds from now\n */\n p5.Part.prototype.stop = function(time) {\n this.partStep = 0;\n this.pause(time);\n };\n\n /**\n * Pause the part. Playback will resume\n * from the current step.\n *\n * @method pause\n * @for p5.Part\n * @param {Number} time seconds from now\n */\n p5.Part.prototype.pause = function(time) {\n this.isPlaying = false;\n var t = time || 0;\n this.metro.stop(t);\n };\n\n /**\n * Add a p5.Phrase to this Part.\n *\n * @method addPhrase\n * @for p5.Part\n * @param {p5.Phrase} phrase reference to a p5.Phrase\n */\n p5.Part.prototype.addPhrase = function(name, callback, array) {\n var p;\n if (arguments.length === 3) {\n p = new p5.Phrase(name, callback, array);\n } else if (arguments[0] instanceof p5.Phrase) {\n p = arguments[0];\n } else {\n throw 'invalid input. addPhrase accepts name, callback, array or a p5.Phrase';\n }\n this.phrases.push(p);\n // reset the length if phrase is longer than part's existing length\n if (p.sequence.length > this.length) {\n this.length = p.sequence.length;\n }\n };\n\n /**\n * Remove a phrase from this part, based on the name it was\n * given when it was created.\n *\n * @method removePhrase\n * @for p5.Part\n * @param {String} phraseName\n */\n p5.Part.prototype.removePhrase = function(name) {\n for (var i in this.phrases) {\n if (this.phrases[i].name === name) {\n this.phrases.splice(i, 1);\n }\n }\n };\n\n /**\n * Get a phrase from this part, based on the name it was\n * given when it was created. Now you can modify its array.\n *\n * @method getPhrase\n * @for p5.Part\n * @param {String} phraseName\n */\n p5.Part.prototype.getPhrase = function(name) {\n for (var i in this.phrases) {\n if (this.phrases[i].name === name) {\n return this.phrases[i];\n }\n }\n };\n\n /**\n * Find all sequences with the specified name, and replace their patterns with the specified array.\n *\n * @method replaceSequence\n * @for p5.Part\n * @param {String} phraseName\n * @param {Array} sequence Array of values to pass into the callback\n * at each step of the phrase.\n */\n p5.Part.prototype.replaceSequence = function(name, array) {\n for (var i in this.phrases) {\n if (this.phrases[i].name === name) {\n this.phrases[i].sequence = array;\n }\n }\n };\n\n p5.Part.prototype.incrementStep = function(time) {\n if (this.partStep < this.length - 1) {\n this.callback(time);\n this.partStep += 1;\n } else {\n if (!this.looping && this.partStep === this.length - 1) {\n console.log('done');\n // this.callback(time);\n this.onended();\n }\n }\n };\n\n /**\n * Set the function that will be called at every step. This will clear the previous function.\n *\n * @method onStep\n * @for p5.Part\n * @param {Function} callback The name of the callback\n * you want to fire\n * on every beat/tatum.\n */\n p5.Part.prototype.onStep = function(callback) {\n this.callback = callback;\n };\n\n\n // ===============\n // p5.Score\n // ===============\n\n /**\n * A Score consists of a series of Parts. The parts will\n * be played back in order. For example, you could have an\n * A part, a B part, and a C part, and play them back in this order\n * new p5.Score(a, a, b, a, c)\n *\n * @class p5.Score\n * @constructor\n * @param {p5.Part} [...parts] One or multiple parts, to be played in sequence.\n */\n p5.Score = function() {\n // for all of the arguments\n this.parts = [];\n this.currentPart = 0;\n\n var thisScore = this;\n for (var i in arguments) {\n if (arguments[i] && this.parts[i]) {\n this.parts[i] = arguments[i];\n this.parts[i].nextPart = this.parts[i + 1];\n this.parts[i].onended = function() {\n thisScore.resetPart(i);\n playNextPart(thisScore);\n };\n }\n }\n this.looping = false;\n };\n\n p5.Score.prototype.onended = function() {\n if (this.looping) {\n // this.resetParts();\n this.parts[0].start();\n } else {\n this.parts[this.parts.length - 1].onended = function() {\n this.stop();\n this.resetParts();\n };\n }\n this.currentPart = 0;\n };\n\n /**\n * Start playback of the score.\n *\n * @method start\n * @for p5.Score\n */\n p5.Score.prototype.start = function() {\n this.parts[this.currentPart].start();\n this.scoreStep = 0;\n };\n\n /**\n * Stop playback of the score.\n *\n * @method stop\n * @for p5.Score\n */\n p5.Score.prototype.stop = function() {\n this.parts[this.currentPart].stop();\n this.currentPart = 0;\n this.scoreStep = 0;\n };\n\n /**\n * Pause playback of the score.\n *\n * @method pause\n * @for p5.Score\n */\n p5.Score.prototype.pause = function() {\n this.parts[this.currentPart].stop();\n };\n\n /**\n * Loop playback of the score.\n *\n * @method loop\n * @for p5.Score\n */\n p5.Score.prototype.loop = function() {\n this.looping = true;\n this.start();\n };\n\n /**\n * Stop looping playback of the score. If it\n * is currently playing, this will go into effect\n * after the current round of playback completes.\n *\n * @method noLoop\n * @for p5.Score\n */\n p5.Score.prototype.noLoop = function() {\n this.looping = false;\n };\n\n p5.Score.prototype.resetParts = function() {\n var self = this;\n this.parts.forEach(function(part) {\n self.resetParts[part];\n });\n };\n\n p5.Score.prototype.resetPart = function(i) {\n this.parts[i].stop();\n this.parts[i].partStep = 0;\n for (var p in this.parts[i].phrases) {\n if (this.parts[i]) {\n this.parts[i].phrases[p].phraseStep = 0;\n }\n }\n };\n\n /**\n * Set the tempo for all parts in the score\n *\n * @method setBPM\n * @for p5.Score\n * @param {Number} BPM Beats Per Minute\n * @param {Number} rampTime Seconds from now\n */\n p5.Score.prototype.setBPM = function(bpm, rampTime) {\n for (var i in this.parts) {\n if (this.parts[i]) {\n this.parts[i].setBPM(bpm, rampTime);\n }\n }\n };\n\n function playNextPart(aScore) {\n aScore.currentPart++;\n if (aScore.currentPart >= aScore.parts.length) {\n aScore.scoreStep = 0;\n aScore.onended();\n } else {\n aScore.scoreStep = 0;\n aScore.parts[aScore.currentPart - 1].stop();\n aScore.parts[aScore.currentPart].start();\n }\n }\n\n});\n","'use strict';\n\ndefine(function (require) {\n var p5sound = require('master');\n var Clock = require('Tone/core/Clock');\n\n /**\n * SoundLoop\n *\n * @class p5.SoundLoop\n * @constructor\n *\n * @param {Function} callback this function will be called on each iteration of theloop\n * @param {Number|String} [interval] amount of time or beats for each iteration of the loop\n * defaults to 1\n *\n * @example\n *
\n * var click;\n * var looper1;\n *\n * function preload() {\n * click = loadSound('assets/drum.mp3');\n * }\n *\n * function setup() {\n * //the looper's callback is passed the timeFromNow\n * //this value should be used as a reference point from\n * //which to schedule sounds\n * looper1 = new p5.SoundLoop(function(timeFromNow){\n * click.play(timeFromNow);\n * background(255 * (looper1.iterations % 2));\n * }, 2);\n *\n * //stop after 10 iteratios;\n * looper1.maxIterations = 10;\n * //start the loop\n * looper1.start();\n * }\n *
\n */\n p5.SoundLoop = function(callback, interval) {\n this.callback = callback;\n /**\n * musicalTimeMode uses Tone.Time convention\n\t * true if string, false if number\n * @property {Boolean} musicalTimeMode\n */\n this.musicalTimeMode = typeof this._interval === 'number' ? false : true;\n\n this._interval = interval || 1;\n\n /**\n * musicalTimeMode variables\n * modify these only when the interval is specified in musicalTime format as a string\n */\n this._timeSignature = 4;\n this._bpm = 60;\n\n this.isPlaying = false;\n\n /**\n * Set a limit to the number of loops to play. defaults to Infinity\n * @property {Number} maxIterations\n */\n this.maxIterations = Infinity;\n var self = this;\n\n this.clock = new Clock({\n 'callback' : function(time) {\n var timeFromNow = time - p5sound.audiocontext.currentTime;\n /**\n * Do not initiate the callback if timeFromNow is < 0\n * This ususually occurs for a few milliseconds when the page\n * is not fully loaded\n *\n * The callback should only be called until maxIterations is reached\n */\n if (timeFromNow > 0 && self.iterations <= self.maxIterations) {\n self.callback(timeFromNow);}\n },\n 'frequency' : this._calcFreq()\n });\n };\n\n /**\n * Start the loop\n * @method start\n * @for p5.SoundLoop\n * @param {Number} [timeFromNow] schedule a starting time\n */\n p5.SoundLoop.prototype.start = function(timeFromNow) {\n var t = timeFromNow || 0;\n var now = p5sound.audiocontext.currentTime;\n if (!this.isPlaying) {\n this.clock.start(now + t);\n this.isPlaying = true;\n }\n };\n\n /**\n * Stop the loop\n * @method stop\n * @for p5.SoundLoop\n * @param {Number} [timeFromNow] schedule a stopping time\n */\n p5.SoundLoop.prototype.stop = function(timeFromNow) {\n var t = timeFromNow || 0;\n var now = p5sound.audiocontext.currentTime;\n if (this.isPlaying) {\n this.clock.stop(now + t);\n this.isPlaying = false;\n }\n };\n /**\n * Pause the loop\n * @method pause\n * @for p5.SoundLoop\n * @param {Number} [timeFromNow] schedule a pausing time\n */\n p5.SoundLoop.prototype.pause = function(timeFromNow) {\n var t = timeFromNow || 0;\n var now = p5sound.audiocontext.currentTime;\n if (this.isPlaying) {\n this.clock.pause(now + t);\n this.isPlaying = false;\n }\n };\n\n\n /**\n * Synchronize loops. Use this method to start two more more loops in synchronization\n * or to start a loop in synchronization with a loop that is already playing\n * This method will schedule the implicit loop in sync with the explicit master loop\n * i.e. loopToStart.syncedStart(loopToSyncWith)\n *\n * @method syncedStart\n * @for p5.SoundLoop\n * @param {Object} otherLoop a p5.SoundLoop to sync with\n * @param {Number} [timeFromNow] Start the loops in sync after timeFromNow seconds\n */\n p5.SoundLoop.prototype.syncedStart = function(otherLoop, timeFromNow) {\n var t = timeFromNow || 0;\n var now = p5sound.audiocontext.currentTime;\n\n if (!otherLoop.isPlaying) {\n otherLoop.clock.start(now + t);\n otherLoop.isPlaying = true;\n this.clock.start(now + t);\n this.isPlaying = true;\n } else if (otherLoop.isPlaying) {\n var time = otherLoop.clock._nextTick - p5sound.audiocontext.currentTime;\n this.clock.start(now + time);\n this.isPlaying = true;\n }\n };\n\n\n /**\n * Updates frequency value, reflected in next callback\n * @private\n * @for p5.SoundLoop\n * @method _update\n */\n p5.SoundLoop.prototype._update = function() {\n this.clock.frequency.value = this._calcFreq();\n };\n\n /**\n * Calculate the frequency of the clock's callback based on bpm, interval, and timesignature\n * @private\n * @for p5.SoundLoop\n * @method _calcFreq\n * @return {Number} new clock frequency value\n */\n p5.SoundLoop.prototype._calcFreq = function() {\n //Seconds mode, bpm / timesignature has no effect\n if (typeof this._interval === 'number') {\n this.musicalTimeMode = false;\n return 1 / this._interval;\n }\n //Musical timing mode, calculate interval based bpm, interval,and time signature\n else if (typeof this._interval === 'string') {\n this.musicalTimeMode = true;\n return this._bpm / 60 / this._convertNotation(this._interval) * (this._timeSignature / 4);\n }\n };\n\n /**\n * Convert notation from musical time format to seconds\n * Uses Tone.Time convention\n * @private\n * @for p5.SoundLoop\n * @method _convertNotation\n * @param {String} value value to be converted\n * @return {Number} converted value in seconds\n */\n p5.SoundLoop.prototype._convertNotation = function(value) {\n var type = value.slice(-1);\n value = Number(value.slice(0,-1));\n switch (type) {\n case 'm':\n return this._measure(value);\n case 'n':\n return this._note(value);\n default:\n console.warn('Specified interval is not formatted correctly. See Tone.js '+\n 'timing reference for more info: https://github.com/Tonejs/Tone.js/wiki/Time');\n }\n };\n\n /**\n * Helper conversion methods of measure and note\n * @private\n * @for p5.SoundLoop\n * @method _measure\n */\n p5.SoundLoop.prototype._measure = function(value) {\n return value * this._timeSignature;\n };\n\n /**\n * @private\n * @method _note\n * @for p5.SoundLoop\n */\n p5.SoundLoop.prototype._note = function(value) {\n return this._timeSignature / value ;\n };\n\n\n /**\n * Getters and Setters, setting any paramter will result in a change in the clock's\n * frequency, that will be reflected after the next callback\n * beats per minute (defaults to 60)\n * @property {Number} bpm\n * @for p5.SoundLoop\n */\n Object.defineProperty(p5.SoundLoop.prototype, 'bpm', {\n get : function() {\n return this._bpm;\n },\n set : function(bpm) {\n if (!this.musicalTimeMode) {\n console.warn('Changing the BPM in \"seconds\" mode has no effect. '+\n 'BPM is only relevant in musicalTimeMode '+\n 'when the interval is specified as a string '+\n '(\"2n\", \"4n\", \"1m\"...etc)');\n }\n this._bpm = bpm;\n this._update();\n }\n });\n\n /**\n * number of quarter notes in a measure (defaults to 4)\n * @property {Number} timeSignature\n * @for p5.SoundLoop\n */\n Object.defineProperty(p5.SoundLoop.prototype, 'timeSignature', {\n get : function() {\n return this._timeSignature;\n },\n set : function(timeSig) {\n if (!this.musicalTimeMode) {\n console.warn('Changing the timeSignature in \"seconds\" mode has no effect. '+\n 'BPM is only relevant in musicalTimeMode '+\n 'when the interval is specified as a string '+\n '(\"2n\", \"4n\", \"1m\"...etc)');\n }\n this._timeSignature = timeSig;\n this._update();\n }\n });\n\n /**\n * length of the loops interval\n * @property {Number|String} interval\n * @for p5.SoundLoop\n */\n Object.defineProperty(p5.SoundLoop.prototype, 'interval', {\n get : function() {\n return this._interval;\n },\n set : function(interval) {\n this.musicalTimeMode = typeof interval === 'Number'? false : true;\n this._interval = interval;\n this._update();\n }\n });\n\n /**\n * how many times the callback has been called so far\n * @property {Number} iterations\n * @for p5.SoundLoop\n * @readonly\n */\n Object.defineProperty(p5.SoundLoop.prototype, 'iterations', {\n get : function() {\n return this.clock.ticks;\n }\n });\n\n return p5.SoundLoop;\n});\n","define(function (require) {\n\t'use strict';\n\n\tvar p5sound = require('master');\n\tvar Effect = require('effect');\n var CustomError = require('errorHandler');\n\n /**\n * Compressor is an audio effect class that performs dynamics compression\n * on an audio input source. This is a very commonly used technique in music\n * and sound production. Compression creates an overall louder, richer,\n * and fuller sound by lowering the volume of louds and raising that of softs.\n * Compression can be used to avoid clipping (sound distortion due to\n * peaks in volume) and is especially useful when many sounds are played\n * at once. Compression can be used on indivudal sound sources in addition\n * to the master output.\n *\n * This class extends p5.Effect.\n * Methods amp(), chain(),\n * drywet(), connect(), and\n * disconnect() are available.\n *\n * @class p5.Compressor\n * @constructor\n * @extends p5.Effect\n *\n *\n */\n\tp5.Compressor = function() {\n\t\tEffect.call(this);\n\n /**\n * The p5.Compressor is built with a Web Audio Dynamics Compressor Node\n * \n * @property {AudioNode} compressor\n */\n\n\n\t\tthis.compressor = this.ac.createDynamicsCompressor();\n\n this.input.connect(this.compressor);\n this.compressor.connect(this.wet);\n\t};\n\n\tp5.Compressor.prototype = Object.create(Effect.prototype);\n\n /**\n * Performs the same function as .connect, but also accepts\n * optional parameters to set compressor's audioParams\n * @method process\n * @for p5.Compressor\n *\n * @param {Object} src Sound source to be connected\n *\n * @param {Number} [attack] The amount of time (in seconds) to reduce the gain by 10dB,\n * default = .003, range 0 - 1\n * @param {Number} [knee] A decibel value representing the range above the\n * threshold where the curve smoothly transitions to the \"ratio\" portion.\n * default = 30, range 0 - 40\n * @param {Number} [ratio] The amount of dB change in input for a 1 dB change in output\n * default = 12, range 1 - 20\n * @param {Number} [threshold] The decibel value above which the compression will start taking effect\n * default = -24, range -100 - 0\n * @param {Number} [release] The amount of time (in seconds) to increase the gain by 10dB\n * default = .25, range 0 - 1\n */\n\tp5.Compressor.prototype.process = function(src, attack, knee,\n ratio, threshold, release) {\n\t\tsrc.connect(this.input);\n\t\tthis.set(attack, knee, ratio, threshold, release);\n\t};\n\n /**\n * Set the paramters of a compressor.\n * @method set\n * @for p5.Compressor\n * @param {Number} attack The amount of time (in seconds) to reduce the gain by 10dB,\n * default = .003, range 0 - 1\n * @param {Number} knee A decibel value representing the range above the\n * threshold where the curve smoothly transitions to the \"ratio\" portion.\n * default = 30, range 0 - 40\n * @param {Number} ratio The amount of dB change in input for a 1 dB change in output\n * default = 12, range 1 - 20\n * @param {Number} threshold The decibel value above which the compression will start taking effect\n * default = -24, range -100 - 0\n * @param {Number} release The amount of time (in seconds) to increase the gain by 10dB\n * default = .25, range 0 - 1\n */\n p5.Compressor.prototype.set = function (attack, knee,\n ratio, threshold, release) {\n\n if (typeof attack !== 'undefined') {this.attack(attack);}\n if (typeof knee !== 'undefined') {this.knee(knee);}\n if (typeof ratio !== 'undefined') {this.ratio(ratio);}\n if (typeof threshold !== 'undefined') {this.threshold(threshold);}\n if (typeof release !== 'undefined') {this.release(release);}\n };\n\n\n /**\n * Get current attack or set value w/ time ramp\n *\n *\n * @method attack\n * @for p5.Compressor\n * @param {Number} [attack] Attack is the amount of time (in seconds) to reduce the gain by 10dB,\n * default = .003, range 0 - 1\n * @param {Number} [time] Assign time value to schedule the change in value\n */\n p5.Compressor.prototype.attack = function (attack, time){\n var t = time || 0;\n if (typeof attack == 'number'){\n this.compressor.attack.value = attack;\n this.compressor.attack.cancelScheduledValues(this.ac.currentTime + 0.01 + t);\n this.compressor.attack.linearRampToValueAtTime(attack, this.ac.currentTime + 0.02 + t);\n } else if (typeof attack !== 'undefined') {\n attack.connect(this.compressor.attack);\n }\n return this.compressor.attack.value;\n };\n\n\n /**\n * Get current knee or set value w/ time ramp\n *\n * @method knee\n * @for p5.Compressor\n * @param {Number} [knee] A decibel value representing the range above the\n * threshold where the curve smoothly transitions to the \"ratio\" portion.\n * default = 30, range 0 - 40\n * @param {Number} [time] Assign time value to schedule the change in value\n */\n p5.Compressor.prototype.knee = function (knee, time){\n var t = time || 0;\n if (typeof knee == 'number'){\n this.compressor.knee.value = knee;\n this.compressor.knee.cancelScheduledValues(this.ac.currentTime + 0.01 + t);\n this.compressor.knee.linearRampToValueAtTime(knee, this.ac.currentTime + 0.02 + t);\n } else if (typeof knee !== 'undefined') {\n knee.connect(this.compressor.knee);\n }\n return this.compressor.knee.value;\n };\n\n\n /**\n * Get current ratio or set value w/ time ramp\n * @method ratio\n * @for p5.Compressor\n * @param {Number} [ratio] The amount of dB change in input for a 1 dB change in output\n * default = 12, range 1 - 20\n * @param {Number} [time] Assign time value to schedule the change in value\n */\n p5.Compressor.prototype.ratio = function (ratio, time){\n var t = time || 0;\n if (typeof ratio == 'number'){\n this.compressor.ratio.value = ratio;\n this.compressor.ratio.cancelScheduledValues(this.ac.currentTime + 0.01 + t);\n this.compressor.ratio.linearRampToValueAtTime(ratio, this.ac.currentTime + 0.02 + t);\n } else if (typeof ratio !== 'undefined') {\n ratio.connect(this.compressor.ratio);\n }\n return this.compressor.ratio.value;\n };\n\n\n /**\n * Get current threshold or set value w/ time ramp\n * @method threshold\n * @for p5.Compressor\n * @param {Number} threshold The decibel value above which the compression will start taking effect\n * default = -24, range -100 - 0\n * @param {Number} [time] Assign time value to schedule the change in value\n */\n p5.Compressor.prototype.threshold = function (threshold, time){\n var t = time || 0;\n if (typeof threshold == 'number'){\n this.compressor.threshold.value = threshold;\n this.compressor.threshold.cancelScheduledValues(this.ac.currentTime + 0.01 + t);\n this.compressor.threshold.linearRampToValueAtTime(threshold, this.ac.currentTime + 0.02 + t);\n } else if (typeof threshold !== 'undefined') {\n threshold.connect(this.compressor.threshold);\n }\n return this.compressor.threshold.value;\n };\n\n\n /**\n * Get current release or set value w/ time ramp\n * @method release\n * @for p5.Compressor\n * @param {Number} release The amount of time (in seconds) to increase the gain by 10dB\n * default = .25, range 0 - 1\n *\n * @param {Number} [time] Assign time value to schedule the change in value\n */\n p5.Compressor.prototype.release = function (release, time){\n var t = time || 0;\n if (typeof release == 'number'){\n this.compressor.release.value = release;\n this.compressor.release.cancelScheduledValues(this.ac.currentTime + 0.01 + t);\n this.compressor.release.linearRampToValueAtTime(release, this.ac.currentTime + 0.02 + t);\n } else if (typeof number !== 'undefined') {\n release.connect(this.compressor.release);\n }\n return this.compressor.release.value;\n };\n\n /**\n * Return the current reduction value\n *\n * @method reduction\n * @for p5.Compressor\n * @return {Number} Value of the amount of gain reduction that is applied to the signal\n */\n p5.Compressor.prototype.reduction =function() {\n return this.compressor.reduction.value;\n };\n\n\n\tp5.Compressor.prototype.dispose = function() {\n Effect.prototype.dispose.apply(this);\n if (this.compressor) {\n this.compressor.disconnect();\n delete this.compressor;\n }\n\t};\n\n return p5.Compressor;\n});\n","'use strict';\n\ndefine(function (require) {\n\n // inspiration: recorder.js, Tone.js & typedarray.org\n\n var p5sound = require('master');\n var convertToWav = require('helpers').convertToWav;\n var processorNames = require('./audioWorklet/processorNames');\n var ac = p5sound.audiocontext;\n\n /**\n *
Record sounds for playback and/or to save as a .wav file.\n * The p5.SoundRecorder records all sound output from your sketch,\n * or can be assigned a specific source with setInput().
\n *
The record() method accepts a p5.SoundFile as a parameter.\n * When playback is stopped (either after the given amount of time,\n * or with the stop() method), the p5.SoundRecorder will send its\n * recording to that p5.SoundFile for playback.
\n * var mic, recorder, soundFile;\n * var state = 0;\n *\n * function setup() {\n * background(200);\n * // create an audio in\n * mic = new p5.AudioIn();\n *\n * // prompts user to enable their browser mic\n * mic.start();\n *\n * // create a sound recorder\n * recorder = new p5.SoundRecorder();\n *\n * // connect the mic to the recorder\n * recorder.setInput(mic);\n *\n * // this sound file will be used to\n * // playback & save the recording\n * soundFile = new p5.SoundFile();\n *\n * text('keyPress to record', 20, 20);\n * }\n *\n * function keyPressed() {\n * // make sure user enabled the mic\n * if (state === 0 && mic.enabled) {\n *\n * // record to our p5.SoundFile\n * recorder.record(soundFile);\n *\n * background(255,0,0);\n * text('Recording!', 20, 20);\n * state++;\n * }\n * else if (state === 1) {\n * background(0,255,0);\n *\n * // stop recorder and\n * // send result to soundFile\n * recorder.stop();\n *\n * text('Stopped', 20, 20);\n * state++;\n * }\n *\n * else if (state === 2) {\n * soundFile.play(); // play the result!\n * save(soundFile, 'mySound.wav');\n * state++;\n * }\n * }\n *
\n */\n p5.SoundRecorder = function() {\n this.input = ac.createGain();\n this.output = ac.createGain();\n\n this._inputChannels = 2;\n this._outputChannels = 2; // stereo output, even if input is mono\n\n this._workletNode = new AudioWorkletNode(ac, processorNames.recorderProcessor, {\n outputChannelCount: [this._outputChannels],\n processorOptions: { numInputChannels: this._inputChannels }\n });\n\n this._workletNode.port.onmessage = function(event) {\n if (event.data.name === 'buffers') {\n const buffers = [\n new Float32Array(event.data.leftBuffer),\n new Float32Array(event.data.rightBuffer)\n ];\n this._callback(buffers);\n }\n }.bind(this);\n\n /**\n * callback invoked when the recording is over\n * @private\n * @type Function(Float32Array)\n */\n this._callback = function() {};\n\n // connections\n this._workletNode.connect(p5.soundOut._silentNode);\n this.setInput();\n\n // add this p5.SoundFile to the soundArray\n p5sound.soundArray.push(this);\n };\n\n /**\n * Connect a specific device to the p5.SoundRecorder.\n * If no parameter is given, p5.SoundRecorer will record\n * all audible p5.sound from your sketch.\n *\n * @method setInput\n * @for p5.SoundRecorder\n * @param {Object} [unit] p5.sound object or a web audio unit\n * that outputs sound\n */\n p5.SoundRecorder.prototype.setInput = function(unit) {\n this.input.disconnect();\n this.input = null;\n this.input = ac.createGain();\n this.input.connect(this._workletNode);\n this.input.connect(this.output);\n if (unit) {\n unit.connect(this.input);\n } else {\n p5.soundOut.output.connect(this.input);\n }\n };\n\n /**\n * Start recording. To access the recording, provide\n * a p5.SoundFile as the first parameter. The p5.SoundRecorder\n * will send its recording to that p5.SoundFile for playback once\n * recording is complete. Optional parameters include duration\n * (in seconds) of the recording, and a callback function that\n * will be called once the complete recording has been\n * transfered to the p5.SoundFile.\n *\n * @method record\n * @for p5.SoundRecorder\n * @param {p5.SoundFile} soundFile p5.SoundFile\n * @param {Number} [duration] Time (in seconds)\n * @param {Function} [callback] The name of a function that will be\n * called once the recording completes\n */\n p5.SoundRecorder.prototype.record = function(sFile, duration, callback) {\n this._workletNode.port.postMessage({ name: 'start', duration: duration });\n\n if (sFile && callback) {\n this._callback = function(buffer) {\n sFile.setBuffer(buffer);\n callback();\n };\n }\n else if (sFile) {\n this._callback = function(buffer) {\n sFile.setBuffer(buffer);\n };\n }\n };\n\n /**\n * Stop the recording. Once the recording is stopped,\n * the results will be sent to the p5.SoundFile that\n * was given on .record(), and if a callback function\n * was provided on record, that function will be called.\n *\n * @method stop\n * @for p5.SoundRecorder\n */\n p5.SoundRecorder.prototype.stop = function() {\n this._workletNode.port.postMessage({ name: 'stop' });\n };\n\n p5.SoundRecorder.prototype.dispose = function() {\n // remove reference from soundArray\n var index = p5sound.soundArray.indexOf(this);\n p5sound.soundArray.splice(index, 1);\n\n this._callback = function() {};\n if (this.input) {\n this.input.disconnect();\n }\n this.input = null;\n this._workletNode = null;\n };\n\n\n /**\n * Save a p5.SoundFile as a .wav file. The browser will prompt the user\n * to download the file to their device.\n * For uploading audio to a server, use\n * `p5.SoundFile.saveBlob`.\n *\n * @for p5\n * @method saveSound\n * @param {p5.SoundFile} soundFile p5.SoundFile that you wish to save\n * @param {String} fileName name of the resulting .wav file.\n */\n // add to p5.prototype as this is used by the p5 `save()` method.\n p5.prototype.saveSound = function (soundFile, fileName) {\n const dataView = convertToWav(soundFile.buffer);\n p5.prototype.writeFile([dataView], fileName, 'wav');\n };\n});\n","'use strict';\n\ndefine(function () {\n /**\n *
PeakDetect works in conjunction with p5.FFT to\n * look for onsets in some or all of the frequency spectrum.\n *
\n *
\n * To use p5.PeakDetect, call update in the draw loop\n * and pass in a p5.FFT object.\n *
\n *
\n * You can listen for a specific part of the frequency spectrum by\n * setting the range between freq1 and freq2.\n *
\n *\n *
threshold is the threshold for detecting a peak,\n * scaled between 0 and 1. It is logarithmic, so 0.1 is half as loud\n * as 1.0.
\n *\n *
\n * The update method is meant to be run in the draw loop, and\n * frames determines how many loops must pass before\n * another peak can be detected.\n * For example, if the frameRate() = 60, you could detect the beat of a\n * 120 beat-per-minute song with this equation:\n * framesPerPeak = 60 / (estimatedBPM / 60 );\n *
\n *\n *
\n * Based on example contribtued by @b2renger, and a simple beat detection\n * explanation by Felix Turner.\n *
\n *\n * @class p5.PeakDetect\n * @constructor\n * @param {Number} [freq1] lowFrequency - defaults to 20Hz\n * @param {Number} [freq2] highFrequency - defaults to 20000 Hz\n * @param {Number} [threshold] Threshold for detecting a beat between 0 and 1\n * scaled logarithmically where 0.1 is 1/2 the loudness\n * of 1.0. Defaults to 0.35.\n * @param {Number} [framesPerPeak] Defaults to 20.\n * @example\n *
\n */\n p5.PeakDetect = function(freq1, freq2, threshold, _framesPerPeak) {\n // framesPerPeak determines how often to look for a beat.\n // If a beat is provided, try to look for a beat based on bpm\n this.framesPerPeak = _framesPerPeak || 20;\n this.framesSinceLastPeak = 0;\n this.decayRate = 0.95;\n\n this.threshold = threshold || 0.35;\n this.cutoff = 0;\n\n // how much to increase the cutoff\n // TO DO: document this / figure out how to make it accessible\n this.cutoffMult = 1.5;\n\n this.energy = 0;\n this.penergy = 0;\n\n // TO DO: document this property / figure out how to make it accessible\n this.currentValue = 0;\n\n /**\n * isDetected is set to true when a peak is detected.\n *\n * @attribute isDetected {Boolean}\n * @default false\n */\n this.isDetected = false;\n\n this.f1 = freq1 || 40;\n this.f2 = freq2 || 20000;\n\n // function to call when a peak is detected\n this._onPeak = function() {};\n };\n\n\n /**\n * The update method is run in the draw loop.\n *\n * Accepts an FFT object. You must call .analyze()\n * on the FFT object prior to updating the peakDetect\n * because it relies on a completed FFT analysis.\n *\n * @method update\n * @param {p5.FFT} fftObject A p5.FFT object\n */\n p5.PeakDetect.prototype.update = function(fftObject) {\n var nrg = this.energy = fftObject.getEnergy(this.f1,this.f2)/255;\n if (nrg > this.cutoff && nrg > this.threshold && nrg-this.penergy > 0) {\n\n // trigger callback\n this._onPeak();\n this.isDetected = true;\n\n // debounce\n this.cutoff = nrg * this.cutoffMult;\n this.framesSinceLastPeak = 0;\n } else {\n this.isDetected = false;\n if (this.framesSinceLastPeak <= this.framesPerPeak) {\n this.framesSinceLastPeak++;\n } else {\n this.cutoff *= this.decayRate;\n this.cutoff = Math.max(this.cutoff, this.threshold);\n }\n }\n\n this.currentValue = nrg;\n this.penergy = nrg;\n };\n\n /**\n * onPeak accepts two arguments: a function to call when\n * a peak is detected. The value of the peak,\n * between 0.0 and 1.0, is passed to the callback.\n *\n * @method onPeak\n * @param {Function} callback Name of a function that will\n * be called when a peak is\n * detected.\n * @param {Object} [val] Optional value to pass\n * into the function when\n * a peak is detected.\n * @example\n *
\n * var cnv, soundFile, fft, peakDetect;\n * var ellipseWidth = 0;\n *\n * function preload() {\n * soundFile = loadSound('assets/beat.mp3');\n * }\n *\n * function setup() {\n * cnv = createCanvas(100,100);\n * textAlign(CENTER);\n *\n * fft = new p5.FFT();\n * peakDetect = new p5.PeakDetect();\n *\n * setupSound();\n *\n * // when a beat is detected, call triggerBeat()\n * peakDetect.onPeak(triggerBeat);\n * }\n *\n * function draw() {\n * background(0);\n * fill(255);\n * text('click to play', width/2, height/2);\n *\n * fft.analyze();\n * peakDetect.update(fft);\n *\n * ellipseWidth *= 0.95;\n * ellipse(width/2, height/2, ellipseWidth, ellipseWidth);\n * }\n *\n * // this function is called by peakDetect.onPeak\n * function triggerBeat() {\n * ellipseWidth = 50;\n * }\n *\n * // mouseclick starts/stops sound\n * function setupSound() {\n * cnv.mouseClicked( function() {\n * if (soundFile.isPlaying() ) {\n * soundFile.stop();\n * } else {\n * soundFile.play();\n * }\n * });\n * }\n *
\n */\n p5.PeakDetect.prototype.onPeak = function(callback, val) {\n var self = this;\n\n self._onPeak = function() {\n callback(self.energy, val);\n };\n };\n\n});\n","'use strict';\n\ndefine(function (require) {\n var p5sound = require('master');\n\n /**\n * A gain node is usefull to set the relative volume of sound.\n * It's typically used to build mixers.\n *\n * @class p5.Gain\n * @constructor\n * @example\n *
\n *\n * // load two soundfile and crossfade beetween them\n * var sound1,sound2;\n * var gain1, gain2, gain3;\n *\n * function preload(){\n * soundFormats('ogg', 'mp3');\n * sound1 = loadSound('assets/Damscray_-_Dancing_Tiger_01');\n * sound2 = loadSound('assets/beat.mp3');\n * }\n *\n * function setup() {\n * createCanvas(400,200);\n *\n * // create a 'master' gain to which we will connect both soundfiles\n * gain3 = new p5.Gain();\n * gain3.connect();\n *\n * // setup first sound for playing\n * sound1.rate(1);\n * sound1.loop();\n * sound1.disconnect(); // diconnect from p5 output\n *\n * gain1 = new p5.Gain(); // setup a gain node\n * gain1.setInput(sound1); // connect the first sound to its input\n * gain1.connect(gain3); // connect its output to the 'master'\n *\n * sound2.rate(1);\n * sound2.disconnect();\n * sound2.loop();\n *\n * gain2 = new p5.Gain();\n * gain2.setInput(sound2);\n * gain2.connect(gain3);\n *\n * }\n *\n * function draw(){\n * background(180);\n *\n * // calculate the horizontal distance beetween the mouse and the right of the screen\n * var d = dist(mouseX,0,width,0);\n *\n * // map the horizontal position of the mouse to values useable for volume control of sound1\n * var vol1 = map(mouseX,0,width,0,1);\n * var vol2 = 1-vol1; // when sound1 is loud, sound2 is quiet and vice versa\n *\n * gain1.amp(vol1,0.5,0);\n * gain2.amp(vol2,0.5,0);\n *\n * // map the vertical position of the mouse to values useable for 'master volume control'\n * var vol3 = map(mouseY,0,height,0,1);\n * gain3.amp(vol3,0.5,0);\n * }\n *
\n *\n */\n\n p5.Gain = function() {\n this.ac = p5sound.audiocontext;\n\n this.input = this.ac.createGain();\n this.output = this.ac.createGain();\n\n // otherwise, Safari distorts\n this.input.gain.value = 0.5;\n this.input.connect(this.output);\n\n // add to the soundArray\n p5sound.soundArray.push(this);\n };\n\n /**\n * Connect a source to the gain node.\n *\n * @method setInput\n * @for p5.Gain\n * @param {Object} src p5.sound / Web Audio object with a sound\n * output.\n */\n\n\n p5.Gain.prototype.setInput = function(src) {\n src.connect(this.input);\n };\n\n /**\n * Send output to a p5.sound or web audio object\n *\n * @method connect\n * @for p5.Gain\n * @param {Object} unit\n */\n p5.Gain.prototype.connect = function(unit) {\n var u = unit || p5.soundOut.input;\n this.output.connect(u.input ? u.input : u);\n };\n\n /**\n * Disconnect all output.\n *\n * @method disconnect\n * @for p5.Gain\n */\n p5.Gain.prototype.disconnect = function() {\n if (this.output) {\n this.output.disconnect();\n }\n };\n\n /**\n * Set the output level of the gain node.\n *\n * @method amp\n * @for p5.Gain\n * @param {Number} volume amplitude between 0 and 1.0\n * @param {Number} [rampTime] create a fade that lasts rampTime\n * @param {Number} [timeFromNow] schedule this event to happen\n * seconds from now\n */\n p5.Gain.prototype.amp = function(vol, rampTime, tFromNow) {\n var rampTime = rampTime || 0;\n var tFromNow = tFromNow || 0;\n var now = p5sound.audiocontext.currentTime;\n var currentVol = this.output.gain.value;\n this.output.gain.cancelScheduledValues(now);\n this.output.gain.linearRampToValueAtTime(currentVol, now + tFromNow);\n this.output.gain.linearRampToValueAtTime(vol, now + tFromNow + rampTime);\n };\n\n p5.Gain.prototype.dispose = function() {\n // remove reference from soundArray\n var index = p5sound.soundArray.indexOf(this);\n p5sound.soundArray.splice(index, 1);\n if (this.output) {\n this.output.disconnect();\n delete this.output;\n }\n if (this.input) {\n this.input.disconnect();\n delete this.input;\n }\n };\n\n});\n","'use strict';\n\ndefine(function (require) {\n\n var Effect = require('effect');\n\n /*\n * Adapted from [Kevin Ennis on StackOverflow](http://stackoverflow.com/questions/22312841/waveshaper-node-in-webaudio-how-to-emulate-distortion)\n */\n function makeDistortionCurve(amount) {\n var k = typeof amount === 'number' ? amount : 50;\n var numSamples = 44100;\n var curve = new Float32Array(numSamples);\n var deg = Math.PI / 180;\n var i = 0;\n var x;\n for ( ; i < numSamples; ++i ) {\n x = i * 2 / numSamples - 1;\n curve[i] = ( 3 + k ) * x * 20 * deg / ( Math.PI + k * Math.abs(x) );\n }\n return curve;\n }\n\n /**\n * A Distortion effect created with a Waveshaper Node,\n * with an approach adapted from\n * [Kevin Ennis](http://stackoverflow.com/questions/22312841/waveshaper-node-in-webaudio-how-to-emulate-distortion)\n *\n * This class extends p5.Effect.\n * Methods amp(), chain(),\n * drywet(), connect(), and\n * disconnect() are available.\n *\n * @class p5.Distortion\n * @extends p5.Effect\n * @constructor\n * @param {Number} [amount=0.25] Unbounded distortion amount.\n * Normal values range from 0-1.\n * @param {String} [oversample='none'] 'none', '2x', or '4x'.\n *\n */\n p5.Distortion = function(amount, oversample) {\n Effect.call(this);\n\n if (typeof amount === 'undefined') {\n amount = 0.25;\n } if (typeof amount !== 'number') {\n throw new Error('amount must be a number');\n } if (typeof oversample === 'undefined') {\n oversample = '2x';\n } if (typeof oversample !== 'string') {\n throw new Error('oversample must be a String');\n }\n\n var curveAmount = p5.prototype.map(amount, 0.0, 1.0, 0, 2000);\n\n /**\n * The p5.Distortion is built with a\n * \n * Web Audio WaveShaper Node.\n *\n * @property {AudioNode} WaveShaperNode\n */\n this.waveShaperNode = this.ac.createWaveShaper();\n\n this.amount = curveAmount;\n this.waveShaperNode.curve = makeDistortionCurve(curveAmount);\n this.waveShaperNode.oversample = oversample;\n\n this.input.connect(this.waveShaperNode);\n\n this.waveShaperNode.connect(this.wet);\n };\n\n p5.Distortion.prototype = Object.create(Effect.prototype);\n\n\n /**\n * Process a sound source, optionally specify amount and oversample values.\n *\n * @method process\n * @for p5.Distortion\n * @param {Number} [amount=0.25] Unbounded distortion amount.\n * Normal values range from 0-1.\n * @param {String} [oversample='none'] 'none', '2x', or '4x'.\n */\n p5.Distortion.prototype.process = function(src, amount, oversample) {\n src.connect(this.input);\n this.set(amount, oversample);\n };\n\n /**\n * Set the amount and oversample of the waveshaper distortion.\n *\n * @method set\n * @for p5.Distortion\n * @param {Number} [amount=0.25] Unbounded distortion amount.\n * Normal values range from 0-1.\n * @param {String} [oversample='none'] 'none', '2x', or '4x'.\n */\n p5.Distortion.prototype.set = function(amount, oversample) {\n if (amount) {\n var curveAmount = p5.prototype.map(amount, 0.0, 1.0, 0, 2000);\n this.amount = curveAmount;\n this.waveShaperNode.curve = makeDistortionCurve(curveAmount);\n }\n if (oversample) {\n this.waveShaperNode.oversample = oversample;\n }\n };\n\n /**\n * Return the distortion amount, typically between 0-1.\n *\n * @method getAmount\n * @for p5.Distortion\n * @return {Number} Unbounded distortion amount.\n * Normal values range from 0-1.\n */\n p5.Distortion.prototype.getAmount = function() {\n return this.amount;\n };\n\n /**\n * Return the oversampling.\n *\n * @method getOversample\n * @for p5.Distortion\n * @return {String} Oversample can either be 'none', '2x', or '4x'.\n */\n p5.Distortion.prototype.getOversample = function() {\n return this.waveShaperNode.oversample;\n };\n\n\n p5.Distortion.prototype.dispose = function() {\n Effect.prototype.dispose.apply(this);\n if (this.waveShaperNode) {\n this.waveShaperNode.disconnect();\n this.waveShaperNode = null;\n }\n };\n});\n"],"sourceRoot":""}
\ No newline at end of file
diff --git a/src/audioWorklet/soundFileProcessor.js b/src/audioWorklet/soundFileProcessor.js
index b9abaffd..a442b2d5 100644
--- a/src/audioWorklet/soundFileProcessor.js
+++ b/src/audioWorklet/soundFileProcessor.js
@@ -2,12 +2,29 @@
const processorNames = preval.require('./processorNames');
class SoundFileProcessor extends AudioWorkletProcessor {
+ constructor() {
+ super();
+
+ this.paused = false;
+
+ this.port.onmessage = (event) => {
+ const data = event.data;
+ if (data.name === 'play') {
+ this.paused = false;
+ } else if (data.name === 'pause') {
+ this.paused = true;
+ }
+ };
+ }
+
process(inputs) {
const input = inputs[0];
const inputChannel = input[0];
const position = inputChannel[inputChannel.length - 1] || 0;
- this.port.postMessage({ name: 'position', position: position });
+ if (!this.paused) {
+ this.port.postMessage({ name: 'position', position: position });
+ }
return true;
}
diff --git a/src/soundfile.js b/src/soundfile.js
index 8924b179..d402e2a3 100644
--- a/src/soundfile.js
+++ b/src/soundfile.js
@@ -140,7 +140,6 @@ define(function (require) {
this._whileLoading = function() {};
}
- this._onAudioProcess = _onAudioProcess.bind(this);
this._clearOnEnd = _clearOnEnd.bind(this);
};
@@ -351,7 +350,6 @@ define(function (require) {
return;
}
- var self = this;
var now = p5sound.audiocontext.currentTime;
var cueStart, cueEnd;
var time = startTime || 0;
@@ -440,6 +438,8 @@ define(function (require) {
this._counterNode.loopStart = cueStart;
this._counterNode.loopEnd = cueEnd;
}
+
+ this._workletNode.port.postMessage({ name: 'play' });
};
@@ -539,6 +539,8 @@ define(function (require) {
var pTime = time + now;
if (this.isPlaying() && this.buffer && this.bufferSourceNode) {
+ this._workletNode.port.postMessage({ name: 'pause' });
+
this.pauseTime = this.currentTime();
this.bufferSourceNode.stop(pTime);
this._counterNode.stop(pTime);
@@ -1753,16 +1755,6 @@ define(function (require) {
return new Blob([dataView], { type: 'audio/wav' });
};
- // event handler to keep track of current position
- function _onAudioProcess(processEvent) {
- var inputBuffer = processEvent.inputBuffer.getChannelData(0);
-
- this._lastPos = inputBuffer[inputBuffer.length - 1] || 0;
-
- // do any callbacks that have been scheduled
- this._onTimeUpdate(self._lastPos);
- }
-
// event handler to remove references to the bufferSourceNode when it is done playing
function _clearOnEnd(e) {
const thisBufferSourceNode = e.target;
From f0b6713a4c175d966e03f5f145b5e6a0509cb868 Mon Sep 17 00:00:00 2001
From: Oren Shoham
Date: Fri, 16 Aug 2019 17:14:04 -0400
Subject: [PATCH 3/4] Fix p5.SoundFile pause functionality on Firefox and
Safari by moving pause position logic out of AudioWorklet processor
---
lib/p5.sound.js | 27 +++++++++++++-------------
lib/p5.sound.js.map | 2 +-
lib/p5.sound.min.js | 2 +-
lib/p5.sound.min.js.map | 2 +-
src/audioWorklet/soundFileProcessor.js | 19 +-----------------
src/soundfile.js | 15 +++++++-------
6 files changed, 25 insertions(+), 42 deletions(-)
diff --git a/lib/p5.sound.js b/lib/p5.sound.js
index 86bf5b8b..93cf77b9 100644
--- a/lib/p5.sound.js
+++ b/lib/p5.sound.js
@@ -3467,7 +3467,7 @@ __webpack_require__.r(__webpack_exports__);
"use strict";
__webpack_require__.r(__webpack_exports__);
-/* harmony default export */ __webpack_exports__["default"] = ("function _typeof(obj) { if (typeof Symbol === \"function\" && typeof Symbol.iterator === \"symbol\") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === \"function\" && obj.constructor === Symbol && obj !== Symbol.prototype ? \"symbol\" : typeof obj; }; } return _typeof(obj); }\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\nfunction _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if (\"value\" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }\n\nfunction _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }\n\nfunction _possibleConstructorReturn(self, call) { if (call && (_typeof(call) === \"object\" || typeof call === \"function\")) { return call; } return _assertThisInitialized(self); }\n\nfunction _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError(\"this hasn't been initialised - super() hasn't been called\"); } return self; }\n\nfunction _inherits(subClass, superClass) { if (typeof superClass !== \"function\" && superClass !== null) { throw new TypeError(\"Super expression must either be null or a function\"); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, writable: true, configurable: true } }); if (superClass) _setPrototypeOf(subClass, superClass); }\n\nfunction _wrapNativeSuper(Class) { var _cache = typeof Map === \"function\" ? new Map() : undefined; _wrapNativeSuper = function _wrapNativeSuper(Class) { if (Class === null || !_isNativeFunction(Class)) return Class; if (typeof Class !== \"function\") { throw new TypeError(\"Super expression must either be null or a function\"); } if (typeof _cache !== \"undefined\") { if (_cache.has(Class)) return _cache.get(Class); _cache.set(Class, Wrapper); } function Wrapper() { return _construct(Class, arguments, _getPrototypeOf(this).constructor); } Wrapper.prototype = Object.create(Class.prototype, { constructor: { value: Wrapper, enumerable: false, writable: true, configurable: true } }); return _setPrototypeOf(Wrapper, Class); }; return _wrapNativeSuper(Class); }\n\nfunction isNativeReflectConstruct() { if (typeof Reflect === \"undefined\" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === \"function\") return true; try { Date.prototype.toString.call(Reflect.construct(Date, [], function () {})); return true; } catch (e) { return false; } }\n\nfunction _construct(Parent, args, Class) { if (isNativeReflectConstruct()) { _construct = Reflect.construct; } else { _construct = function _construct(Parent, args, Class) { var a = [null]; a.push.apply(a, args); var Constructor = Function.bind.apply(Parent, a); var instance = new Constructor(); if (Class) _setPrototypeOf(instance, Class.prototype); return instance; }; } return _construct.apply(null, arguments); }\n\nfunction _isNativeFunction(fn) { return Function.toString.call(fn).indexOf(\"[native code]\") !== -1; }\n\nfunction _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); }\n\nfunction _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); }; return _getPrototypeOf(o); }\n\n// import processor name via preval.require so that it's available as a value at compile time\nvar processorNames = {\n \"recorderProcessor\": \"recorder-processor\",\n \"soundFileProcessor\": \"sound-file-processor\",\n \"amplitudeProcessor\": \"amplitude-processor\"\n};\n\nvar SoundFileProcessor =\n/*#__PURE__*/\nfunction (_AudioWorkletProcesso) {\n _inherits(SoundFileProcessor, _AudioWorkletProcesso);\n\n function SoundFileProcessor() {\n var _this;\n\n _classCallCheck(this, SoundFileProcessor);\n\n _this = _possibleConstructorReturn(this, _getPrototypeOf(SoundFileProcessor).call(this));\n _this.paused = false;\n\n _this.port.onmessage = function (event) {\n var data = event.data;\n\n if (data.name === 'play') {\n _this.paused = false;\n } else if (data.name === 'pause') {\n _this.paused = true;\n }\n };\n\n return _this;\n }\n\n _createClass(SoundFileProcessor, [{\n key: \"process\",\n value: function process(inputs) {\n var input = inputs[0];\n var inputChannel = input[0];\n var position = inputChannel[inputChannel.length - 1];\n\n if (!this.paused) {\n this.port.postMessage({\n name: 'position',\n position: position\n });\n }\n\n return true;\n }\n }]);\n\n return SoundFileProcessor;\n}(_wrapNativeSuper(AudioWorkletProcessor));\n\nregisterProcessor(processorNames.soundFileProcessor, SoundFileProcessor);");
+/* harmony default export */ __webpack_exports__["default"] = ("function _typeof(obj) { if (typeof Symbol === \"function\" && typeof Symbol.iterator === \"symbol\") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === \"function\" && obj.constructor === Symbol && obj !== Symbol.prototype ? \"symbol\" : typeof obj; }; } return _typeof(obj); }\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\nfunction _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if (\"value\" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }\n\nfunction _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }\n\nfunction _possibleConstructorReturn(self, call) { if (call && (_typeof(call) === \"object\" || typeof call === \"function\")) { return call; } return _assertThisInitialized(self); }\n\nfunction _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError(\"this hasn't been initialised - super() hasn't been called\"); } return self; }\n\nfunction _inherits(subClass, superClass) { if (typeof superClass !== \"function\" && superClass !== null) { throw new TypeError(\"Super expression must either be null or a function\"); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, writable: true, configurable: true } }); if (superClass) _setPrototypeOf(subClass, superClass); }\n\nfunction _wrapNativeSuper(Class) { var _cache = typeof Map === \"function\" ? new Map() : undefined; _wrapNativeSuper = function _wrapNativeSuper(Class) { if (Class === null || !_isNativeFunction(Class)) return Class; if (typeof Class !== \"function\") { throw new TypeError(\"Super expression must either be null or a function\"); } if (typeof _cache !== \"undefined\") { if (_cache.has(Class)) return _cache.get(Class); _cache.set(Class, Wrapper); } function Wrapper() { return _construct(Class, arguments, _getPrototypeOf(this).constructor); } Wrapper.prototype = Object.create(Class.prototype, { constructor: { value: Wrapper, enumerable: false, writable: true, configurable: true } }); return _setPrototypeOf(Wrapper, Class); }; return _wrapNativeSuper(Class); }\n\nfunction isNativeReflectConstruct() { if (typeof Reflect === \"undefined\" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === \"function\") return true; try { Date.prototype.toString.call(Reflect.construct(Date, [], function () {})); return true; } catch (e) { return false; } }\n\nfunction _construct(Parent, args, Class) { if (isNativeReflectConstruct()) { _construct = Reflect.construct; } else { _construct = function _construct(Parent, args, Class) { var a = [null]; a.push.apply(a, args); var Constructor = Function.bind.apply(Parent, a); var instance = new Constructor(); if (Class) _setPrototypeOf(instance, Class.prototype); return instance; }; } return _construct.apply(null, arguments); }\n\nfunction _isNativeFunction(fn) { return Function.toString.call(fn).indexOf(\"[native code]\") !== -1; }\n\nfunction _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); }\n\nfunction _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); }; return _getPrototypeOf(o); }\n\n// import processor name via preval.require so that it's available as a value at compile time\nvar processorNames = {\n \"recorderProcessor\": \"recorder-processor\",\n \"soundFileProcessor\": \"sound-file-processor\",\n \"amplitudeProcessor\": \"amplitude-processor\"\n};\n\nvar SoundFileProcessor =\n/*#__PURE__*/\nfunction (_AudioWorkletProcesso) {\n _inherits(SoundFileProcessor, _AudioWorkletProcesso);\n\n function SoundFileProcessor() {\n _classCallCheck(this, SoundFileProcessor);\n\n return _possibleConstructorReturn(this, _getPrototypeOf(SoundFileProcessor).apply(this, arguments));\n }\n\n _createClass(SoundFileProcessor, [{\n key: \"process\",\n value: function process(inputs) {\n var input = inputs[0];\n var inputChannel = input[0];\n var position = inputChannel[inputChannel.length - 1] || 0;\n this.port.postMessage({\n name: 'position',\n position: position\n });\n return true;\n }\n }]);\n\n return SoundFileProcessor;\n}(_wrapNativeSuper(AudioWorkletProcessor));\n\nregisterProcessor(processorNames.soundFileProcessor, SoundFileProcessor);");
/***/ }),
/* 39 */
@@ -4034,10 +4034,6 @@ function _typeof(obj) { if (typeof Symbol === "function" && typeof Symbol.iterat
this._counterNode.loopStart = cueStart;
this._counterNode.loopEnd = cueEnd;
}
-
- this._workletNode.port.postMessage({
- name: 'play'
- });
};
/**
* p5.SoundFile has two play modes: restart and
@@ -4137,17 +4133,13 @@ function _typeof(obj) { if (typeof Symbol === "function" && typeof Symbol.iterat
var pTime = time + now;
if (this.isPlaying() && this.buffer && this.bufferSourceNode) {
- this._workletNode.port.postMessage({
- name: 'pause'
- });
-
+ this._paused = true;
+ this._playing = false;
this.pauseTime = this.currentTime();
this.bufferSourceNode.stop(pTime);
this._counterNode.stop(pTime);
- this._paused = true;
- this._playing = false;
this._pauseTime = this.currentTime(); // TO DO: make sure play() still starts from orig start position
} else {
this._pauseTime = 0;
@@ -4873,6 +4865,8 @@ function _typeof(obj) { if (typeof Symbol === "function" && typeof Symbol.iterat
p5.SoundFile.prototype._initCounterNode = function () {
+ var _this = this;
+
var self = this;
var now = ac.currentTime;
var cNode = ac.createBufferSource(); // dispose of worklet node if it already exists
@@ -4887,11 +4881,16 @@ function _typeof(obj) { if (typeof Symbol === "function" && typeof Symbol.iterat
self._workletNode.port.onmessage = function (event) {
if (event.data.name === 'position') {
- this._lastPos = event.data.position; // do any callbacks that have been scheduled
+ // event.data.position should only be 0 when paused
+ if (event.data.position === 0) {
+ return;
+ }
+
+ _this._lastPos = event.data.position; // do any callbacks that have been scheduled
- this._onTimeUpdate(self._lastPos);
+ _this._onTimeUpdate(self._lastPos);
}
- }.bind(self); // create counter buffer of the same length as self.buffer
+ }; // create counter buffer of the same length as self.buffer
cNode.buffer = _createCounterBuffer(self.buffer);
diff --git a/lib/p5.sound.js.map b/lib/p5.sound.js.map
index 61867fa7..e0fa1766 100644
--- a/lib/p5.sound.js.map
+++ b/lib/p5.sound.js.map
@@ -1 +1 @@
-{"version":3,"sources":["webpack:///webpack/bootstrap","webpack:///../node_modules/tone/Tone/core/Tone.js","webpack:///./master.js","webpack:///../node_modules/tone/Tone/signal/Signal.js","webpack:///../node_modules/tone/Tone/signal/Multiply.js","webpack:///./effect.js","webpack:///../node_modules/tone/Tone/signal/WaveShaper.js","webpack:///./helpers.js","webpack:///../node_modules/tone/Tone/signal/Add.js","webpack:///../node_modules/tone/Tone/type/Type.js","webpack:///../node_modules/tone/Tone/core/Gain.js","webpack:///./errorHandler.js","webpack:///../node_modules/tone/Tone/core/Context.js","webpack:///./audioWorklet/processorNames.js","webpack:///../node_modules/tone/Tone/signal/Scale.js","webpack:///../node_modules/tone/Tone/signal/TimelineSignal.js","webpack:///./filter.js","webpack:///../node_modules/tone/Tone/signal/Subtract.js","webpack:///./audiocontext.js","webpack:///../node_modules/tone/Tone/core/Emitter.js","webpack:///../node_modules/tone/Tone/signal/SignalBase.js","webpack:///../node_modules/tone/Tone/type/Time.js","webpack:///../node_modules/tone/Tone/type/TimeBase.js","webpack:///../node_modules/tone/Tone/core/Param.js","webpack:///./oscillator.js","webpack:///../node_modules/tone/Tone/core/Timeline.js","webpack:///../node_modules/tone/Tone/signal/Negate.js","webpack:///../node_modules/tone/Tone/signal/GreaterThanZero.js","webpack:///../node_modules/tone/Tone/core/Clock.js","webpack:///./monosynth.js","webpack:///./audioVoice.js","webpack:///./polysynth.js","webpack:///./app.js","webpack:///../node_modules/audioworklet-polyfill/dist/audioworklet-polyfill.js","webpack:///./shims.js","webpack:///../node_modules/webpack/buildin/global.js","webpack:///../node_modules/startaudiocontext/StartAudioContext.js","webpack:///./audioWorklet/index.js","webpack:///./audioWorklet/recorderProcessor.js","webpack:///./audioWorklet/soundFileProcessor.js","webpack:///./audioWorklet/amplitudeProcessor.js","webpack:///./panner.js","webpack:///./soundfile.js","webpack:///./amplitude.js","webpack:///./fft.js","webpack:///./signal.js","webpack:///../node_modules/tone/Tone/type/Frequency.js","webpack:///../node_modules/tone/Tone/type/TransportTime.js","webpack:///./envelope.js","webpack:///./pulse.js","webpack:///./noise.js","webpack:///./audioin.js","webpack:///../node_modules/tone/Tone/component/CrossFade.js","webpack:///../node_modules/tone/Tone/signal/Expr.js","webpack:///../node_modules/tone/Tone/signal/GreaterThan.js","webpack:///../node_modules/tone/Tone/signal/Abs.js","webpack:///../node_modules/tone/Tone/signal/Modulo.js","webpack:///../node_modules/tone/Tone/signal/Pow.js","webpack:///../node_modules/tone/Tone/signal/AudioToGain.js","webpack:///../node_modules/tone/Tone/signal/EqualPowerGain.js","webpack:///./eq.js","webpack:///./eqFilter.js","webpack:///./panner3d.js","webpack:///./listener3d.js","webpack:///./delay.js","webpack:///./reverb.js","webpack:///./metro.js","webpack:///../node_modules/tone/Tone/core/TimelineState.js","webpack:///./looper.js","webpack:///./soundLoop.js","webpack:///./compressor.js","webpack:///./soundRecorder.js","webpack:///./peakDetect.js","webpack:///./gain.js","webpack:///./distortion.js"],"names":["define","Tone","inputs","outputs","this","isUndef","input","context","createGain","Array","output","audioContext","prototype","set","params","value","rampTime","isObject","isString","tmpObj","paramLoop","attr","parent","indexOf","attrSplit","split","i","length","splice","innerParam","join","param","Signal","Param","rampTo","AudioParam","get","_collectDefaults","constructor","ret","subRet","j","subAttr","isFunction","constr","defaults","Object","keys","_super","superDefs","push","toString","className","isLetter","match","sameConstructor","defineProperty","isArray","dispose","AudioNode","disconnect","connect","unit","outputNum","inputNum","defaultArg","destination","isNumber","apply","arguments","connectSeries","currentUnit","toUnit","chain","fan","given","fallback","givenProp","fallbackProp","optionsObject","values","options","val","arg","call","isBoolean","noOp","_readOnly","property","writable","enumerable","_writable","State","Started","Stopped","Paused","equalPowerScale","percent","piFactor","Math","PI","sin","dbToGain","db","pow","gainToDb","gain","log","LN10","intervalToFrequencyRatio","interval","now","extend","child","TempConstructor","Context","emit","setContext","ctx","sampleRate","hasAudioContext","window","hasOwnProperty","hasPromises","hasWorkers","version","TONE_SILENCE_VERSION_LOGGING","console","audiocontext","Master","limiter","createDynamicsCompressor","threshold","ratio","knee","meter","fftMeter","soundArray","parts","extensions","p5sound","p5","getMasterVolume","masterVolume","vol","tFromNow","currentTime","currentVol","cancelScheduledValues","linearRampToValueAtTime","soundOut","_silentNode","_gain","_param","getConstant","units","Type","Default","convert","SignalBase","Multiply","createInsOuts","_mult","Gain","require","CrossFade","Effect","ac","_drywet","wet","a","b","amp","drywet","fade","u","index","undefined","WaveShaper","mapping","bufferLen","_shaper","createWaveShaper","_curve","curve","isFinite","Float32Array","setMap","len","normalized","oversample","oversampling","RangeError","freqToMidi","f","mathlog2","m","round","midiToFreq","noteToFreq","note","wholeNotes","A","B","C","D","E","F","G","toUpperCase","octave","slice","soundFormats","toLowerCase","disposeSound","registerMethod","_checkFileFormats","paths","path","extTest","pop","isFileSupported","pathSplit","pathCore","extension","supported","p","_mathChain","o","math","thisChain","nextChain","type","mathOps","convertToWav","audioBuffer","leftChannel","rightChannel","getChannelData","numberOfChannels","interleaved","interleave","buffer","ArrayBuffer","view","DataView","writeUTFBytes","setUint32","setUint16","lng","volume","setInt16","result","inputIndex","offset","string","setUint8","charCodeAt","Add","_sum","Time","Frequency","TransportTime","Ticks","NormalRange","AudioRange","Decibels","Interval","BPM","Positive","Cents","Degrees","MIDI","BarsBeatsSixteenths","Samples","Hertz","Note","Milliseconds","Seconds","Notation","toSeconds","time","TimeBase","toFrequency","freq","valueOf","toTicks","Transport","ticks","GainNode","AudioContext","createGainNode","_gainNode","CustomError","name","errorTrace","failedPath","err","Error","tempStack","splitStack","originalStack","stack","filter","ln","toneConnect","outNum","inNum","nativeConnect","e","nativeDisconnect","webkitAudioContext","prop","Emitter","_context","_defineProperty","_latencyHint","_lookAhead","_updateInterval","_computedUpdateInterval","_worker","_createWorker","_constants","mixin","bind","URL","webkitURL","blob","Blob","toFixed","blobUrl","createObjectURL","worker","Worker","addEventListener","_lastUpdate","diff","max","createBuffer","arr","constant","createBufferSource","channelCount","channelCountMode","loop","start","lA","blockTime","postMessage","hint","lookAhead","latencyHint","updateInterval","warn","module","exports","recorderProcessor","soundFileProcessor","amplitudeProcessor","Scale","outputMin","outputMax","_outputMin","_outputMax","_scale","_add","_setRange","min","TimelineSignal","_events","Timeline","_initial","_fromUnits","Linear","Exponential","Target","Curve","Set","getValueAtTime","_toUnits","convertedVal","setValueAtTime","startTime","add","endTime","exponentialRampToValueAtTime","beforeEvent","_searchBefore","_minOutput","setValue","sampleTime","setTargetAtTime","timeConstant","setValueCurveAtTime","duration","scaling","floats","segmentTime","after","cancel","setRampPoint","before","_searchAfter","linearRampToValueBetween","finish","exponentialRampToValueBetween","getAfter","previouVal","previous","getBefore","_exponentialApproach","_curveInterpolate","_linearInterpolate","_exponentialInterpolate","t0","v0","v1","t","exp","t1","progress","lowerIndex","floor","upperIndex","ceil","lowerVal","upperVal","Filter","biquad","createBiquadFilter","setType","_on","_untoggledType","create","process","src","res","frequency","Q","toggle","LowPass","HighPass","BandPass","Subtract","_neg","Negate","global","StartAudioContext","getAudioContext","userStartAudio","elements","callback","elt","Element","map","on","event","events","eventName","off","ev","eventList","args","object","functions","func","emitterFunc","node","outputNumber","inputNumber","overridden","_plusNow","_unaryExpressions","quantize","regexp","method","rh","nextSubdivision","lh","subdiv","_expr","expr","subdivision","addNow","_defaultExpr","_noOp","copy","toNotation","retNotation","_toNotationHelper","retTripletNotation","testNotations","_notationToUnits","notationTime","multiple","notation","primaryExprs","_primaryExpressions","notationExprs","n","toBarsBeatsSixteenths","quarterTime","_beatsToUnits","quarters","measures","_timeSignature","sixteenths","parseFloat","PPQ","toSamples","toMilliseconds","_defaultUnits","exprString","_parseExprString","clone","instance","parseInt","_ticksToUnits","hz","_frequencyToUnits","tr","q","s","total","_secondsToUnits","samples","default","_binaryExpressions","+","precedence","-","*","/","neg","_syntaxGlue","(",")","_tokenize","position","tokens","token","getNextToken","trim","substr","expressions","group","opName","op","reg","SyntaxError","next","peek","_matchGroup","prec","test","_parseBinary","lexer","_parseUnary","_parsePrimary","matching","beats","bpm","seconds","timeSignature","_pushExpr","sub","mult","div","_lfo","lfo","LFO","currentVal","exponentialRampToValue","linearRampToValue","Mult","Oscillator","started","phaseAmount","oscillator","createOscillator","_freqMods","panPosition","connection","panner","Panner","stop","abs","freqNode","self","getAmp","isNaN","phase","getFreq","getType","oscMods","pan","pval","getPan","osc2","delayAmt","dNode","createDelay","delayTime","sigChain","mathObj","chainSource","num","scale","inMin","inMax","outMin","outMax","mapOutMin","mapOutMax","SinOsc","TriOsc","SawOsc","SqrOsc","_timeline","_toRemove","_iterating","memory","Infinity","_search","remove","shift","cancelBefore","beginning","end","midPoint","nextEvent","_iterate","lowerBound","upperBound","forEach","forEachBefore","forEachAfter","forEachFrom","forEachAtTime","_multiply","GreaterThanZero","_thresh","Clock","_nextTick","_lastState","_state","TimelineState","_boundLoop","_loop","state","setStateAtTime","pause","loopInterval","lag","currentState","tickTime","getStateAtTime","AudioVoice","DEFAULT_SUSTAIN","MonoSynth","env","Envelope","setRange","setExp","setADSR","setInput","play","velocity","secondsFromNow","susTime","triggerAttack","triggerRelease","vel","ramp","attack","decay","sustain","release","defineProperties","aTime","dTime","sPercent","rTime","sustime","PolySynth","audioVoice","maxVoices","audiovoices","notes","_newest","_oldest","_voicesInUse","_allocateVoices","noteAttack","noteRelease","noteADSR","d","r","timeFromNow","voice","_note","_velocity","acTime","currentVoice","oldestNote","previousVal","_updateAfter","maxRange","nextTime","p5SOUND","fixSetTarget","setTargetValueAtTime","createDelayNode","createScriptProcessor","createJavaScriptNode","createPeriodicWave","createWaveTable","internal_createGain","internal_createDelay","maxDelayTime","internal_createBufferSource","when","noteGrainOn","noteOn","internal_start","noteOff","internal_stop","playbackRate","internal_createDynamicsCompressor","reduction","internal_createBiquadFilter","detune","internal_createOscillator","setPeriodicWave","setWaveTable","OfflineAudioContext","webkitOfflineAudioContext","navigator","getUserMedia","webkitGetUserMedia","mozGetUserMedia","msGetUserMedia","el","document","createElement","isSupported","canPlayType","isOGGSupported","isMP3Supported","isWAVSupported","isAACSupported","isAIFSupported","moduleSources","loadAudioWorkletModules","Promise","all","moduleSrc","objectURL","audioWorklet","addModule","preload","_preloadCount","onWorkletModulesLoad","_decrementPreload","then","createStereoPanner","stereoPanner","inputChannels","obj","numInputChannels","left","right","channelInterpretation","splitter","createChannelSplitter","createChannelMerger","v","rightVal","cos","leftVal","numChannels","processorNames","SoundFile","onload","onerror","whileLoading","url","File","FileReader","FileList","file","_onended","_looping","_playing","_paused","_pauseTime","_cues","_cueIDCounter","_lastPos","_counterNode","_workletNode","bufferSourceNodes","bufferSourceNode","reversed","pauseTime","mode","startMillis","load","_whileLoading","_clearOnEnd","registerPreloadMethod","loadSound","location","origin","cordova","alert","errorCallback","request","XMLHttpRequest","evt","_updateProgress","open","responseType","status","decodeAudioData","response","buff","msg","error","statusText","message","send","reader","readAsArrayBuffer","lengthComputable","percentComplete","loaded","isLoaded","rate","_cueStart","cueStart","cueEnd","setVolume","isPlaying","_initSourceNode","_initCounterNode","_arrayIndex","loopStart","loopEnd","port","playMode","str","pTime","setLoop","bool","isLooping","isPaused","stopAll","_time","_rampTime","_tFromNow","getVolume","reverse","reverseBuffer","setPitch","newPlaybackRate","getPlaybackRate","jump","cueTime","cTime","dur","channels","frames","getPeaks","width","sampleSize","sampleStep","peaks","c","chan","currentPos","curVol","onended","warning","getLevel","setPath","setBuffer","buf","size","newBuffer","channelNum","channel","_createCounterBuffer","audioBuf","arrayBuffer","cNode","AudioWorkletNode","onmessage","data","_onTimeUpdate","processPeaks","_initThreshold","_minThreshold","_minPeaks","bufLen","allPeaks","initialThreshold","minThreshold","minPeaks","offlineContext","source","startRendering","oncomplete","filteredBuffer","renderedBuffer","bufferData","getPeaksAtThreshold","intervalCounts","countIntervalsBetweenNearbyPeaks","groups","groupNeighborsByTempo","topTempos","sort","intA","intB","count","tempo","bpmVariance","tempoPeaks","getPeaksAtTopTempo","Peak","sampleIndex","amplitude","tempos","intervals","peaksObj","peak","peaksArray","startPeak","endPeak","startPos","endPos","foundInterval","some","intervalCount","tempoCounts","theoreticalTempo","mapTempo","foundTempo","tempoCount","peaksAtTopTempo","key","intervalBPM","peakTime","dif","Cue","id","addCue","cue","removeCue","cueLength","clearCues","playbackTime","callbackTime","_prevTime","save","fileName","dataView","saveSound","getBlob","thisBufferSourceNode","target","soundFile","removeEventListener","Amplitude","smoothing","bufferSize","outputChannelCount","processorOptions","normalize","volNorm","stereoVol","stereoVolNorm","parameters","toggleNormalize","smooth","FFT","bins","analyser","createAnalyser","fftSize","configurable","smoothingTimeConstant","freqDomain","Uint8Array","frequencyBinCount","timeDomain","bass","lowMid","mid","highMid","treble","waveform","normalArray","_isSafari","timeToFloat","getFloatTimeDomainData","timeToInt","getByteTimeDomainData","scaled","analyze","freqToFloat","getFloatFrequencyData","freqToInt","getByteFrequencyData","getEnergy","frequency1","frequency2","nyquist","swap","lowIndex","highIndex","numFrequencies","toReturn","freq1","freq2","x","getCentroid","cumulative_sum","centroid_normalization","mean_freq_index","spec_centroid_freq","linAverages","N","spectrum","spectrumLength","spectrumStep","linearAverages","groupIndex","specIndex","logAverages","octaveBands","octaveIndex","specIndexFrequency","hi","getOctaveBands","fCtr0","lastFrequencyBand","lo","ctr","newFrequencyBand","fft","_input","midi","midiToFrequency","pitch","noteNumber","noteToScaleIndex","transpose","harmonize","toMidi","frequencyToMidi","toNote","A4","LN2","scaleIndexToNote","cbb","cb","c#","cx","dbb","d#","dx","ebb","eb","e#","ex","fbb","fb","f#","fx","gbb","gb","g","g#","gx","abb","ab","a#","ax","bbb","bb","b#","bx","_secondsToTicks","l1","t2","l2","t3","l3","aLevel","dLevel","rLevel","_rampHighPercentage","_rampLowPercentage","control","_init","isExponential","sourceToClear","wasTriggered","_setRampAD","_rampAttackTime","checkExpInput","_rampDecayTime","TCDenominator","_rampAttackTC","_rampDecayTC","setRampPercentages","p1","p2","isExp","lastAttack","valToSet","v2","destination1","destination2","AudioIn","Reverb","Noise","Delay","Env","Pulse","w","dcOffset","createDCOffset","dcGain","mW","sig","SignalAdd","mods","currentFreq","freqMod","bufferSource","assignType","_brownNoise","_pinkNoise","_whiteNoise","whiteBuffer","noiseData","random","pinkBuffer","b0","b1","b2","b3","b4","b5","b6","white","brownBuffer","lastOut","noise","inputSources","stream","mediaStream","currentSource","enabled","MediaStreamTrack","mediaDevices","successCallback","audioSource","constraints","audio","echoCancellation","deviceId","createMediaStreamSource","getTracks","track","getSources","onSuccess","onError","resolve","reject","enumerateDevices","devices","device","kind","setSource","active","initialFade","_equalPowerA","EqualPowerGain","_equalPowerB","_invert","Expr","applyBinary","Constructor","_eval","applyUnary","getNumber","literalNumber","_replacements","inputCount","_parseInputs","_nodes","tree","_parseTree","_disposeNodes","_Expressions","signal","glue",",","Abs","mod","modulus","Modulo","Pow","a2g","AudioToGain","binary","unary","!","NOT","inputArray","inputMax","replace","matchSyntax","syn","matchGroup","groupName","parseExpression","parseUnary","operator","parsePrimary","parseArgumentList","parseFunctionCall","GreaterThan","_gtz","_abs","_subtract","_modSignal","_setWaveShaper","_exp","_expScaler","_expFunc","_norm","_eqPower","EQFilter","EQ","_eqsize","factor","bands","_newBand","Panner3D","createPanner","panningModel","distanceModel","xVal","yVal","zVal","positionX","positionY","positionZ","orient","orientX","orientY","orientZ","orientationX","orientationY","orientationZ","setFalloff","maxDistance","rolloffFactor","maxDist","rolloff","Listener3D","listener","xValF","yValF","zValF","xValU","yValU","zValU","orientForward","orientUp","forwardX","forwardY","forwardZ","upX","upY","upZ","_split","_merge","_leftGain","_rightGain","leftDelay","rightDelay","_leftFilter","_rightFilter","_maxDelay","maxValue","feedback","_delayTime","_feedback","_filter","_initConvolverNode","_seconds","_decay","_reverse","_buildImpulse","convolverNode","createConvolver","_teardownConvolverNode","_setBuffer","decayRate","rebuild","impulse","impulseL","impulseR","Convolver","impulses","_loadBuffer","cReverb","chunks","addImpulse","resetImpulse","toggleImpulse","Metro","clock","ontick","syncedParts","prevTick","tatumTime","tickCallback","elapsedTime","thisPart","incrementStep","phrases","thisPhrase","phraseArray","sequence","bNum","metroTicks","looping","setBPM","beatTime","tatums","getBPM","getRate","resetSync","part","pushSync","beatLength","initial","Phrase","phraseStep","Part","steps","bLength","partStep","noLoop","metro","addPhrase","array","removePhrase","getPhrase","replaceSequence","onStep","Score","currentPart","thisScore","nextPart","resetPart","playNextPart","resetParts","scoreStep","aScore","SoundLoop","musicalTimeMode","_interval","_bpm","maxIterations","iterations","_calcFreq","syncedStart","otherLoop","_update","_convertNotation","Number","_measure","timeSig","Compressor","compressor","number","SoundRecorder","_inputChannels","_outputChannels","buffers","leftBuffer","rightBuffer","_callback","record","sFile","writeFile","PeakDetect","_framesPerPeak","framesPerPeak","framesSinceLastPeak","cutoff","cutoffMult","energy","penergy","currentValue","isDetected","f1","f2","_onPeak","update","fftObject","nrg","onPeak","makeDistortionCurve","amount","k","numSamples","deg","Distortion","curveAmount","waveShaperNode","getAmount","getOversample"],"mappings":"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;;AAED;AACA;AACA;AACA,CAAC;AACD;AACA;AACA;;AAEA;AACA;AACA,4CAA4C;;AAE5C;;;;;;;ACnBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK,IAA0C;AAC/C,EAAE,iCAAO,EAAE,oCAAE,OAAO;AAAA;AAAA;AAAA,oGAAC;AACrB,GAAG,MAAM,EAIN;AACH,CAAC;;AAED;;AAEA;AACA;AACA,YAAY,QAAQ;AACpB;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA,YAAY,aAAa;AACzB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,aAAa,aAAa;AAC1B,aAAa;AACb;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,aAAa,aAAa;AAC1B,aAAa,SAAS;AACtB;AACA;;AAEA;AACA;AACA;AACA,IAAI;AACJ;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,GAAG;AACH;AACA;AACA;;AAEA;AACA;AACA,aAAa,4BAA4B;AACzC,YAAY,MAAM;AAClB;AACA;AACA;AACA,kBAAkB,oBAAoB;AACtC;AACA;AACA,GAAG;AACH;AACA,GAAG;AACH;AACA,GAAG;AACH;AACA;AACA;AACA,G;AACA;;AAEA;AACA,YAAY,aAAa;AACzB,YAAY,6BAA6B;AACzC;AACA;AACA;AACA;AACA,YAAY,UAAU;AACtB,aAAa,QAAQ;AACrB;AACA;AACA;;AAEA;AACA;AACA;AACA,GAAG;;AAEH;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,kBAAkB,yBAAyB;AAC3C;AACA;AACA;;AAEA;AACA;AACA;AACA,GAAG;;AAEH;AACA;;AAEA;AACA,CAAC,E;;;;;;A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","file":"p5.sound.js","sourcesContent":[" \t// The module cache\n \tvar installedModules = {};\n\n \t// The require function\n \tfunction __webpack_require__(moduleId) {\n\n \t\t// Check if module is in cache\n \t\tif(installedModules[moduleId]) {\n \t\t\treturn installedModules[moduleId].exports;\n \t\t}\n \t\t// Create a new module (and put it into the cache)\n \t\tvar module = installedModules[moduleId] = {\n \t\t\ti: moduleId,\n \t\t\tl: false,\n \t\t\texports: {}\n \t\t};\n\n \t\t// Execute the module function\n \t\tmodules[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n\n \t\t// Flag the module as loaded\n \t\tmodule.l = true;\n\n \t\t// Return the exports of the module\n \t\treturn module.exports;\n \t}\n\n\n \t// expose the modules object (__webpack_modules__)\n \t__webpack_require__.m = modules;\n\n \t// expose the module cache\n \t__webpack_require__.c = installedModules;\n\n \t// define getter function for harmony exports\n \t__webpack_require__.d = function(exports, name, getter) {\n \t\tif(!__webpack_require__.o(exports, name)) {\n \t\t\tObject.defineProperty(exports, name, { enumerable: true, get: getter });\n \t\t}\n \t};\n\n \t// define __esModule on exports\n \t__webpack_require__.r = function(exports) {\n \t\tif(typeof Symbol !== 'undefined' && Symbol.toStringTag) {\n \t\t\tObject.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });\n \t\t}\n \t\tObject.defineProperty(exports, '__esModule', { value: true });\n \t};\n\n \t// create a fake namespace object\n \t// mode & 1: value is a module id, require it\n \t// mode & 2: merge all properties of value into the ns\n \t// mode & 4: return value when already ns object\n \t// mode & 8|1: behave like require\n \t__webpack_require__.t = function(value, mode) {\n \t\tif(mode & 1) value = __webpack_require__(value);\n \t\tif(mode & 8) return value;\n \t\tif((mode & 4) && typeof value === 'object' && value && value.__esModule) return value;\n \t\tvar ns = Object.create(null);\n \t\t__webpack_require__.r(ns);\n \t\tObject.defineProperty(ns, 'default', { enumerable: true, value: value });\n \t\tif(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key));\n \t\treturn ns;\n \t};\n\n \t// getDefaultExport function for compatibility with non-harmony modules\n \t__webpack_require__.n = function(module) {\n \t\tvar getter = module && module.__esModule ?\n \t\t\tfunction getDefault() { return module['default']; } :\n \t\t\tfunction getModuleExports() { return module; };\n \t\t__webpack_require__.d(getter, 'a', getter);\n \t\treturn getter;\n \t};\n\n \t// Object.prototype.hasOwnProperty.call\n \t__webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };\n\n \t// __webpack_public_path__\n \t__webpack_require__.p = \"\";\n\n\n \t// Load entry module and return exports\n \treturn __webpack_require__(__webpack_require__.s = 31);\n","/**\n * Tone.js\n * @author Yotam Mann\n * @license http://opensource.org/licenses/MIT MIT License\n * @copyright 2014-2017 Yotam Mann\n */\ndefine(function(){\n\n\t\"use strict\";\n\n\t///////////////////////////////////////////////////////////////////////////\n\t//\tTONE\n\t///////////////////////////////////////////////////////////////////////////\n\n\t/**\n\t * @class Tone is the base class of all other classes. It provides \n\t * a lot of methods and functionality to all classes that extend\n\t * it. \n\t * \n\t * @constructor\n\t * @alias Tone\n\t * @param {number} [inputs=1] the number of input nodes\n\t * @param {number} [outputs=1] the number of output nodes\n\t */\n\tvar Tone = function(inputs, outputs){\n\n\t\t/**\n\t\t * the input node(s)\n\t\t * @type {GainNode|Array}\n\t\t */\n\t\tif (this.isUndef(inputs) || inputs === 1){\n\t\t\tthis.input = this.context.createGain();\n\t\t} else if (inputs > 1){\n\t\t\tthis.input = new Array(inputs);\n\t\t}\n\n\t\t/**\n\t\t * the output node(s)\n\t\t * @type {GainNode|Array}\n\t\t */\n\t\tif (this.isUndef(outputs) || outputs === 1){\n\t\t\tthis.output = this.context.createGain();\n\t\t} else if (outputs > 1){\n\t\t\tthis.output = new Array(inputs);\n\t\t}\n\t};\n\n\t/**\n\t * Set the parameters at once. Either pass in an\n\t * object mapping parameters to values, or to set a\n\t * single parameter, by passing in a string and value.\n\t * The last argument is an optional ramp time which \n\t * will ramp any signal values to their destination value\n\t * over the duration of the rampTime.\n\t * @param {Object|string} params\n\t * @param {number=} value\n\t * @param {Time=} rampTime\n\t * @returns {Tone} this\n\t * @example\n\t * //set values using an object\n\t * filter.set({\n\t * \t\"frequency\" : 300,\n\t * \t\"type\" : highpass\n\t * });\n\t * @example\n\t * filter.set(\"type\", \"highpass\");\n\t * @example\n\t * //ramp to the value 220 over 3 seconds. \n\t * oscillator.set({\n\t * \t\"frequency\" : 220\n\t * }, 3);\n\t */\n\tTone.prototype.set = function(params, value, rampTime){\n\t\tif (this.isObject(params)){\n\t\t\trampTime = value;\n\t\t} else if (this.isString(params)){\n\t\t\tvar tmpObj = {};\n\t\t\ttmpObj[params] = value;\n\t\t\tparams = tmpObj;\n\t\t}\n\n\t\tparamLoop:\n\t\tfor (var attr in params){\n\t\t\tvalue = params[attr];\n\t\t\tvar parent = this;\n\t\t\tif (attr.indexOf(\".\") !== -1){\n\t\t\t\tvar attrSplit = attr.split(\".\");\n\t\t\t\tfor (var i = 0; i < attrSplit.length - 1; i++){\n\t\t\t\t\tparent = parent[attrSplit[i]];\n\t\t\t\t\tif (parent instanceof Tone) {\n\t\t\t\t\t\tattrSplit.splice(0,i+1);\n\t\t\t\t\t\tvar innerParam = attrSplit.join(\".\");\n\t\t\t\t\t\tparent.set(innerParam, value);\n\t\t\t\t\t\tcontinue paramLoop;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tattr = attrSplit[attrSplit.length - 1];\n\t\t\t}\n\t\t\tvar param = parent[attr];\n\t\t\tif (this.isUndef(param)){\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tif ((Tone.Signal && param instanceof Tone.Signal) || \n\t\t\t\t\t(Tone.Param && param instanceof Tone.Param)){\n\t\t\t\tif (param.value !== value){\n\t\t\t\t\tif (this.isUndef(rampTime)){\n\t\t\t\t\t\tparam.value = value;\n\t\t\t\t\t} else {\n\t\t\t\t\t\tparam.rampTo(value, rampTime);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} else if (param instanceof AudioParam){\n\t\t\t\tif (param.value !== value){\n\t\t\t\t\tparam.value = value;\n\t\t\t\t}\t\t\t\t\n\t\t\t} else if (param instanceof Tone){\n\t\t\t\tparam.set(value);\n\t\t\t} else if (param !== value){\n\t\t\t\tparent[attr] = value;\n\t\t\t}\n\t\t}\n\t\treturn this;\n\t};\n\n\t/**\n\t * Get the object's attributes. Given no arguments get\n\t * will return all available object properties and their corresponding\n\t * values. Pass in a single attribute to retrieve or an array\n\t * of attributes. The attribute strings can also include a \".\"\n\t * to access deeper properties.\n\t * @example\n\t * osc.get();\n\t * //returns {\"type\" : \"sine\", \"frequency\" : 440, ...etc}\n\t * @example\n\t * osc.get(\"type\");\n\t * //returns { \"type\" : \"sine\"}\n\t * @example\n\t * //use dot notation to access deep properties\n\t * synth.get([\"envelope.attack\", \"envelope.release\"]);\n\t * //returns {\"envelope\" : {\"attack\" : 0.2, \"release\" : 0.4}}\n\t * @param {Array=|string|undefined} params the parameters to get, otherwise will return \n\t * \t\t\t\t\t all available.\n\t * @returns {Object}\n\t */\n\tTone.prototype.get = function(params){\n\t\tif (this.isUndef(params)){\n\t\t\tparams = this._collectDefaults(this.constructor);\n\t\t} else if (this.isString(params)){\n\t\t\tparams = [params];\n\t\t} \n\t\tvar ret = {};\n\t\tfor (var i = 0; i < params.length; i++){\n\t\t\tvar attr = params[i];\n\t\t\tvar parent = this;\n\t\t\tvar subRet = ret;\n\t\t\tif (attr.indexOf(\".\") !== -1){\n\t\t\t\tvar attrSplit = attr.split(\".\");\n\t\t\t\tfor (var j = 0; j < attrSplit.length - 1; j++){\n\t\t\t\t\tvar subAttr = attrSplit[j];\n\t\t\t\t\tsubRet[subAttr] = subRet[subAttr] || {};\n\t\t\t\t\tsubRet = subRet[subAttr];\n\t\t\t\t\tparent = parent[subAttr];\n\t\t\t\t}\n\t\t\t\tattr = attrSplit[attrSplit.length - 1];\n\t\t\t}\n\t\t\tvar param = parent[attr];\n\t\t\tif (this.isObject(params[attr])){\n\t\t\t\tsubRet[attr] = param.get();\n\t\t\t} else if (Tone.Signal && param instanceof Tone.Signal){\n\t\t\t\tsubRet[attr] = param.value;\n\t\t\t} else if (Tone.Param && param instanceof Tone.Param){\n\t\t\t\tsubRet[attr] = param.value;\n\t\t\t} else if (param instanceof AudioParam){\n\t\t\t\tsubRet[attr] = param.value;\n\t\t\t} else if (param instanceof Tone){\n\t\t\t\tsubRet[attr] = param.get();\n\t\t\t} else if (!this.isFunction(param) && !this.isUndef(param)){\n\t\t\t\tsubRet[attr] = param;\n\t\t\t} \n\t\t}\n\t\treturn ret;\n\t};\n\n\t/**\n\t * collect all of the default attributes in one\n\t * @private\n\t * @param {function} constr the constructor to find the defaults from\n\t * @return {Array} all of the attributes which belong to the class\n\t */\n\tTone.prototype._collectDefaults = function(constr){\n\t\tvar ret = [];\n\t\tif (!this.isUndef(constr.defaults)){\n\t\t\tret = Object.keys(constr.defaults);\n\t\t}\n\t\tif (!this.isUndef(constr._super)){\n\t\t\tvar superDefs = this._collectDefaults(constr._super);\n\t\t\t//filter out repeats\n\t\t\tfor (var i = 0; i < superDefs.length; i++){\n\t\t\t\tif (ret.indexOf(superDefs[i]) === -1){\n\t\t\t\t\tret.push(superDefs[i]);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\treturn ret;\n\t};\n\n\t/**\n\t * @returns {string} returns the name of the class as a string\n\t */\n\tTone.prototype.toString = function(){\n\t\tfor (var className in Tone){\n\t\t\tvar isLetter = className[0].match(/^[A-Z]$/);\n\t\t\tvar sameConstructor = Tone[className] === this.constructor;\n\t\t\tif (this.isFunction(Tone[className]) && isLetter && sameConstructor){\n\t\t\t\treturn className;\n\t\t\t}\n\t\t}\n\t\treturn \"Tone\";\n\t};\n\n\t///////////////////////////////////////////////////////////////////////////\n\t//\tCLASS VARS\n\t///////////////////////////////////////////////////////////////////////////\n\n\t/**\n\t * The number of inputs feeding into the AudioNode. \n\t * For source nodes, this will be 0.\n\t * @memberOf Tone#\n\t * @name numberOfInputs\n\t * @readOnly\n\t */\n\tObject.defineProperty(Tone.prototype, \"numberOfInputs\", {\n\t\tget : function(){\n\t\t\tif (this.input){\n\t\t\t\tif (this.isArray(this.input)){\n\t\t\t\t\treturn this.input.length;\n\t\t\t\t} else {\n\t\t\t\t\treturn 1;\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\treturn 0;\n\t\t\t}\n\t\t}\n\t});\n\n\t/**\n\t * The number of outputs coming out of the AudioNode. \n\t * For source nodes, this will be 0.\n\t * @memberOf Tone#\n\t * @name numberOfInputs\n\t * @readOnly\n\t */\n\tObject.defineProperty(Tone.prototype, \"numberOfOutputs\", {\n\t\tget : function(){\n\t\t\tif (this.output){\n\t\t\t\tif (this.isArray(this.output)){\n\t\t\t\t\treturn this.output.length;\n\t\t\t\t} else {\n\t\t\t\t\treturn 1;\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\treturn 0;\n\t\t\t}\n\t\t}\n\t});\n\t\n\t///////////////////////////////////////////////////////////////////////////\n\t//\tCONNECTIONS\n\t///////////////////////////////////////////////////////////////////////////\n\n\t/**\n\t * disconnect and dispose\n\t * @returns {Tone} this\n\t */\n\tTone.prototype.dispose = function(){\n\t\tif (!this.isUndef(this.input)){\n\t\t\tif (this.input instanceof AudioNode){\n\t\t\t\tthis.input.disconnect();\n\t\t\t} \n\t\t\tthis.input = null;\n\t\t}\n\t\tif (!this.isUndef(this.output)){\n\t\t\tif (this.output instanceof AudioNode){\n\t\t\t\tthis.output.disconnect();\n\t\t\t} \n\t\t\tthis.output = null;\n\t\t}\n\t\treturn this;\n\t};\n\n\t/**\n\t * connect the output of a ToneNode to an AudioParam, AudioNode, or ToneNode\n\t * @param {Tone | AudioParam | AudioNode} unit \n\t * @param {number} [outputNum=0] optionally which output to connect from\n\t * @param {number} [inputNum=0] optionally which input to connect to\n\t * @returns {Tone} this\n\t */\n\tTone.prototype.connect = function(unit, outputNum, inputNum){\n\t\tif (Array.isArray(this.output)){\n\t\t\toutputNum = this.defaultArg(outputNum, 0);\n\t\t\tthis.output[outputNum].connect(unit, 0, inputNum);\n\t\t} else {\n\t\t\tthis.output.connect(unit, outputNum, inputNum);\n\t\t}\n\t\treturn this;\n\t};\n\n\t/**\n\t * disconnect the output\n\t * @param {Number|AudioNode} output Either the output index to disconnect\n\t * if the output is an array, or the\n\t * node to disconnect from.\n\t * @returns {Tone} this\n\t */\n\tTone.prototype.disconnect = function(destination, outputNum, inputNum){\n\t\tif (this.isArray(this.output)){\n\t\t\tif (this.isNumber(destination)){\n\t\t\t\tthis.output[destination].disconnect();\n\t\t\t} else {\n\t\t\t\toutputNum = this.defaultArg(outputNum, 0);\n\t\t\t\tthis.output[outputNum].disconnect(destination, 0, inputNum);\n\t\t\t}\n\t\t} else {\n\t\t\tthis.output.disconnect.apply(this.output, arguments);\n\t\t}\n\t};\n\n\t/**\n\t * connect together all of the arguments in series\n\t * @param {...AudioParam|Tone|AudioNode} nodes\n\t * @returns {Tone} this\n\t */\n\tTone.prototype.connectSeries = function(){\n\t\tif (arguments.length > 1){\n\t\t\tvar currentUnit = arguments[0];\n\t\t\tfor (var i = 1; i < arguments.length; i++){\n\t\t\t\tvar toUnit = arguments[i];\n\t\t\t\tcurrentUnit.connect(toUnit);\n\t\t\t\tcurrentUnit = toUnit;\n\t\t\t}\n\t\t}\n\t\treturn this;\n\t};\n\n\t/**\n\t * Connect the output of this node to the rest of the nodes in series.\n\t * @example\n\t * //connect a node to an effect, panVol and then to the master output\n\t * node.chain(effect, panVol, Tone.Master);\n\t * @param {...AudioParam|Tone|AudioNode} nodes\n\t * @returns {Tone} this\n\t */\n\tTone.prototype.chain = function(){\n\t\tif (arguments.length > 0){\n\t\t\tvar currentUnit = this;\n\t\t\tfor (var i = 0; i < arguments.length; i++){\n\t\t\t\tvar toUnit = arguments[i];\n\t\t\t\tcurrentUnit.connect(toUnit);\n\t\t\t\tcurrentUnit = toUnit;\n\t\t\t}\n\t\t}\n\t\treturn this;\n\t};\n\n\t/**\n\t * connect the output of this node to the rest of the nodes in parallel.\n\t * @param {...AudioParam|Tone|AudioNode} nodes\n\t * @returns {Tone} this\n\t */\n\tTone.prototype.fan = function(){\n\t\tif (arguments.length > 0){\n\t\t\tfor (var i = 0; i < arguments.length; i++){\n\t\t\t\tthis.connect(arguments[i]);\n\t\t\t}\n\t\t}\n\t\treturn this;\n\t};\n\n\t//give native nodes chain and fan methods\n\tAudioNode.prototype.chain = Tone.prototype.chain;\n\tAudioNode.prototype.fan = Tone.prototype.fan;\n\n\t///////////////////////////////////////////////////////////////////////////\n\t//\tUTILITIES / HELPERS / MATHS\n\t///////////////////////////////////////////////////////////////////////////\n\n\t/**\n\t * If the `given` parameter is undefined, use the `fallback`. \n\t * If both `given` and `fallback` are object literals, it will\n\t * return a deep copy which includes all of the parameters from both \n\t * objects. If a parameter is undefined in given, it will return\n\t * the fallback property. \n\t *
\n\t * WARNING: if object is self referential, it will go into an an \n\t * infinite recursive loop.\n\t * \n\t * @param {*} given \n\t * @param {*} fallback \n\t * @return {*} \n\t */\n\tTone.prototype.defaultArg = function(given, fallback){\n\t\tif (this.isObject(given) && this.isObject(fallback)){\n\t\t\tvar ret = {};\n\t\t\t//make a deep copy of the given object\n\t\t\tfor (var givenProp in given) {\n\t\t\t\tret[givenProp] = this.defaultArg(fallback[givenProp], given[givenProp]);\n\t\t\t}\n\t\t\tfor (var fallbackProp in fallback) {\n\t\t\t\tret[fallbackProp] = this.defaultArg(given[fallbackProp], fallback[fallbackProp]);\n\t\t\t}\n\t\t\treturn ret;\n\t\t} else {\n\t\t\treturn this.isUndef(given) ? fallback : given;\n\t\t}\n\t};\n\n\t/**\n\t * returns the args as an options object with given arguments\n\t * mapped to the names provided. \n\t *\n\t * if the args given is an array containing only one object, it is assumed\n\t * that that's already the options object and will just return it. \n\t * \n\t * @param {Array} values the 'arguments' object of the function\n\t * @param {Array} keys the names of the arguments as they\n\t * should appear in the options object\n\t * @param {Object=} defaults optional defaults to mixin to the returned \n\t * options object \n\t * @return {Object} the options object with the names mapped to the arguments\n\t */\n\tTone.prototype.optionsObject = function(values, keys, defaults){\n\t\tvar options = {};\n\t\tif (values.length === 1 && this.isObject(values[0])){\n\t\t\toptions = values[0];\n\t\t} else {\n\t\t\tfor (var i = 0; i < keys.length; i++){\n\t\t\t\toptions[keys[i]] = values[i];\n\t\t\t}\n\t\t}\n\t\tif (!this.isUndef(defaults)){\n\t\t\treturn this.defaultArg(options, defaults);\n\t\t} else {\n\t\t\treturn options;\n\t\t}\n\t};\n\n\t///////////////////////////////////////////////////////////////////////////\n\t// TYPE CHECKING\n\t///////////////////////////////////////////////////////////////////////////\n\n\t/**\n\t * test if the arg is undefined\n\t * @param {*} arg the argument to test\n\t * @returns {boolean} true if the arg is undefined\n\t * @function\n\t */\n\tTone.prototype.isUndef = function(val){\n\t\treturn typeof val === \"undefined\";\n\t};\n\n\t/**\n\t * test if the arg is a function\n\t * @param {*} arg the argument to test\n\t * @returns {boolean} true if the arg is a function\n\t * @function\n\t */\n\tTone.prototype.isFunction = function(val){\n\t\treturn typeof val === \"function\";\n\t};\n\n\t/**\n\t * Test if the argument is a number.\n\t * @param {*} arg the argument to test\n\t * @returns {boolean} true if the arg is a number\n\t */\n\tTone.prototype.isNumber = function(arg){\n\t\treturn (typeof arg === \"number\");\n\t};\n\n\t/**\n\t * Test if the given argument is an object literal (i.e. `{}`);\n\t * @param {*} arg the argument to test\n\t * @returns {boolean} true if the arg is an object literal.\n\t */\n\tTone.prototype.isObject = function(arg){\n\t\treturn (Object.prototype.toString.call(arg) === \"[object Object]\" && arg.constructor === Object);\n\t};\n\n\t/**\n\t * Test if the argument is a boolean.\n\t * @param {*} arg the argument to test\n\t * @returns {boolean} true if the arg is a boolean\n\t */\n\tTone.prototype.isBoolean = function(arg){\n\t\treturn (typeof arg === \"boolean\");\n\t};\n\n\t/**\n\t * Test if the argument is an Array\n\t * @param {*} arg the argument to test\n\t * @returns {boolean} true if the arg is an array\n\t */\n\tTone.prototype.isArray = function(arg){\n\t\treturn (Array.isArray(arg));\n\t};\n\n\t/**\n\t * Test if the argument is a string.\n\t * @param {*} arg the argument to test\n\t * @returns {boolean} true if the arg is a string\n\t */\n\tTone.prototype.isString = function(arg){\n\t\treturn (typeof arg === \"string\");\n\t};\n\n \t/**\n\t * An empty function.\n\t * @static\n\t */\n\tTone.noOp = function(){};\n\n\t/**\n\t * Make the property not writable. Internal use only. \n\t * @private\n\t * @param {string} property the property to make not writable\n\t */\n\tTone.prototype._readOnly = function(property){\n\t\tif (Array.isArray(property)){\n\t\t\tfor (var i = 0; i < property.length; i++){\n\t\t\t\tthis._readOnly(property[i]);\n\t\t\t}\n\t\t} else {\n\t\t\tObject.defineProperty(this, property, { \n\t\t\t\twritable: false,\n\t\t\t\tenumerable : true,\n\t\t\t});\n\t\t}\n\t};\n\n\t/**\n\t * Make an attribute writeable. Interal use only. \n\t * @private\n\t * @param {string} property the property to make writable\n\t */\n\tTone.prototype._writable = function(property){\n\t\tif (Array.isArray(property)){\n\t\t\tfor (var i = 0; i < property.length; i++){\n\t\t\t\tthis._writable(property[i]);\n\t\t\t}\n\t\t} else {\n\t\t\tObject.defineProperty(this, property, { \n\t\t\t\twritable: true,\n\t\t\t});\n\t\t}\n\t};\n\n\t/**\n\t * Possible play states. \n\t * @enum {string}\n\t */\n\tTone.State = {\n\t\tStarted : \"started\",\n\t\tStopped : \"stopped\",\n\t\tPaused : \"paused\",\n \t};\n\n\t///////////////////////////////////////////////////////////////////////////\n\t// CONVERSIONS\n\t///////////////////////////////////////////////////////////////////////////\n\n\t/**\n\t * Equal power gain scale. Good for cross-fading.\n\t * @param {NormalRange} percent (0-1)\n\t * @return {Number} output gain (0-1)\n\t */\n\tTone.prototype.equalPowerScale = function(percent){\n\t\tvar piFactor = 0.5 * Math.PI;\n\t\treturn Math.sin(percent * piFactor);\n\t};\n\n\t/**\n\t * Convert decibels into gain.\n\t * @param {Decibels} db\n\t * @return {Number} \n\t */\n\tTone.prototype.dbToGain = function(db) {\n\t\treturn Math.pow(2, db / 6);\n\t};\n\n\t/**\n\t * Convert gain to decibels.\n\t * @param {Number} gain (0-1)\n\t * @return {Decibels} \n\t */\n\tTone.prototype.gainToDb = function(gain) {\n\t\treturn 20 * (Math.log(gain) / Math.LN10);\n\t};\n\n\t/**\n\t * Convert an interval (in semitones) to a frequency ratio.\n\t * @param {Interval} interval the number of semitones above the base note\n\t * @return {number} the frequency ratio\n\t * @example\n\t * tone.intervalToFrequencyRatio(0); // 1\n\t * tone.intervalToFrequencyRatio(12); // 2\n\t * tone.intervalToFrequencyRatio(-12); // 0.5\n\t */\n\tTone.prototype.intervalToFrequencyRatio = function(interval){\n\t\treturn Math.pow(2,(interval/12));\n\t};\n\n\t///////////////////////////////////////////////////////////////////////////\n\t//\tTIMING\n\t///////////////////////////////////////////////////////////////////////////\n\n\t/**\n\t * Return the current time of the AudioContext clock.\n\t * @return {Number} the currentTime from the AudioContext\n\t */\n\tTone.prototype.now = function(){\n\t\treturn Tone.context.now();\n\t};\n\n\t/**\n\t * Return the current time of the AudioContext clock.\n\t * @return {Number} the currentTime from the AudioContext\n\t * @static\n\t */\n\tTone.now = function(){\n\t\treturn Tone.context.now();\n\t};\n\n\t///////////////////////////////////////////////////////////////////////////\n\t//\tINHERITANCE\n\t///////////////////////////////////////////////////////////////////////////\n\n\t/**\n\t * have a child inherit all of Tone's (or a parent's) prototype\n\t * to inherit the parent's properties, make sure to call \n\t * Parent.call(this) in the child's constructor\n\t *\n\t * based on closure library's inherit function\n\t *\n\t * @static\n\t * @param {function} \tchild \n\t * @param {function=} parent (optional) parent to inherit from\n\t * if no parent is supplied, the child\n\t * will inherit from Tone\n\t */\n\tTone.extend = function(child, parent){\n\t\tif (Tone.prototype.isUndef(parent)){\n\t\t\tparent = Tone;\n\t\t}\n\t\tfunction TempConstructor(){}\n\t\tTempConstructor.prototype = parent.prototype;\n\t\tchild.prototype = new TempConstructor();\n\t\t/** @override */\n\t\tchild.prototype.constructor = child;\n\t\tchild._super = parent;\n\t};\n\n\t///////////////////////////////////////////////////////////////////////////\n\t//\tCONTEXT\n\t///////////////////////////////////////////////////////////////////////////\n\n\t/**\n\t * The private audio context shared by all Tone Nodes. \n\t * @private\n\t * @type {Tone.Context|undefined}\n\t */\n\tvar audioContext;\n\n\t/**\n\t * A static pointer to the audio context accessible as Tone.context. \n\t * @type {Tone.Context}\n\t * @name context\n\t * @memberOf Tone\n\t */\n\tObject.defineProperty(Tone, \"context\", {\n\t\tget : function(){\n\t\t\treturn audioContext;\n\t\t},\n\t\tset : function(context){\n\t\t\tif (Tone.Context && context instanceof Tone.Context){\n\t\t\t\taudioContext = context;\n\t\t\t} else {\n\t\t\t\taudioContext = new Tone.Context(context);\n\t\t\t}\n\t\t\t//initialize the new audio context\n\t\t\tif (Tone.Context){\n\t\t\t\tTone.Context.emit(\"init\", audioContext);\n\t\t\t}\n\t\t}\n\t});\n\n\t/**\n\t * The AudioContext\n\t * @type {Tone.Context}\n\t * @name context\n\t * @memberOf Tone#\n\t * @readOnly\n\t */\n\tObject.defineProperty(Tone.prototype, \"context\", {\n\t\tget : function(){\n\t\t\treturn Tone.context;\n\t\t}\n\t});\n\n\t/**\n\t * Tone automatically creates a context on init, but if you are working\n\t * with other libraries which also create an AudioContext, it can be\n\t * useful to set your own. If you are going to set your own context, \n\t * be sure to do it at the start of your code, before creating any objects.\n\t * @static\n\t * @param {AudioContext} ctx The new audio context to set\n\t */\n\tTone.setContext = function(ctx){\n\t\tTone.context = ctx;\n\t};\n\n\t/**\n\t * The number of seconds of 1 processing block (128 samples)\n\t * @type {Number}\n\t * @name blockTime\n\t * @memberOf Tone#\n\t * @readOnly\n\t */\n\tObject.defineProperty(Tone.prototype, \"blockTime\", {\n\t\tget : function(){\n\t\t\treturn 128 / this.context.sampleRate;\n\t\t}\n\t});\n\n\t/**\n\t * The duration in seconds of one sample.\n\t * @type {Number}\n\t * @name sampleTime\n\t * @memberOf Tone#\n\t * @readOnly\n\t */\n\tObject.defineProperty(Tone.prototype, \"sampleTime\", {\n\t\tget : function(){\n\t\t\treturn 1 / this.context.sampleRate;\n\t\t}\n\t});\n\n\t/**\n\t * Whether or not all the technologies that Tone.js relies on are supported by the current browser. \n\t * @type {Boolean}\n\t * @name supported\n\t * @memberOf Tone\n\t * @readOnly\n\t */\n\tObject.defineProperty(Tone, \"supported\", {\n\t\tget : function(){\n\t\t\tvar hasAudioContext = window.hasOwnProperty(\"AudioContext\") || window.hasOwnProperty(\"webkitAudioContext\");\n\t\t\tvar hasPromises = window.hasOwnProperty(\"Promise\");\n\t\t\tvar hasWorkers = window.hasOwnProperty(\"Worker\");\n\t\t\treturn hasAudioContext && hasPromises && hasWorkers;\n\t\t}\n\t});\n\n\tTone.version = \"r10\";\n\n\t// allow optional silencing of this log\n\tif (!window.TONE_SILENCE_VERSION_LOGGING) {\n\t\tconsole.log(\"%c * Tone.js \" + Tone.version + \" * \", \"background: #000; color: #fff\");\n\t}\n\n\treturn Tone;\n});\n","'use strict';\n\n\ndefine(['audiocontext'], function (audiocontext) {\n /**\n * Master contains AudioContext and the master sound output.\n * @for p5\n */\n var Master = function() {\n this.input = audiocontext.createGain();\n this.output = audiocontext.createGain();\n\n //put a hard limiter on the output\n this.limiter = audiocontext.createDynamicsCompressor();\n this.limiter.threshold.value = -3;\n this.limiter.ratio.value = 20;\n this.limiter.knee.value = 1;\n\n this.audiocontext = audiocontext;\n\n this.output.disconnect();\n\n // connect input to limiter\n this.input.connect(this.limiter);\n\n // connect limiter to output\n this.limiter.connect(this.output);\n\n // meter is just for global Amplitude / FFT analysis\n this.meter = audiocontext.createGain();\n this.fftMeter = audiocontext.createGain();\n this.output.connect(this.meter);\n this.output.connect(this.fftMeter);\n\n // connect output to destination\n this.output.connect(this.audiocontext.destination);\n\n // an array of all sounds in the sketch\n this.soundArray = [];\n // an array of all musical parts in the sketch\n this.parts = [];\n\n // file extensions to search for\n this.extensions = [];\n };\n\n // create a single instance of the p5Sound / master output for use within this sketch\n var p5sound = new Master();\n\n /**\n * Returns a number representing the master amplitude (volume) for sound\n * in this sketch.\n *\n * @method getMasterVolume\n * @return {Number} Master amplitude (volume) for sound in this sketch.\n * Should be between 0.0 (silence) and 1.0.\n */\n p5.prototype.getMasterVolume = function() {\n return p5sound.output.gain.value;\n };\n\n /**\n *
Scale the output of all sound in this sketch
\n * Scaled between 0.0 (silence) and 1.0 (full volume).\n * 1.0 is the maximum amplitude of a digital sound, so multiplying\n * by greater than 1.0 may cause digital distortion. To\n * fade, provide a rampTime parameter. For more\n * complex fades, see the Envelope class.\n *\n * Alternately, you can pass in a signal source such as an\n * oscillator to modulate the amplitude with an audio signal.\n *\n *
How This Works: When you load the p5.sound module, it\n * creates a single instance of p5sound. All sound objects in this\n * module output to p5sound before reaching your computer's output.\n * So if you change the amplitude of p5sound, it impacts all of the\n * sound in this module.
\n *\n *
If no value is provided, returns a Web Audio API Gain Node
\n *\n * @method masterVolume\n * @param {Number|Object} volume Volume (amplitude) between 0.0\n * and 1.0 or modulating signal/oscillator\n * @param {Number} [rampTime] Fade for t seconds\n * @param {Number} [timeFromNow] Schedule this event to happen at\n * t seconds in the future\n */\n p5.prototype.masterVolume = function(vol, rampTime, tFromNow) {\n if (typeof vol === 'number') {\n var rampTime = rampTime || 0;\n var tFromNow = tFromNow || 0;\n var now = p5sound.audiocontext.currentTime;\n var currentVol = p5sound.output.gain.value;\n p5sound.output.gain.cancelScheduledValues(now + tFromNow);\n p5sound.output.gain.linearRampToValueAtTime(currentVol, now + tFromNow);\n p5sound.output.gain.linearRampToValueAtTime(vol, now + tFromNow + rampTime);\n }\n else if (vol) {\n vol.connect(p5sound.output.gain);\n } else {\n // return the Gain Node\n return p5sound.output.gain;\n }\n };\n\n /**\n * `p5.soundOut` is the p5.sound master output. It sends output to\n * the destination of this window's web audio context. It contains\n * Web Audio API nodes including a dyanmicsCompressor (.limiter),\n * and Gain Nodes for .input and .output.\n *\n * @property {Object} soundOut\n */\n p5.prototype.soundOut = p5.soundOut = p5sound;\n\n /**\n * a silent connection to the DesinationNode\n * which will ensure that anything connected to it\n * will not be garbage collected\n *\n * @private\n */\n p5.soundOut._silentNode = p5sound.audiocontext.createGain();\n p5.soundOut._silentNode.gain.value = 0;\n p5.soundOut._silentNode.connect(p5sound.audiocontext.destination);\n\n\n return p5sound;\n});\n","define([\"Tone/core/Tone\", \"Tone/signal/WaveShaper\", \"Tone/type/Type\", \"Tone/core/Param\", \"Tone/core/Gain\"], function(Tone){\n\n\t\"use strict\";\n\n\t/**\n\t * @class A signal is an audio-rate value. Tone.Signal is a core component of the library.\n\t * Unlike a number, Signals can be scheduled with sample-level accuracy. Tone.Signal\n\t * has all of the methods available to native Web Audio \n\t * [AudioParam](http://webaudio.github.io/web-audio-api/#the-audioparam-interface)\n\t * as well as additional conveniences. Read more about working with signals \n\t * [here](https://github.com/Tonejs/Tone.js/wiki/Signals).\n\t *\n\t * @constructor\n\t * @extends {Tone.Param}\n\t * @param {Number|AudioParam} [value] Initial value of the signal. If an AudioParam\n\t * is passed in, that parameter will be wrapped\n\t * and controlled by the Signal. \n\t * @param {string} [units=Number] unit The units the signal is in. \n\t * @example\n\t * var signal = new Tone.Signal(10);\n\t */\n\tTone.Signal = function(){\n\n\t\tvar options = this.optionsObject(arguments, [\"value\", \"units\"], Tone.Signal.defaults);\n\n\t\t/**\n\t\t * The node where the constant signal value is scaled.\n\t\t * @type {GainNode}\n\t\t * @private\n\t\t */\n\t\tthis.output = this._gain = this.context.createGain();\n\n\t\toptions.param = this._gain.gain;\n\t\tTone.Param.call(this, options);\n\n\t\t/**\n\t\t * The node where the value is set.\n\t\t * @type {Tone.Param}\n\t\t * @private\n\t\t */\n\t\tthis.input = this._param = this._gain.gain;\n\n\t\t//connect the const output to the node output\n\t\tthis.context.getConstant(1).chain(this._gain);\n\t};\n\n\tTone.extend(Tone.Signal, Tone.Param);\n\n\t/**\n\t * The default values\n\t * @type {Object}\n\t * @static\n\t * @const\n\t */\n\tTone.Signal.defaults = {\n\t\t\"value\" : 0,\n\t\t\"units\" : Tone.Type.Default,\n\t\t\"convert\" : true,\n\t};\n\n\t/**\n\t * When signals connect to other signals or AudioParams, \n\t * they take over the output value of that signal or AudioParam. \n\t * For all other nodes, the behavior is the same as a default connect. \n\t *\n\t * @override\n\t * @param {AudioParam|AudioNode|Tone.Signal|Tone} node \n\t * @param {number} [outputNumber=0] The output number to connect from.\n\t * @param {number} [inputNumber=0] The input number to connect to.\n\t * @returns {Tone.SignalBase} this\n\t * @method\n\t */\n\tTone.Signal.prototype.connect = Tone.SignalBase.prototype.connect;\n\n\t/**\n\t * dispose and disconnect\n\t * @returns {Tone.Signal} this\n\t */\n\tTone.Signal.prototype.dispose = function(){\n\t\tTone.Param.prototype.dispose.call(this);\n\t\tthis._param = null;\n\t\tthis._gain.disconnect();\n\t\tthis._gain = null;\n\t\treturn this;\n\t};\n\n\treturn Tone.Signal;\n});","define([\"Tone/core/Tone\", \"Tone/signal/Signal\", \"Tone/core/Gain\"], function(Tone){\n\n\t\"use strict\";\n\n\t/**\n\t * @class Multiply two incoming signals. Or, if a number is given in the constructor, \n\t * multiplies the incoming signal by that value. \n\t *\n\t * @constructor\n\t * @extends {Tone.Signal}\n\t * @param {number=} value Constant value to multiple. If no value is provided,\n\t * it will return the product of the first and second inputs\n\t * @example\n\t * var mult = new Tone.Multiply();\n\t * var sigA = new Tone.Signal(3);\n\t * var sigB = new Tone.Signal(4);\n\t * sigA.connect(mult, 0, 0);\n\t * sigB.connect(mult, 0, 1);\n\t * //output of mult is 12.\n\t * @example\n\t * var mult = new Tone.Multiply(10);\n\t * var sig = new Tone.Signal(2).connect(mult);\n\t * //the output of mult is 20. \n\t */\n\tTone.Multiply = function(value){\n\n\t\tthis.createInsOuts(2, 0);\n\n\t\t/**\n\t\t * the input node is the same as the output node\n\t\t * it is also the GainNode which handles the scaling of incoming signal\n\t\t * \n\t\t * @type {GainNode}\n\t\t * @private\n\t\t */\n\t\tthis._mult = this.input[0] = this.output = new Tone.Gain();\n\n\t\t/**\n\t\t * the scaling parameter\n\t\t * @type {AudioParam}\n\t\t * @private\n\t\t */\n\t\tthis._param = this.input[1] = this.output.gain;\n\t\t\n\t\tthis._param.value = this.defaultArg(value, 0);\n\t};\n\n\tTone.extend(Tone.Multiply, Tone.Signal);\n\n\t/**\n\t * clean up\n\t * @returns {Tone.Multiply} this\n\t */\n\tTone.Multiply.prototype.dispose = function(){\n\t\tTone.prototype.dispose.call(this);\n\t\tthis._mult.dispose();\n\t\tthis._mult = null;\n\t\tthis._param = null;\n\t\treturn this;\n\t}; \n\n\treturn Tone.Multiply;\n});\n","'use strict';\ndefine(function (require) {\n\n var p5sound = require('master');\n var CrossFade = require('Tone/component/CrossFade');\n\n /**\n * Effect is a base class for audio effects in p5. \n * This module handles the nodes and methods that are\n * common and useful for current and future effects.\n *\n *\n * This class is extended by p5.Distortion,\n * p5.Compressor,\n * p5.Delay,\n * p5.Filter,\n * p5.Reverb.\n *\n * @class p5.Effect\n * @constructor\n *\n * @param {Object} [ac] Reference to the audio context of the p5 object\n * @param {AudioNode} [input] Gain Node effect wrapper\n * @param {AudioNode} [output] Gain Node effect wrapper\n * @param {Object} [_drywet] Tone.JS CrossFade node (defaults to value: 1)\n * @param {AudioNode} [wet] Effects that extend this class should connect\n * to the wet signal to this gain node, so that dry and wet\n * signals are mixed properly.\n */\n p5.Effect = function() {\n this.ac = p5sound.audiocontext;\n\n this.input = this.ac.createGain();\n this.output = this.ac.createGain();\n\n /**\n *\tThe p5.Effect class is built\n * \tusing Tone.js CrossFade\n * \t@private\n */\n\n this._drywet = new CrossFade(1);\n\n /**\n *\tIn classes that extend\n *\tp5.Effect, connect effect nodes\n *\tto the wet parameter\n */\n this.wet = this.ac.createGain();\n\n this.input.connect(this._drywet.a);\n this.wet.connect(this._drywet.b);\n this._drywet.connect(this.output);\n\n this.connect();\n\n //Add to the soundArray\n p5sound.soundArray.push(this);\n };\n\n /**\n * Set the output volume of the filter.\n *\n * @method amp\n * @for p5.Effect\n * @param {Number} [vol] amplitude between 0 and 1.0\n * @param {Number} [rampTime] create a fade that lasts until rampTime\n * @param {Number} [tFromNow] schedule this event to happen in tFromNow seconds\n */\n p5.Effect.prototype.amp = function(vol, rampTime, tFromNow){\n var rampTime = rampTime || 0;\n var tFromNow = tFromNow || 0;\n var now = p5sound.audiocontext.currentTime;\n var currentVol = this.output.gain.value;\n this.output.gain.cancelScheduledValues(now);\n this.output.gain.linearRampToValueAtTime(currentVol, now + tFromNow + .001);\n this.output.gain.linearRampToValueAtTime(vol, now + tFromNow + rampTime + .001);\n };\n\n /**\n * Link effects together in a chain\n * Example usage: filter.chain(reverb, delay, panner);\n * May be used with an open-ended number of arguments\n *\n * @method chain\n * @for p5.Effect\n * @param {Object} [arguments] Chain together multiple sound objects\n */\n p5.Effect.prototype.chain = function(){\n if (arguments.length>0){\n this.connect(arguments[0]);\n for(var i=1;i\n * var notes = [60, 64, 67, 72];\n * var i = 0;\n *\n * function setup() {\n * osc = new p5.Oscillator('Triangle');\n * osc.start();\n * frameRate(1);\n * }\n *\n * function draw() {\n * var freq = midiToFreq(notes[i]);\n * osc.freq(freq);\n * i++;\n * if (i >= notes.length){\n * i = 0;\n * }\n * }\n * \n */\n var midiToFreq = p5.prototype.midiToFreq = function(m) {\n return 440 * Math.pow(2, (m-69)/12.0);\n };\n\n // This method converts ANSI notes specified as a string \"C4\", \"Eb3\" to a frequency\n var noteToFreq = function(note) {\n if (typeof note !== 'string') {\n return note;\n }\n var wholeNotes = {A:21, B:23, C:24, D:26, E:28, F:29, G:31};\n var value = wholeNotes[ note[0].toUpperCase() ];\n var octave = ~~note.slice(-1);\n value += 12 * (octave -1);\n\n switch(note[1]) {\n case '#':\n value += 1;\n break;\n case 'b':\n value -= 1;\n break;\n default:\n break;\n }\n return midiToFreq(value);\n };\n\n /**\n * List the SoundFile formats that you will include. LoadSound\n * will search your directory for these extensions, and will pick\n * a format that is compatable with the client's web browser.\n * Here is a free online file\n * converter.\n *\n * @method soundFormats\n * @param {String} [...formats] i.e. 'mp3', 'wav', 'ogg'\n * @example\n *
\n * function preload() {\n * // set the global sound formats\n * soundFormats('mp3', 'ogg');\n *\n * // load either beatbox.mp3, or .ogg, depending on browser\n * mySound = loadSound('assets/beatbox.mp3');\n * }\n *\n * function setup() {\n * mySound.play();\n * }\n *
\n */\n p5.prototype.soundFormats = function() {\n // reset extensions array\n p5sound.extensions = [];\n // add extensions\n for (var i = 0; i < arguments.length; i++) {\n arguments[i] = arguments[i].toLowerCase();\n if (['mp3','wav','ogg', 'm4a', 'aac'].indexOf(arguments[i]) > -1) {\n p5sound.extensions.push(arguments[i]);\n } else {\n throw arguments[i] + ' is not a valid sound format!';\n }\n }\n };\n\n p5.prototype.disposeSound = function() {\n for (var i = 0; i < p5sound.soundArray.length; i++) {\n p5sound.soundArray[i].dispose();\n }\n };\n\n // register removeSound to dispose of p5sound SoundFiles, Convolvers,\n // Oscillators etc when sketch ends\n p5.prototype.registerMethod('remove', p5.prototype.disposeSound);\n\n p5.prototype._checkFileFormats = function(paths) {\n var path;\n // if path is a single string, check to see if extension is provided\n if (typeof paths === 'string') {\n path = paths;\n // see if extension is provided\n var extTest = path.split('.').pop();\n // if an extension is provided...\n if (['mp3','wav','ogg', 'm4a', 'aac'].indexOf(extTest) > -1) {\n if (p5.prototype.isFileSupported(extTest)) {\n path = path;\n }\n else {\n var pathSplit = path.split('.');\n var pathCore = pathSplit[pathSplit.length - 1];\n for (var i = 0; i 1) {\n rightChannel = audioBuffer.getChannelData(1);\n } else {\n rightChannel = leftChannel;\n }\n\n var interleaved = interleave(leftChannel, rightChannel);\n\n // create the buffer and view to create the .WAV file\n var buffer = new window.ArrayBuffer(44 + interleaved.length * 2);\n var view = new window.DataView(buffer);\n\n // write the WAV container,\n // check spec at: https://web.archive.org/web/20171215131933/http://tiny.systems/software/soundProgrammer/WavFormatDocs.pdf\n\n // RIFF chunk descriptor\n writeUTFBytes(view, 0, 'RIFF');\n view.setUint32(4, 36 + interleaved.length * 2, true);\n writeUTFBytes(view, 8, 'WAVE');\n // FMT sub-chunk\n writeUTFBytes(view, 12, 'fmt ');\n view.setUint32(16, 16, true);\n view.setUint16(20, 1, true);\n // stereo (2 channels)\n view.setUint16(22, 2, true);\n view.setUint32(24, p5sound.audiocontext.sampleRate, true);\n view.setUint32(28, p5sound.audiocontext.sampleRate * 4, true);\n view.setUint16(32, 4, true);\n view.setUint16(34, 16, true);\n // data sub-chunk\n writeUTFBytes(view, 36, 'data');\n view.setUint32(40, interleaved.length * 2, true);\n\n // write the PCM samples\n var lng = interleaved.length;\n var index = 44;\n var volume = 1;\n for (var i = 0; i < lng; i++) {\n view.setInt16(index, interleaved[i] * (0x7FFF * volume), true);\n index += 2;\n }\n\n return view;\n }\n\n // helper methods to save waves\n function interleave(leftChannel, rightChannel) {\n var length = leftChannel.length + rightChannel.length;\n var result = new Float32Array(length);\n\n var inputIndex = 0;\n\n for (var index = 0; index < length;) {\n result[index++] = leftChannel[inputIndex];\n result[index++] = rightChannel[inputIndex];\n inputIndex++;\n }\n return result;\n }\n\n function writeUTFBytes(view, offset, string) {\n var lng = string.length;\n for (var i = 0; i < lng; i++) {\n view.setUint8(offset + i, string.charCodeAt(i));\n }\n }\n\n return {\n convertToWav: convertToWav,\n midiToFreq: midiToFreq,\n noteToFreq: noteToFreq\n };\n\n});\n","define([\"Tone/core/Tone\", \"Tone/signal/Signal\", \"Tone/core/Gain\"], function(Tone){\n\n\t\"use strict\";\n\n\t/**\n\t * @class Add a signal and a number or two signals. When no value is\n\t * passed into the constructor, Tone.Add will sum input[0]\n\t * and input[1]. If a value is passed into the constructor, \n\t * the it will be added to the input.\n\t * \n\t * @constructor\n\t * @extends {Tone.Signal}\n\t * @param {number=} value If no value is provided, Tone.Add will sum the first\n\t * and second inputs. \n\t * @example\n\t * var signal = new Tone.Signal(2);\n\t * var add = new Tone.Add(2);\n\t * signal.connect(add);\n\t * //the output of add equals 4\n\t * @example\n\t * //if constructed with no arguments\n\t * //it will add the first and second inputs\n\t * var add = new Tone.Add();\n\t * var sig0 = new Tone.Signal(3).connect(add, 0, 0);\n\t * var sig1 = new Tone.Signal(4).connect(add, 0, 1);\n\t * //the output of add equals 7. \n\t */\n\tTone.Add = function(value){\n\n\t\tthis.createInsOuts(2, 0);\n\n\t\t/**\n\t\t * the summing node\n\t\t * @type {GainNode}\n\t\t * @private\n\t\t */\n\t\tthis._sum = this.input[0] = this.input[1] = this.output = new Tone.Gain();\n\n\t\t/**\n\t\t * @private\n\t\t * @type {Tone.Signal}\n\t\t */\n\t\tthis._param = this.input[1] = new Tone.Signal(value);\n\n\t\tthis._param.connect(this._sum);\n\t};\n\n\tTone.extend(Tone.Add, Tone.Signal);\n\t\n\t/**\n\t * Clean up.\n\t * @returns {Tone.Add} this\n\t */\n\tTone.Add.prototype.dispose = function(){\n\t\tTone.prototype.dispose.call(this);\n\t\tthis._sum.dispose();\n\t\tthis._sum = null;\n\t\tthis._param.dispose();\n\t\tthis._param = null;\n\t\treturn this;\n\t}; \n\n\treturn Tone.Add;\n});","define([\"Tone/core/Tone\", \"Tone/type/Time\", \"Tone/type/Frequency\", \"Tone/type/TransportTime\", \"Tone/core/Context\"],\nfunction (Tone) {\t\n\n\t///////////////////////////////////////////////////////////////////////////\n\t//\tTYPES\n\t///////////////////////////////////////////////////////////////////////////\n\n\t/**\n\t * Units which a value can take on.\n\t * @enum {String}\n\t */\n\tTone.Type = {\n\t\t/** \n\t\t * Default units\n\t\t * @typedef {Default}\n\t\t */\n\t\tDefault : \"number\",\n\t\t/**\n\t\t * Time can be described in a number of ways. Read more [Time](https://github.com/Tonejs/Tone.js/wiki/Time).\n\t\t *\n\t\t *
\n\t\t *
Numbers, which will be taken literally as the time (in seconds).
\n\t\t *
Notation, (\"4n\", \"8t\") describes time in BPM and time signature relative values.
\n\t\t *
TransportTime, (\"4:3:2\") will also provide tempo and time signature relative times \n\t\t * in the form BARS:QUARTERS:SIXTEENTHS.
\n\t\t *
Frequency, (\"8hz\") is converted to the length of the cycle in seconds.
\n\t\t *
Now-Relative, (\"+1\") prefix any of the above with \"+\" and it will be interpreted as \n\t\t * \"the current time plus whatever expression follows\".
\n\t\t *
Expressions, (\"3:0 + 2 - (1m / 7)\") any of the above can also be combined \n\t\t * into a mathematical expression which will be evaluated to compute the desired time.
\n\t\t *
No Argument, for methods which accept time, no argument will be interpreted as \n\t\t * \"now\" (i.e. the currentTime).
\n\t\t *
\n\t\t * \n\t\t * @typedef {Time}\n\t\t */\n\t\tTime : \"time\",\n\t\t/**\n\t\t * Frequency can be described similar to time, except ultimately the\n\t\t * values are converted to frequency instead of seconds. A number\n\t\t * is taken literally as the value in hertz. Additionally any of the \n\t\t * Time encodings can be used. Note names in the form\n\t\t * of NOTE OCTAVE (i.e. C4) are also accepted and converted to their\n\t\t * frequency value. \n\t\t * @typedef {Frequency}\n\t\t */\n\t\tFrequency : \"frequency\",\n\t\t/**\n\t\t * TransportTime describes a position along the Transport's timeline. It is\n\t\t * similar to Time in that it uses all the same encodings, but TransportTime specifically\n\t\t * pertains to the Transport's timeline, which is startable, stoppable, loopable, and seekable. \n\t\t * [Read more](https://github.com/Tonejs/Tone.js/wiki/TransportTime)\n\t\t * @typedef {TransportTime}\n\t\t */\n\t\tTransportTime : \"transportTime\",\n\t\t/** \n\t\t * Ticks are the basic subunit of the Transport. They are\n\t\t * the smallest unit of time that the Transport supports.\n\t\t * @typedef {Ticks}\n\t\t */\n\t\tTicks : \"ticks\",\n\t\t/** \n\t\t * Normal values are within the range [0, 1].\n\t\t * @typedef {NormalRange}\n\t\t */\n\t\tNormalRange : \"normalRange\",\n\t\t/** \n\t\t * AudioRange values are between [-1, 1].\n\t\t * @typedef {AudioRange}\n\t\t */\n\t\tAudioRange : \"audioRange\",\n\t\t/** \n\t\t * Decibels are a logarithmic unit of measurement which is useful for volume\n\t\t * because of the logarithmic way that we perceive loudness. 0 decibels \n\t\t * means no change in volume. -10db is approximately half as loud and 10db \n\t\t * is twice is loud. \n\t\t * @typedef {Decibels}\n\t\t */\n\t\tDecibels : \"db\",\n\t\t/** \n\t\t * Half-step note increments, i.e. 12 is an octave above the root. and 1 is a half-step up.\n\t\t * @typedef {Interval}\n\t\t */\n\t\tInterval : \"interval\",\n\t\t/** \n\t\t * Beats per minute. \n\t\t * @typedef {BPM}\n\t\t */\n\t\tBPM : \"bpm\",\n\t\t/** \n\t\t * The value must be greater than or equal to 0.\n\t\t * @typedef {Positive}\n\t\t */\n\t\tPositive : \"positive\",\n\t\t/** \n\t\t * A cent is a hundredth of a semitone. \n\t\t * @typedef {Cents}\n\t\t */\n\t\tCents : \"cents\",\n\t\t/** \n\t\t * Angle between 0 and 360. \n\t\t * @typedef {Degrees}\n\t\t */\n\t\tDegrees : \"degrees\",\n\t\t/** \n\t\t * A number representing a midi note.\n\t\t * @typedef {MIDI}\n\t\t */\n\t\tMIDI : \"midi\",\n\t\t/** \n\t\t * A colon-separated representation of time in the form of\n\t\t * Bars:Beats:Sixteenths. \n\t\t * @typedef {BarsBeatsSixteenths}\n\t\t */\n\t\tBarsBeatsSixteenths : \"barsBeatsSixteenths\",\n\t\t/** \n\t\t * Sampling is the reduction of a continuous signal to a discrete signal.\n\t\t * Audio is typically sampled 44100 times per second. \n\t\t * @typedef {Samples}\n\t\t */\n\t\tSamples : \"samples\",\n\t\t/** \n\t\t * Hertz are a frequency representation defined as one cycle per second.\n\t\t * @typedef {Hertz}\n\t\t */\n\t\tHertz : \"hertz\",\n\t\t/** \n\t\t * A frequency represented by a letter name, \n\t\t * accidental and octave. This system is known as\n\t\t * [Scientific Pitch Notation](https://en.wikipedia.org/wiki/Scientific_pitch_notation).\n\t\t * @typedef {Note}\n\t\t */\n\t\tNote : \"note\",\n\t\t/** \n\t\t * One millisecond is a thousandth of a second. \n\t\t * @typedef {Milliseconds}\n\t\t */\n\t\tMilliseconds : \"milliseconds\",\n\t\t/** \n\t\t * Seconds are the time unit of the AudioContext. In the end, \n\t\t * all values need to be evaluated to seconds. \n\t\t * @typedef {Seconds}\n\t\t */\n\t\tSeconds : \"seconds\",\n\t\t/** \n\t\t * A string representing a duration relative to a measure. \n\t\t *
\n\t\t * \t
\"4n\" = quarter note
\n\t\t * \t
\"2m\" = two measures
\n\t\t * \t
\"8t\" = eighth-note triplet
\n\t\t *
\n\t\t * @typedef {Notation}\n\t\t */\n\t\tNotation : \"notation\",\n\t};\n\n\t///////////////////////////////////////////////////////////////////////////\n\t// AUGMENT TONE's PROTOTYPE\n\t///////////////////////////////////////////////////////////////////////////\n\n\t/**\n\t * Convert Time into seconds.\n\t * \n\t * Unlike the method which it overrides, this takes into account \n\t * transporttime and musical notation.\n\t *\n\t * Time : 1.40\n\t * Notation: 4n|1m|2t\n\t * Now Relative: +3n\n\t * Math: 3n+16n or even complicated expressions ((3n*2)/6 + 1)\n\t *\n\t * @param {Time} time \n\t * @return {Seconds} \n\t */\n\tTone.prototype.toSeconds = function(time){\n\t\tif (this.isNumber(time)){\n\t\t\treturn time;\n\t\t} else if (this.isUndef(time)){\n\t\t\treturn this.now();\t\t\t\n\t\t} else if (this.isString(time)){\n\t\t\treturn (new Tone.Time(time)).toSeconds();\n\t\t} else if (time instanceof Tone.TimeBase){\n\t\t\treturn time.toSeconds();\n\t\t}\n\t};\n\n\t/**\n\t * Convert a frequency representation into a number.\n\t * @param {Frequency} freq \n\t * @return {Hertz} the frequency in hertz\n\t */\n\tTone.prototype.toFrequency = function(freq){\n\t\tif (this.isNumber(freq)){\n\t\t\treturn freq;\n\t\t} else if (this.isString(freq) || this.isUndef(freq)){\n\t\t\treturn (new Tone.Frequency(freq)).valueOf();\n\t\t} else if (freq instanceof Tone.TimeBase){\n\t\t\treturn freq.toFrequency();\n\t\t}\n\t};\n\n\t/**\n\t * Convert a time representation into ticks.\n\t * @param {Time} time\n\t * @return {Ticks} the time in ticks\n\t */\n\tTone.prototype.toTicks = function(time){\n\t\tif (this.isNumber(time) || this.isString(time)){\n\t\t\treturn (new Tone.TransportTime(time)).toTicks();\n\t\t} else if (this.isUndef(time)){\n\t\t\treturn Tone.Transport.ticks;\t\t\t\n\t\t} else if (time instanceof Tone.TimeBase){\n\t\t\treturn time.toTicks();\n\t\t}\n\t};\n\n\treturn Tone;\n});","define([\"Tone/core/Tone\", \"Tone/core/Param\", \"Tone/type/Type\"], function (Tone) {\n\n\t\"use strict\";\n\n\t/**\n\t * createGain shim\n\t * @private\n\t */\n\tif (window.GainNode && !AudioContext.prototype.createGain){\n\t\tAudioContext.prototype.createGain = AudioContext.prototype.createGainNode;\n\t}\n\n\t/**\n\t * @class A thin wrapper around the Native Web Audio GainNode.\n\t * The GainNode is a basic building block of the Web Audio\n\t * API and is useful for routing audio and adjusting gains. \n\t * @extends {Tone}\n\t * @param {Number=} gain The initial gain of the GainNode\n\t * @param {Tone.Type=} units The units of the gain parameter. \n\t */\n\tTone.Gain = function(){\n\n\t\tvar options = this.optionsObject(arguments, [\"gain\", \"units\"], Tone.Gain.defaults);\n\n\t\t/**\n\t\t * The GainNode\n\t\t * @type {GainNode}\n\t\t * @private\n\t\t */\n\t\tthis.input = this.output = this._gainNode = this.context.createGain();\n\n\t\t/**\n\t\t * The gain parameter of the gain node.\n\t\t * @type {Tone.Param}\n\t\t * @signal\n\t\t */\n\t\tthis.gain = new Tone.Param({\n\t\t\t\"param\" : this._gainNode.gain, \n\t\t\t\"units\" : options.units,\n\t\t\t\"value\" : options.gain,\n\t\t\t\"convert\" : options.convert\n\t\t});\n\t\tthis._readOnly(\"gain\");\n\t};\n\n\tTone.extend(Tone.Gain);\n\n\t/**\n\t * The defaults\n\t * @const\n\t * @type {Object}\n\t */\n\tTone.Gain.defaults = {\n\t\t\"gain\" : 1,\n\t\t\"convert\" : true,\n\t};\n\n\t/**\n\t * Clean up.\n\t * @return {Tone.Gain} this\n\t */\n\tTone.Gain.prototype.dispose = function(){\n\t\tTone.Param.prototype.dispose.call(this);\n\t\tthis._gainNode.disconnect();\n\t\tthis._gainNode = null;\n\t\tthis._writable(\"gain\");\n\t\tthis.gain.dispose();\n\t\tthis.gain = null;\n\t};\n\n\t//STATIC///////////////////////////////////////////////////////////////////\n\n\t/**\n\t * Create input and outputs for this object.\n\t * @param {Number} input The number of inputs\n\t * @param {Number=} outputs The number of outputs\n\t * @return {Tone} this\n\t * @internal\n\t */\n\tTone.prototype.createInsOuts = function(inputs, outputs){\n\n\t\tif (inputs === 1){\n\t\t\tthis.input = new Tone.Gain();\n\t\t} else if (inputs > 1){\n\t\t\tthis.input = new Array(inputs);\n\t\t}\n\n\t\tif (outputs === 1){\n\t\t\tthis.output = new Tone.Gain();\n\t\t} else if (outputs > 1){\n\t\t\tthis.output = new Array(inputs);\n\t\t}\n\t};\n\n\t///////////////////////////////////////////////////////////////////////////\n\n\treturn Tone.Gain;\n});","'use strict';\n\ndefine(function () {\n /*\n Helper function to generate an error\n with a custom stack trace that points to the sketch\n and removes other parts of the stack trace.\n\n @private\n @class customError\n @constructor\n @param {String} name custom error name\n @param {String} errorTrace custom error trace\n @param {String} failedPath path to the file that failed to load\n @property {String} name custom error name\n @property {String} message custom error message\n @property {String} stack trace the error back to a line in the user's sketch.\n Note: this edits out stack trace within p5.js and p5.sound.\n @property {String} originalStack unedited, original stack trace\n @property {String} failedPath path to the file that failed to load\n @return {Error} returns a custom Error object\n */\n var CustomError = function(name, errorTrace, failedPath) {\n var err = new Error();\n var tempStack, splitStack;\n\n err.name = name;\n err.originalStack = err.stack + errorTrace;\n tempStack = err.stack + errorTrace;\n err.failedPath = failedPath;\n\n // only print the part of the stack trace that refers to the user code:\n var splitStack = tempStack.split('\\n');\n splitStack = splitStack.filter(function(ln) {\n return !ln.match(/(p5.|native code|globalInit)/g);\n });\n err.stack = splitStack.join('\\n');\n\n return err; // TODO: is this really a constructor?\n };\n\n return CustomError;\n});\n","define([\"Tone/core/Tone\", \"Tone/core/Emitter\"], function (Tone) {\n\n\t/**\n\t * shim\n\t * @private\n\t */\n\tif (!window.hasOwnProperty(\"AudioContext\") && window.hasOwnProperty(\"webkitAudioContext\")){\n\t\twindow.AudioContext = window.webkitAudioContext;\n\t}\n\n\t/**\n\t * @class Wrapper around the native AudioContext.\n\t * @extends {Tone.Emitter}\n\t * @param {AudioContext=} context optionally pass in a context\n\t */\n\tTone.Context = function(context){\n\n\t\tTone.Emitter.call(this);\n\n\t\tif (!context){\n\t\t\tcontext = new window.AudioContext();\n\t\t}\n\t\tthis._context = context;\n\t\t// extend all of the methods\n\t\tfor (var prop in this._context){\n\t\t\tthis._defineProperty(this._context, prop);\n\t\t}\n\n\t\t///////////////////////////////////////////////////////////////////////\n\t\t// WORKER\n\t\t///////////////////////////////////////////////////////////////////////\n\n\t\t/**\n\t\t * The default latency hint\n\t\t * @type {String}\n\t\t * @private\n\t\t */\n\t\tthis._latencyHint = \"interactive\";\n\n\t\t/**\n\t\t * The amount of time events are scheduled\n\t\t * into the future\n\t\t * @type {Number}\n\t\t * @private\n\t\t */\n\t\tthis._lookAhead = 0.1;\n\n\t\t/**\n\t\t * How often the update look runs\n\t\t * @type {Number}\n\t\t * @private\n\t\t */\n\t\tthis._updateInterval = this._lookAhead/3;\n\n\t\t/**\n\t\t * A reference to the actual computed update interval\n\t\t * @type {Number}\n\t\t * @private\n\t\t */\n\t\tthis._computedUpdateInterval = 0;\n\n\t\t/**\n\t\t * The web worker which is used to update Tone.Clock\n\t\t * @private\n\t\t * @type {WebWorker}\n\t\t */\n\t\tthis._worker = this._createWorker();\n\n\t\t/**\n\t\t * An object containing all of the constants AudioBufferSourceNodes\n\t\t * @type {Object}\n\t\t * @private\n\t\t */\n\t\tthis._constants = {};\n\n\t};\n\n\tTone.extend(Tone.Context, Tone.Emitter);\n\tTone.Emitter.mixin(Tone.Context);\n\n\t/**\n\t * Define a property on this Tone.Context. \n\t * This is used to extend the native AudioContext\n\t * @param {AudioContext} context\n\t * @param {String} prop \n\t * @private\n\t */\n\tTone.Context.prototype._defineProperty = function(context, prop){\n\t\tif (this.isUndef(this[prop])){\n\t\t\tObject.defineProperty(this, prop, {\n\t\t\t\tget : function(){\n\t\t\t\t\tif (typeof context[prop] === \"function\"){\n\t\t\t\t\t\treturn context[prop].bind(context);\n\t\t\t\t\t} else {\n\t\t\t\t\t\treturn context[prop];\n\t\t\t\t\t}\n\t\t\t\t},\n\t\t\t\tset : function(val){\n\t\t\t\t\tcontext[prop] = val;\n\t\t\t\t}\n\t\t\t});\n\t\t}\n\t};\n\n\t/**\n\t * The current audio context time\n\t * @return {Number}\n\t */\n\tTone.Context.prototype.now = function(){\n\t\treturn this._context.currentTime;\n\t};\n\n\t/**\n\t * Generate a web worker\n\t * @return {WebWorker}\n\t * @private\n\t */\n\tTone.Context.prototype._createWorker = function(){\n\t\t\n\t\t//URL Shim\n\t\twindow.URL = window.URL || window.webkitURL;\n\n\t\tvar blob = new Blob([\n\t\t\t//the initial timeout time\n\t\t\t\"var timeoutTime = \"+(this._updateInterval * 1000).toFixed(1)+\";\" +\n\t\t\t//onmessage callback\n\t\t\t\"self.onmessage = function(msg){\" +\n\t\t\t\"\ttimeoutTime = parseInt(msg.data);\" + \n\t\t\t\"};\" + \n\t\t\t//the tick function which posts a message\n\t\t\t//and schedules a new tick\n\t\t\t\"function tick(){\" +\n\t\t\t\"\tsetTimeout(tick, timeoutTime);\" +\n\t\t\t\"\tself.postMessage('tick');\" +\n\t\t\t\"}\" +\n\t\t\t//call tick initially\n\t\t\t\"tick();\"\n\t\t]);\n\t\tvar blobUrl = URL.createObjectURL(blob);\n\t\tvar worker = new Worker(blobUrl);\n\n\t\tworker.addEventListener(\"message\", function(){\n\t\t\t// tick the clock\n\t\t\tthis.emit(\"tick\");\n\t\t}.bind(this));\n\n\t\t//lag compensation\n\t\tworker.addEventListener(\"message\", function(){\n\t\t\tvar now = this.now();\n\t\t\tif (this.isNumber(this._lastUpdate)){\n\t\t\t\tvar diff = now - this._lastUpdate;\n\t\t\t\tthis._computedUpdateInterval = Math.max(diff, this._computedUpdateInterval * 0.97);\n\t\t\t}\n\t\t\tthis._lastUpdate = now;\n\t\t}.bind(this));\n\n\t\treturn worker;\n\t};\n\n\t/**\n\t * Generate a looped buffer at some constant value.\n\t * @param {Number} val\n\t * @return {BufferSourceNode}\n\t */\n\tTone.Context.prototype.getConstant = function(val){\n\t\tif (this._constants[val]){\n\t\t\treturn this._constants[val];\n\t\t} else {\n\t\t\tvar buffer = this._context.createBuffer(1, 128, this._context.sampleRate);\n\t\t\tvar arr = buffer.getChannelData(0);\n\t\t\tfor (var i = 0; i < arr.length; i++){\n\t\t\t\tarr[i] = val;\n\t\t\t}\n\t\t\tvar constant = this._context.createBufferSource();\n\t\t\tconstant.channelCount = 1;\n\t\t\tconstant.channelCountMode = \"explicit\";\n\t\t\tconstant.buffer = buffer;\n\t\t\tconstant.loop = true;\n\t\t\tconstant.start(0);\n\t\t\tthis._constants[val] = constant;\n\t\t\treturn constant;\n\t\t}\n\t};\n\n\t/**\n\t * This is the time that the clock is falling behind\n\t * the scheduled update interval. The Context automatically\n\t * adjusts for the lag and schedules further in advance.\n\t * @type {Number}\n\t * @memberOf Tone.Context\n\t * @name lag\n\t * @static\n\t * @readOnly\n\t */\n\tObject.defineProperty(Tone.Context.prototype, \"lag\", {\n\t\tget : function(){\n\t\t\tvar diff = this._computedUpdateInterval - this._updateInterval;\n\t\t\tdiff = Math.max(diff, 0);\n\t\t\treturn diff;\n\t\t}\n\t});\n\n\t/**\n\t * The amount of time in advance that events are scheduled.\n\t * The lookAhead will adjust slightly in response to the \n\t * measured update time to try to avoid clicks.\n\t * @type {Number}\n\t * @memberOf Tone.Context\n\t * @name lookAhead\n\t * @static\n\t */\n\tObject.defineProperty(Tone.Context.prototype, \"lookAhead\", {\n\t\tget : function(){\n\t\t\treturn this._lookAhead;\n\t\t},\n\t\tset : function(lA){\n\t\t\tthis._lookAhead = lA;\n\t\t}\n\t});\n\n\t/**\n\t * How often the Web Worker callback is invoked.\n\t * This number corresponds to how responsive the scheduling\n\t * can be. Context.updateInterval + Context.lookAhead gives you the\n\t * total latency between scheduling an event and hearing it.\n\t * @type {Number}\n\t * @memberOf Tone.Context\n\t * @name updateInterval\n\t * @static\n\t */\n\tObject.defineProperty(Tone.Context.prototype, \"updateInterval\", {\n\t\tget : function(){\n\t\t\treturn this._updateInterval;\n\t\t},\n\t\tset : function(interval){\n\t\t\tthis._updateInterval = Math.max(interval, Tone.prototype.blockTime);\n\t\t\tthis._worker.postMessage(Math.max(interval * 1000, 1));\n\t\t}\n\t});\n\n\t/**\n\t * The type of playback, which affects tradeoffs between audio \n\t * output latency and responsiveness. \n\t * \n\t * In addition to setting the value in seconds, the latencyHint also\n\t * accepts the strings \"interactive\" (prioritizes low latency), \n\t * \"playback\" (prioritizes sustained playback), \"balanced\" (balances\n\t * latency and performance), and \"fastest\" (lowest latency, might glitch more often). \n\t * @type {String|Seconds}\n\t * @memberOf Tone.Context#\n\t * @name latencyHint\n\t * @static\n\t * @example\n\t * //set the lookAhead to 0.3 seconds\n\t * Tone.context.latencyHint = 0.3;\n\t */\n\tObject.defineProperty(Tone.Context.prototype, \"latencyHint\", {\n\t\tget : function(){\n\t\t\treturn this._latencyHint;\n\t\t},\n\t\tset : function(hint){\n\t\t\tvar lookAhead = hint;\n\t\t\tthis._latencyHint = hint;\n\t\t\tif (this.isString(hint)){\n\t\t\t\tswitch(hint){\n\t\t\t\t\tcase \"interactive\" :\n\t\t\t\t\t\tlookAhead = 0.1;\n\t\t\t\t\t\tthis._context.latencyHint = hint;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase \"playback\" :\n\t\t\t\t\t\tlookAhead = 0.8;\n\t\t\t\t\t\tthis._context.latencyHint = hint;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase \"balanced\" :\n\t\t\t\t\t\tlookAhead = 0.25;\n\t\t\t\t\t\tthis._context.latencyHint = hint;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase \"fastest\" :\n\t\t\t\t\t\tlookAhead = 0.01;\n\t\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t\tthis.lookAhead = lookAhead;\n\t\t\tthis.updateInterval = lookAhead/3;\n\t\t}\n\t});\n\n\t/**\n\t * Shim all connect/disconnect and some deprecated methods which are still in\n\t * some older implementations.\n\t * @private\n\t */\n\tfunction shimConnect(){\n\n\t\tvar nativeConnect = AudioNode.prototype.connect;\n\t\tvar nativeDisconnect = AudioNode.prototype.disconnect;\n\n\t\t//replace the old connect method\n\t\tfunction toneConnect(B, outNum, inNum){\n\t\t\tif (B.input){\n\t\t\t\tif (Array.isArray(B.input)){\n\t\t\t\t\tif (Tone.prototype.isUndef(inNum)){\n\t\t\t\t\t\tinNum = 0;\n\t\t\t\t\t}\n\t\t\t\t\tthis.connect(B.input[inNum]);\n\t\t\t\t} else {\n\t\t\t\t\tthis.connect(B.input, outNum, inNum);\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\ttry {\n\t\t\t\t\tif (B instanceof AudioNode){\n\t\t\t\t\t\tnativeConnect.call(this, B, outNum, inNum);\n\t\t\t\t\t} else {\n\t\t\t\t\t\tnativeConnect.call(this, B, outNum);\n\t\t\t\t\t}\n\t\t\t\t} catch (e) {\n\t\t\t\t\tthrow new Error(\"error connecting to node: \"+B+\"\\n\"+e);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t//replace the old disconnect method\n\t\tfunction toneDisconnect(B, outNum, inNum){\n\t\t\tif (B && B.input && Array.isArray(B.input)){\n\t\t\t\tif (Tone.prototype.isUndef(inNum)){\n\t\t\t\t\tinNum = 0;\n\t\t\t\t}\n\t\t\t\tthis.disconnect(B.input[inNum], outNum, inNum);\n\t\t\t} else if (B && B.input){\n\t\t\t\tthis.disconnect(B.input, outNum, inNum);\n\t\t\t} else {\n\t\t\t\ttry {\n\t\t\t\t\tnativeDisconnect.apply(this, arguments);\n\t\t\t\t} catch (e) {\n\t\t\t\t\tthrow new Error(\"error disconnecting node: \"+B+\"\\n\"+e);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tif (AudioNode.prototype.connect !== toneConnect){\n\t\t\tAudioNode.prototype.connect = toneConnect;\n\t\t\tAudioNode.prototype.disconnect = toneDisconnect;\n\t\t}\n\t}\n\n\t// set the audio context initially\n\tif (Tone.supported){\n\t\tshimConnect();\n\t\tTone.context = new Tone.Context();\n\t} else {\n\t\tconsole.warn(\"This browser does not support Tone.js\");\n\t}\n\n\treturn Tone.Context;\n});","module.exports = {\n recorderProcessor: 'recorder-processor',\n soundFileProcessor: 'sound-file-processor',\n amplitudeProcessor: 'amplitude-processor'\n};\n","define([\"Tone/core/Tone\", \"Tone/signal/Add\", \"Tone/signal/Multiply\", \"Tone/signal/Signal\"], function(Tone){\n\n\t\"use strict\";\n\t\n\t/**\n\t * @class Performs a linear scaling on an input signal.\n\t * Scales a NormalRange input to between\n\t * outputMin and outputMax.\n\t *\n\t * @constructor\n\t * @extends {Tone.SignalBase}\n\t * @param {number} [outputMin=0] The output value when the input is 0. \n\t * @param {number} [outputMax=1]\tThe output value when the input is 1. \n\t * @example\n\t * var scale = new Tone.Scale(50, 100);\n\t * var signal = new Tone.Signal(0.5).connect(scale);\n\t * //the output of scale equals 75\n\t */\n\tTone.Scale = function(outputMin, outputMax){\n\n\t\t/** \n\t\t * @private\n\t\t * @type {number}\n\t\t */\n\t\tthis._outputMin = this.defaultArg(outputMin, 0);\n\n\t\t/** \n\t\t * @private\n\t\t * @type {number}\n\t\t */\n\t\tthis._outputMax = this.defaultArg(outputMax, 1);\n\n\n\t\t/** \n\t\t * @private\n\t\t * @type {Tone.Multiply}\n\t\t * @private\n\t\t */\n\t\tthis._scale = this.input = new Tone.Multiply(1);\n\t\t\n\t\t/** \n\t\t * @private\n\t\t * @type {Tone.Add}\n\t\t * @private\n\t\t */\n\t\tthis._add = this.output = new Tone.Add(0);\n\n\t\tthis._scale.connect(this._add);\n\t\tthis._setRange();\n\t};\n\n\tTone.extend(Tone.Scale, Tone.SignalBase);\n\n\t/**\n\t * The minimum output value. This number is output when \n\t * the value input value is 0. \n\t * @memberOf Tone.Scale#\n\t * @type {number}\n\t * @name min\n\t */\n\tObject.defineProperty(Tone.Scale.prototype, \"min\", {\n\t\tget : function(){\n\t\t\treturn this._outputMin;\n\t\t},\n\t\tset : function(min){\n\t\t\tthis._outputMin = min;\n\t\t\tthis._setRange();\n\t\t}\n\t});\n\n\t/**\n\t * The maximum output value. This number is output when \n\t * the value input value is 1. \n\t * @memberOf Tone.Scale#\n\t * @type {number}\n\t * @name max\n\t */\n\tObject.defineProperty(Tone.Scale.prototype, \"max\", {\n\t\tget : function(){\n\t\t\treturn this._outputMax;\n\t\t},\n\t\tset : function(max){\n\t\t\tthis._outputMax = max;\n\t\t\tthis._setRange();\n\t\t}\n\t});\n\n\t/**\n\t * set the values\n\t * @private\n\t */\n\tTone.Scale.prototype._setRange = function() {\n\t\tthis._add.value = this._outputMin;\n\t\tthis._scale.value = this._outputMax - this._outputMin;\n\t};\n\n\t/**\n\t * Clean up.\n\t * @returns {Tone.Scale} this\n\t */\n\tTone.Scale.prototype.dispose = function(){\n\t\tTone.prototype.dispose.call(this);\n\t\tthis._add.dispose();\n\t\tthis._add = null;\n\t\tthis._scale.dispose();\n\t\tthis._scale = null;\n\t\treturn this;\n\t}; \n\n\treturn Tone.Scale;\n});\n","define([\"Tone/core/Tone\", \"Tone/signal/Signal\", \"Tone/core/Timeline\"], function (Tone) {\n\n\t\"use strict\";\n\n\t/**\n\t * @class A signal which adds the method getValueAtTime. \n\t * Code and inspiration from https://github.com/jsantell/web-audio-automation-timeline\n\t * @extends {Tone.Param}\n\t * @param {Number=} value The initial value of the signal\n\t * @param {String=} units The conversion units of the signal.\n\t */\n\tTone.TimelineSignal = function(){\n\n\t\tvar options = this.optionsObject(arguments, [\"value\", \"units\"], Tone.Signal.defaults);\n\t\t\n\t\t/**\n\t\t * The scheduled events\n\t\t * @type {Tone.Timeline}\n\t\t * @private\n\t\t */\n\t\tthis._events = new Tone.Timeline(10);\n\n\t\t//constructors\n\t\tTone.Signal.apply(this, options);\n\t\toptions.param = this._param;\n\t\tTone.Param.call(this, options);\n\n\t\t/**\n\t\t * The initial scheduled value\n\t\t * @type {Number}\n\t\t * @private\n\t\t */\n\t\tthis._initial = this._fromUnits(this._param.value);\n\t};\n\n\tTone.extend(Tone.TimelineSignal, Tone.Param);\n\n\t/**\n\t * The event types of a schedulable signal.\n\t * @enum {String}\n\t * @private\n\t */\n\tTone.TimelineSignal.Type = {\n\t\tLinear : \"linear\",\n\t\tExponential : \"exponential\",\n\t\tTarget : \"target\",\n\t\tCurve : \"curve\",\n\t\tSet : \"set\"\n\t};\n\n\t/**\n\t * The current value of the signal. \n\t * @memberOf Tone.TimelineSignal#\n\t * @type {Number}\n\t * @name value\n\t */\n\tObject.defineProperty(Tone.TimelineSignal.prototype, \"value\", {\n\t\tget : function(){\n\t\t\tvar now = this.now();\n\t\t\tvar val = this.getValueAtTime(now);\n\t\t\treturn this._toUnits(val);\n\t\t},\n\t\tset : function(value){\n\t\t\tvar convertedVal = this._fromUnits(value);\n\t\t\tthis._initial = convertedVal;\n\t\t\tthis.cancelScheduledValues();\n\t\t\tthis._param.value = convertedVal;\n\t\t}\n\t});\n\n\t///////////////////////////////////////////////////////////////////////////\n\t//\tSCHEDULING\n\t///////////////////////////////////////////////////////////////////////////\n\n\t/**\n\t * Schedules a parameter value change at the given time.\n\t * @param {*}\tvalue The value to set the signal.\n\t * @param {Time} time The time when the change should occur.\n\t * @returns {Tone.TimelineSignal} this\n\t * @example\n\t * //set the frequency to \"G4\" in exactly 1 second from now. \n\t * freq.setValueAtTime(\"G4\", \"+1\");\n\t */\n\tTone.TimelineSignal.prototype.setValueAtTime = function (value, startTime) {\n\t\tvalue = this._fromUnits(value);\n\t\tstartTime = this.toSeconds(startTime);\n\t\tthis._events.add({\n\t\t\t\"type\" : Tone.TimelineSignal.Type.Set,\n\t\t\t\"value\" : value,\n\t\t\t\"time\" : startTime\n\t\t});\n\t\t//invoke the original event\n\t\tthis._param.setValueAtTime(value, startTime);\n\t\treturn this;\n\t};\n\n\t/**\n\t * Schedules a linear continuous change in parameter value from the \n\t * previous scheduled parameter value to the given value.\n\t * \n\t * @param {number} value \n\t * @param {Time} endTime \n\t * @returns {Tone.TimelineSignal} this\n\t */\n\tTone.TimelineSignal.prototype.linearRampToValueAtTime = function (value, endTime) {\n\t\tvalue = this._fromUnits(value);\n\t\tendTime = this.toSeconds(endTime);\n\t\tthis._events.add({\n\t\t\t\"type\" : Tone.TimelineSignal.Type.Linear,\n\t\t\t\"value\" : value,\n\t\t\t\"time\" : endTime\n\t\t});\n\t\tthis._param.linearRampToValueAtTime(value, endTime);\n\t\treturn this;\n\t};\n\n\t/**\n\t * Schedules an exponential continuous change in parameter value from \n\t * the previous scheduled parameter value to the given value.\n\t * \n\t * @param {number} value \n\t * @param {Time} endTime \n\t * @returns {Tone.TimelineSignal} this\n\t */\n\tTone.TimelineSignal.prototype.exponentialRampToValueAtTime = function (value, endTime) {\n\t\t//get the previous event and make sure it's not starting from 0\n\t\tendTime = this.toSeconds(endTime);\n\t\tvar beforeEvent = this._searchBefore(endTime);\n\t\tif (beforeEvent && beforeEvent.value === 0){\n\t\t\t//reschedule that event\n\t\t\tthis.setValueAtTime(this._minOutput, beforeEvent.time);\n\t\t}\n\t\tvalue = this._fromUnits(value);\n\t\tvar setValue = Math.max(value, this._minOutput);\n\t\tthis._events.add({\n\t\t\t\"type\" : Tone.TimelineSignal.Type.Exponential,\n\t\t\t\"value\" : setValue,\n\t\t\t\"time\" : endTime\n\t\t});\n\t\t//if the ramped to value is 0, make it go to the min output, and then set to 0.\n\t\tif (value < this._minOutput){\n\t\t\tthis._param.exponentialRampToValueAtTime(this._minOutput, endTime - this.sampleTime);\n\t\t\tthis.setValueAtTime(0, endTime);\n\t\t} else {\n\t\t\tthis._param.exponentialRampToValueAtTime(value, endTime);\n\t\t}\n\t\treturn this;\n\t};\n\n\t/**\n\t * Start exponentially approaching the target value at the given time with\n\t * a rate having the given time constant.\n\t * @param {number} value \n\t * @param {Time} startTime \n\t * @param {number} timeConstant \n\t * @returns {Tone.TimelineSignal} this \n\t */\n\tTone.TimelineSignal.prototype.setTargetAtTime = function (value, startTime, timeConstant) {\n\t\tvalue = this._fromUnits(value);\n\t\tvalue = Math.max(this._minOutput, value);\n\t\ttimeConstant = Math.max(this._minOutput, timeConstant);\n\t\tstartTime = this.toSeconds(startTime);\n\t\tthis._events.add({\n\t\t\t\"type\" : Tone.TimelineSignal.Type.Target,\n\t\t\t\"value\" : value,\n\t\t\t\"time\" : startTime,\n\t\t\t\"constant\" : timeConstant\n\t\t});\n\t\tthis._param.setTargetAtTime(value, startTime, timeConstant);\n\t\treturn this;\n\t};\n\n\t/**\n\t * Set an array of arbitrary values starting at the given time for the given duration.\n\t * @param {Float32Array} values \n\t * @param {Time} startTime \n\t * @param {Time} duration\n\t * @param {NormalRange} [scaling=1] If the values in the curve should be scaled by some value\n\t * @returns {Tone.TimelineSignal} this \n\t */\n\tTone.TimelineSignal.prototype.setValueCurveAtTime = function (values, startTime, duration, scaling) {\n\t\tscaling = this.defaultArg(scaling, 1);\n\t\t//copy the array\n\t\tvar floats = new Array(values.length);\n\t\tfor (var i = 0; i < floats.length; i++){\n\t\t\tfloats[i] = this._fromUnits(values[i]) * scaling;\n\t\t}\n\t\tstartTime = this.toSeconds(startTime);\n\t\tduration = this.toSeconds(duration);\n\t\tthis._events.add({\n\t\t\t\"type\" : Tone.TimelineSignal.Type.Curve,\n\t\t\t\"value\" : floats,\n\t\t\t\"time\" : startTime,\n\t\t\t\"duration\" : duration\n\t\t});\n\t\t//set the first value\n\t\tthis._param.setValueAtTime(floats[0], startTime);\n\t\t//schedule a lienar ramp for each of the segments\n\t\tfor (var j = 1; j < floats.length; j++){\n\t\t\tvar segmentTime = startTime + (j / (floats.length - 1) * duration);\n\t\t\tthis._param.linearRampToValueAtTime(floats[j], segmentTime);\n\t\t}\n\t\treturn this;\n\t};\n\n\t/**\n\t * Cancels all scheduled parameter changes with times greater than or \n\t * equal to startTime.\n\t * \n\t * @param {Time} startTime\n\t * @returns {Tone.TimelineSignal} this\n\t */\n\tTone.TimelineSignal.prototype.cancelScheduledValues = function (after) {\n\t\tafter = this.toSeconds(after);\n\t\tthis._events.cancel(after);\n\t\tthis._param.cancelScheduledValues(after);\n\t\treturn this;\n\t};\n\n\t/**\n\t * Sets the computed value at the given time. This provides\n\t * a point from which a linear or exponential curve\n\t * can be scheduled after. Will cancel events after \n\t * the given time and shorten the currently scheduled\n\t * linear or exponential ramp so that it ends at `time` .\n\t * This is to avoid discontinuities and clicks in envelopes. \n\t * @param {Time} time When to set the ramp point\n\t * @returns {Tone.TimelineSignal} this\n\t */\n\tTone.TimelineSignal.prototype.setRampPoint = function (time) {\n\t\ttime = this.toSeconds(time);\n\t\t//get the value at the given time\n\t\tvar val = this._toUnits(this.getValueAtTime(time));\n\t\t//if there is an event at the given time\n\t\t//and that even is not a \"set\"\n\t\tvar before = this._searchBefore(time);\n\t\tif (before && before.time === time){\n\t\t\t//remove everything after\n\t\t\tthis.cancelScheduledValues(time + this.sampleTime);\n\t\t} else if (before && \n\t\t\t\t before.type === Tone.TimelineSignal.Type.Curve &&\n\t\t\t\t before.time + before.duration > time){\n\t\t\t//if the curve is still playing\n\t\t\t//cancel the curve\n\t\t\tthis.cancelScheduledValues(time);\n\t\t\tthis.linearRampToValueAtTime(val, time);\n\t\t} else {\n\t\t\t//reschedule the next event to end at the given time\n\t\t\tvar after = this._searchAfter(time);\n\t\t\tif (after){\n\t\t\t\t//cancel the next event(s)\n\t\t\t\tthis.cancelScheduledValues(time);\n\t\t\t\tif (after.type === Tone.TimelineSignal.Type.Linear){\n\t\t\t\t\tthis.linearRampToValueAtTime(val, time);\n\t\t\t\t} else if (after.type === Tone.TimelineSignal.Type.Exponential){\n\t\t\t\t\tthis.exponentialRampToValueAtTime(val, time);\n\t\t\t\t}\n\t\t\t}\n\t\t\tthis.setValueAtTime(val, time);\n\t\t}\n\t\treturn this;\n\t};\n\n\t/**\n\t * Do a linear ramp to the given value between the start and finish times.\n\t * @param {Number} value The value to ramp to.\n\t * @param {Time} start The beginning anchor point to do the linear ramp\n\t * @param {Time} finish The ending anchor point by which the value of\n\t * the signal will equal the given value.\n\t * @returns {Tone.TimelineSignal} this\n\t */\n\tTone.TimelineSignal.prototype.linearRampToValueBetween = function (value, start, finish) {\n\t\tthis.setRampPoint(start);\n\t\tthis.linearRampToValueAtTime(value, finish);\n\t\treturn this;\n\t};\n\n\t/**\n\t * Do a exponential ramp to the given value between the start and finish times.\n\t * @param {Number} value The value to ramp to.\n\t * @param {Time} start The beginning anchor point to do the exponential ramp\n\t * @param {Time} finish The ending anchor point by which the value of\n\t * the signal will equal the given value.\n\t * @returns {Tone.TimelineSignal} this\n\t */\n\tTone.TimelineSignal.prototype.exponentialRampToValueBetween = function (value, start, finish) {\n\t\tthis.setRampPoint(start);\n\t\tthis.exponentialRampToValueAtTime(value, finish);\n\t\treturn this;\n\t};\n\n\t///////////////////////////////////////////////////////////////////////////\n\t//\tGETTING SCHEDULED VALUES\n\t///////////////////////////////////////////////////////////////////////////\n\n\t/**\n\t * Returns the value before or equal to the given time\n\t * @param {Number} time The time to query\n\t * @return {Object} The event at or before the given time.\n\t * @private\n\t */\n\tTone.TimelineSignal.prototype._searchBefore = function(time){\n\t\treturn this._events.get(time);\n\t};\n\n\t/**\n\t * The event after the given time\n\t * @param {Number} time The time to query.\n\t * @return {Object} The next event after the given time\n\t * @private\n\t */\n\tTone.TimelineSignal.prototype._searchAfter = function(time){\n\t\treturn this._events.getAfter(time);\n\t};\n\n\t/**\n\t * Get the scheduled value at the given time. This will\n\t * return the unconverted (raw) value.\n\t * @param {Number} time The time in seconds.\n\t * @return {Number} The scheduled value at the given time.\n\t */\n\tTone.TimelineSignal.prototype.getValueAtTime = function(time){\n\t\ttime = this.toSeconds(time);\n\t\tvar after = this._searchAfter(time);\n\t\tvar before = this._searchBefore(time);\n\t\tvar value = this._initial;\n\t\t//if it was set by\n\t\tif (before === null){\n\t\t\tvalue = this._initial;\n\t\t} else if (before.type === Tone.TimelineSignal.Type.Target){\n\t\t\tvar previous = this._events.getBefore(before.time);\n\t\t\tvar previouVal;\n\t\t\tif (previous === null){\n\t\t\t\tpreviouVal = this._initial;\n\t\t\t} else {\n\t\t\t\tpreviouVal = previous.value;\n\t\t\t}\n\t\t\tvalue = this._exponentialApproach(before.time, previouVal, before.value, before.constant, time);\n\t\t} else if (before.type === Tone.TimelineSignal.Type.Curve){\n\t\t\tvalue = this._curveInterpolate(before.time, before.value, before.duration, time);\n\t\t} else if (after === null){\n\t\t\tvalue = before.value;\n\t\t} else if (after.type === Tone.TimelineSignal.Type.Linear){\n\t\t\tvalue = this._linearInterpolate(before.time, before.value, after.time, after.value, time);\n\t\t} else if (after.type === Tone.TimelineSignal.Type.Exponential){\n\t\t\tvalue = this._exponentialInterpolate(before.time, before.value, after.time, after.value, time);\n\t\t} else {\n\t\t\tvalue = before.value;\n\t\t}\n\t\treturn value;\n\t};\n\n\t/**\n\t * When signals connect to other signals or AudioParams, \n\t * they take over the output value of that signal or AudioParam. \n\t * For all other nodes, the behavior is the same as a default connect. \n\t *\n\t * @override\n\t * @param {AudioParam|AudioNode|Tone.Signal|Tone} node \n\t * @param {number} [outputNumber=0] The output number to connect from.\n\t * @param {number} [inputNumber=0] The input number to connect to.\n\t * @returns {Tone.TimelineSignal} this\n\t * @method\n\t */\n\tTone.TimelineSignal.prototype.connect = Tone.SignalBase.prototype.connect;\n\n\n\t///////////////////////////////////////////////////////////////////////////\n\t//\tAUTOMATION CURVE CALCULATIONS\n\t//\tMIT License, copyright (c) 2014 Jordan Santell\n\t///////////////////////////////////////////////////////////////////////////\n\n\t/**\n\t * Calculates the the value along the curve produced by setTargetAtTime\n\t * @private\n\t */\n\tTone.TimelineSignal.prototype._exponentialApproach = function (t0, v0, v1, timeConstant, t) {\n\t\treturn v1 + (v0 - v1) * Math.exp(-(t - t0) / timeConstant);\n\t};\n\n\t/**\n\t * Calculates the the value along the curve produced by linearRampToValueAtTime\n\t * @private\n\t */\n\tTone.TimelineSignal.prototype._linearInterpolate = function (t0, v0, t1, v1, t) {\n\t\treturn v0 + (v1 - v0) * ((t - t0) / (t1 - t0));\n\t};\n\n\t/**\n\t * Calculates the the value along the curve produced by exponentialRampToValueAtTime\n\t * @private\n\t */\n\tTone.TimelineSignal.prototype._exponentialInterpolate = function (t0, v0, t1, v1, t) {\n\t\tv0 = Math.max(this._minOutput, v0);\n\t\treturn v0 * Math.pow(v1 / v0, (t - t0) / (t1 - t0));\n\t};\n\n\t/**\n\t * Calculates the the value along the curve produced by setValueCurveAtTime\n\t * @private\n\t */\n\tTone.TimelineSignal.prototype._curveInterpolate = function (start, curve, duration, time) {\n\t\tvar len = curve.length;\n\t\t// If time is after duration, return the last curve value\n\t\tif (time >= start + duration) {\n\t\t\treturn curve[len - 1];\n\t\t} else if (time <= start){\n\t\t\treturn curve[0];\n\t\t} else {\n\t\t\tvar progress = (time - start) / duration;\n\t\t\tvar lowerIndex = Math.floor((len - 1) * progress);\n\t\t\tvar upperIndex = Math.ceil((len - 1) * progress);\n\t\t\tvar lowerVal = curve[lowerIndex];\n\t\t\tvar upperVal = curve[upperIndex];\n\t\t\tif (upperIndex === lowerIndex){\n\t\t\t\treturn lowerVal;\n\t\t\t} else {\n\t\t\t\treturn this._linearInterpolate(lowerIndex, lowerVal, upperIndex, upperVal, progress * (len - 1));\n\t\t\t}\n\t\t}\n\t};\n\n\t/**\n\t * Clean up.\n\t * @return {Tone.TimelineSignal} this\n\t */\n\tTone.TimelineSignal.prototype.dispose = function(){\n\t\tTone.Signal.prototype.dispose.call(this);\n\t\tTone.Param.prototype.dispose.call(this);\n\t\tthis._events.dispose();\n\t\tthis._events = null;\n\t};\n\n\treturn Tone.TimelineSignal;\n});","'use strict';\n\ndefine(function (require) {\n var Effect = require('effect');\n\n /**\n *
A p5.Filter uses a Web Audio Biquad Filter to filter\n * the frequency response of an input source. Subclasses\n * include:
\n * p5.LowPass:\n * Allows frequencies below the cutoff frequency to pass through,\n * and attenuates frequencies above the cutoff. \n * p5.HighPass:\n * The opposite of a lowpass filter. \n * p5.BandPass:\n * Allows a range of frequencies to pass through and attenuates\n * the frequencies below and above this frequency range. \n *\n * The .res() method controls either width of the\n * bandpass, or resonance of the low/highpass cutoff frequency.\n *\n * This class extends p5.Effect.\n * Methods amp(), chain(),\n * drywet(), connect(), and\n * disconnect() are available.\n *\n * @class p5.Filter\n * @extends p5.Effect\n * @constructor\n * @param {String} [type] 'lowpass' (default), 'highpass', 'bandpass'\n * @example\n *
\n * var fft, noise, filter;\n *\n * function setup() {\n * fill(255, 40, 255);\n *\n * filter = new p5.BandPass();\n *\n * noise = new p5.Noise();\n * // disconnect unfiltered noise,\n * // and connect to filter\n * noise.disconnect();\n * noise.connect(filter);\n * noise.start();\n *\n * fft = new p5.FFT();\n * }\n *\n * function draw() {\n * background(30);\n *\n * // set the BandPass frequency based on mouseX\n * var freq = map(mouseX, 0, width, 20, 10000);\n * filter.freq(freq);\n * // give the filter a narrow band (lower res = wider bandpass)\n * filter.res(50);\n *\n * // draw filtered spectrum\n * var spectrum = fft.analyze();\n * noStroke();\n * for (var i = 0; i < spectrum.length; i++) {\n * var x = map(i, 0, spectrum.length, 0, width);\n * var h = -height + map(spectrum[i], 0, 255, height, 0);\n * rect(x, height, width/spectrum.length, h);\n * }\n *\n * isMouseOverCanvas();\n * }\n *\n * function isMouseOverCanvas() {\n * var mX = mouseX, mY = mouseY;\n * if (mX > 0 && mX < width && mY < height && mY > 0) {\n * noise.amp(0.5, 0.2);\n * } else {\n * noise.amp(0, 0.2);\n * }\n * }\n *
\n */\n p5.Filter = function (type) {\n\n Effect.call(this);\n //add extend Effect by adding a Biquad Filter\n\n /**\n * The p5.Filter is built with a\n * \n * Web Audio BiquadFilter Node.\n *\n * @property {DelayNode} biquadFilter\n\t */\n\n this.biquad = this.ac.createBiquadFilter();\n\n this.input.connect(this.biquad);\n\n this.biquad.connect(this.wet);\n\n if (type) {\n this.setType(type);\n }\n\n //Properties useful for the toggle method.\n this._on = true;\n this._untoggledType = this.biquad.type;\n };\n p5.Filter.prototype = Object.create(Effect.prototype);\n\n\n /**\n * Filter an audio signal according to a set\n * of filter parameters.\n *\n * @method process\n * @param {Object} Signal An object that outputs audio\n * @param {Number} [freq] Frequency in Hz, from 10 to 22050\n * @param {Number} [res] Resonance/Width of the filter frequency\n * from 0.001 to 1000\n */\n p5.Filter.prototype.process = function(src, freq, res, time) {\n src.connect(this.input);\n this.set(freq, res, time);\n };\n\n\n /**\n * Set the frequency and the resonance of the filter.\n *\n * @method set\n * @param {Number} [freq] Frequency in Hz, from 10 to 22050\n * @param {Number} [res] Resonance (Q) from 0.001 to 1000\n * @param {Number} [timeFromNow] schedule this event to happen\n * seconds from now\n */\n p5.Filter.prototype.set = function(freq, res, time) {\n if (freq) {\n this.freq(freq, time);\n }\n if (res) {\n this.res(res, time);\n }\n };\n\n /**\n * Set the filter frequency, in Hz, from 10 to 22050 (the range of\n * human hearing, although in reality most people hear in a narrower\n * range).\n *\n * @method freq\n * @param {Number} freq Filter Frequency\n * @param {Number} [timeFromNow] schedule this event to happen\n * seconds from now\n * @return {Number} value Returns the current frequency value\n */\n p5.Filter.prototype.freq = function(freq, time) {\n var t = time || 0;\n if (freq <= 0) {\n freq = 1;\n }\n if (typeof freq === 'number') {\n this.biquad.frequency.cancelScheduledValues(this.ac.currentTime + 0.01 + t);\n this.biquad.frequency.exponentialRampToValueAtTime(freq, this.ac.currentTime + 0.02 + t);\n } else if (freq) {\n freq.connect(this.biquad.frequency);\n }\n return this.biquad.frequency.value;\n };\n\n /**\n * Controls either width of a bandpass frequency,\n * or the resonance of a low/highpass cutoff frequency.\n *\n * @method res\n * @param {Number} res Resonance/Width of filter freq\n * from 0.001 to 1000\n * @param {Number} [timeFromNow] schedule this event to happen\n * seconds from now\n * @return {Number} value Returns the current res value\n */\n p5.Filter.prototype.res = function(res, time) {\n var t = time || 0;\n if (typeof res === 'number') {\n this.biquad.Q.value = res;\n this.biquad.Q.cancelScheduledValues(this.ac.currentTime + 0.01 + t);\n this.biquad.Q.linearRampToValueAtTime(res, this.ac.currentTime + 0.02 + t);\n } else if (res) {\n res.connect(this.biquad.Q);\n }\n return this.biquad.Q.value;\n };\n\n /**\n * Controls the gain attribute of a Biquad Filter.\n * This is distinctly different from .amp() which is inherited from p5.Effect\n * .amp() controls the volume via the output gain node\n * p5.Filter.gain() controls the gain parameter of a Biquad Filter node.\n *\n * @method gain\n * @param {Number} gain\n * @return {Number} Returns the current or updated gain value\n */\n p5.Filter.prototype.gain = function(gain, time) {\n var t = time || 0;\n if (typeof gain === 'number') {\n this.biquad.gain.value = gain;\n this.biquad.gain.cancelScheduledValues(this.ac.currentTime + 0.01 + t);\n this.biquad.gain.linearRampToValueAtTime(gain, this.ac.currentTime + 0.02 + t);\n } else if (gain) {\n gain.connect(this.biquad.gain);\n }\n return this.biquad.gain.value;\n };\n\n\n /**\n * Toggle function. Switches between the specified type and allpass\n *\n * @method toggle\n * @return {boolean} [Toggle value]\n */\n p5.Filter.prototype.toggle = function() {\n this._on = !this._on;\n\n if (this._on === true) {\n this.biquad.type = this._untoggledType;\n } else if (this._on === false) {\n this.biquad.type = 'allpass';\n }\n\n return this._on;\n };\n\n /**\n * Set the type of a p5.Filter. Possible types include:\n * \"lowpass\" (default), \"highpass\", \"bandpass\",\n * \"lowshelf\", \"highshelf\", \"peaking\", \"notch\",\n * \"allpass\".\n *\n * @method setType\n * @param {String} t\n */\n p5.Filter.prototype.setType = function(t) {\n this.biquad.type = t;\n this._untoggledType = this.biquad.type;\n };\n\n p5.Filter.prototype.dispose = function() {\n // remove reference from soundArray\n Effect.prototype.dispose.apply(this);\n if (this.biquad) {\n this.biquad.disconnect();\n delete this.biquad;\n }\n };\n\n /**\n * Constructor: new p5.LowPass() Filter.\n * This is the same as creating a p5.Filter and then calling\n * its method setType('lowpass').\n * See p5.Filter for methods.\n *\n * @class p5.LowPass\n * @constructor\n * @extends p5.Filter\n */\n p5.LowPass = function() {\n p5.Filter.call(this, 'lowpass');\n };\n p5.LowPass.prototype = Object.create(p5.Filter.prototype);\n\n /**\n * Constructor: new p5.HighPass() Filter.\n * This is the same as creating a p5.Filter and then calling\n * its method setType('highpass').\n * See p5.Filter for methods.\n *\n * @class p5.HighPass\n * @constructor\n * @extends p5.Filter\n */\n p5.HighPass = function() {\n p5.Filter.call(this, 'highpass');\n };\n p5.HighPass.prototype = Object.create(p5.Filter.prototype);\n\n /**\n * Constructor: new p5.BandPass() Filter.\n * This is the same as creating a p5.Filter and then calling\n * its method setType('bandpass').\n * See p5.Filter for methods.\n *\n * @class p5.BandPass\n * @constructor\n * @extends p5.Filter\n */\n p5.BandPass = function() {\n p5.Filter.call(this, 'bandpass');\n };\n p5.BandPass.prototype = Object.create(p5.Filter.prototype);\n\n return p5.Filter;\n});\n","define([\"Tone/core/Tone\", \"Tone/signal/Add\", \"Tone/signal/Negate\", \"Tone/signal/Signal\", \"Tone/core/Gain\"], function(Tone){\n\n\t\"use strict\";\n\n\t/**\n\t * @class Subtract the signal connected to input[1] from the signal connected \n\t * to input[0]. If an argument is provided in the constructor, the \n\t * signals .value will be subtracted from the incoming signal.\n\t *\n\t * @extends {Tone.Signal}\n\t * @constructor\n\t * @param {number=} value The value to subtract from the incoming signal. If the value\n\t * is omitted, it will subtract the second signal from the first.\n\t * @example\n\t * var sub = new Tone.Subtract(1);\n\t * var sig = new Tone.Signal(4).connect(sub);\n\t * //the output of sub is 3. \n\t * @example\n\t * var sub = new Tone.Subtract();\n\t * var sigA = new Tone.Signal(10);\n\t * var sigB = new Tone.Signal(2.5);\n\t * sigA.connect(sub, 0, 0);\n\t * sigB.connect(sub, 0, 1);\n\t * //output of sub is 7.5\n\t */\n\tTone.Subtract = function(value){\n\n\t\tthis.createInsOuts(2, 0);\n\n\t\t/**\n\t\t * the summing node\n\t\t * @type {GainNode}\n\t\t * @private\n\t\t */\n\t\tthis._sum = this.input[0] = this.output = new Tone.Gain();\n\n\t\t/**\n\t\t * negate the input of the second input before connecting it\n\t\t * to the summing node.\n\t\t * @type {Tone.Negate}\n\t\t * @private\n\t\t */\n\t\tthis._neg = new Tone.Negate();\n\n\t\t/**\n\t\t * the node where the value is set\n\t\t * @private\n\t\t * @type {Tone.Signal}\n\t\t */\n\t\tthis._param = this.input[1] = new Tone.Signal(value);\n\n\t\tthis._param.chain(this._neg, this._sum);\n\t};\n\n\tTone.extend(Tone.Subtract, Tone.Signal);\n\n\t/**\n\t * Clean up.\n\t * @returns {Tone.SignalBase} this\n\t */\n\tTone.Subtract.prototype.dispose = function(){\n\t\tTone.prototype.dispose.call(this);\n\t\tthis._neg.dispose();\n\t\tthis._neg = null;\n\t\tthis._sum.disconnect();\n\t\tthis._sum = null;\n\t\tthis._param.dispose();\n\t\tthis._param = null;\n\t\treturn this;\n\t};\n\n\treturn Tone.Subtract;\n});","'use strict';\n\nglobal.TONE_SILENCE_VERSION_LOGGING = true;\n\ndefine(['startaudiocontext', 'Tone/core/Context', 'Tone/core/Tone'], function (StartAudioContext, Context, Tone) {\n // Create the Audio Context\n const audiocontext = new window.AudioContext();\n\n // Tone and p5.sound share the same audio context\n Tone.context.dispose();\n Tone.setContext(audiocontext);\n\n /**\n *
Returns the Audio Context for this sketch. Useful for users\n * who would like to dig deeper into the Web Audio API\n * .
\n *\n *
Some browsers require users to startAudioContext\n * with a user gesture, such as touchStarted in the example below.
\n *\n * @method getAudioContext\n * @return {Object} AudioContext for this sketch\n * @example\n *
\n * function draw() {\n * background(255);\n * textAlign(CENTER);\n *\n * if (getAudioContext().state !== 'running') {\n * text('click to start audio', width/2, height/2);\n * } else {\n * text('audio is enabled', width/2, height/2);\n * }\n * }\n *\n * function touchStarted() {\n * if (getAudioContext().state !== 'running') {\n * getAudioContext().resume();\n * }\n * var synth = new p5.MonoSynth();\n * synth.play('A4', 0.5, 0, 0.2);\n * }\n *\n *
It is a good practice to give users control over starting audio playback.\n * This practice is enforced by Google Chrome's autoplay policy as of r70\n * (info), iOS Safari, and other browsers.\n *
\n *\n *
\n * userStartAudio() starts the Audio Context on a user gesture. It utilizes\n * the StartAudioContext library by\n * Yotam Mann (MIT Licence, 2016). Read more at https://github.com/tambien/StartAudioContext.\n *
\n *\n *
Starting the audio context on a user gesture can be as simple as userStartAudio().\n * Optional parameters let you decide on a specific element that will start the audio context,\n * and/or call a function once the audio context is started.
\n * @param {Element|Array} [element(s)] This argument can be an Element,\n * Selector String, NodeList, p5.Element,\n * jQuery Element, or an Array of any of those.\n * @param {Function} [callback] Callback to invoke when the AudioContext has started\n * @return {Promise} Returns a Promise which is resolved when\n * the AudioContext state is 'running'\n * @method userStartAudio\n * @for p5\n * @example\n *
\n * function setup() {\n * var myDiv = createDiv('click to start audio');\n * myDiv.position(0, 0);\n *\n * var mySynth = new p5.MonoSynth();\n *\n * // This won't play until the context has started\n * mySynth.play('A6');\n *\n * // Start the audio context on a click/touch event\n * userStartAudio().then(function() {\n * myDiv.remove();\n * });\n * }\n *
\n */\n p5.prototype.userStartAudio = function(elements, callback) {\n var elt = elements;\n if (elements instanceof p5.Element) {\n elt = elements.elt;\n } else if (elements instanceof Array && elements[0] instanceof p5.Element ) {\n elt = elements.map(function(e) { return e.elt});\n }\n return StartAudioContext(audiocontext, elt, callback);\n };\n\n return audiocontext;\n});\n","define([\"Tone/core/Tone\"], function (Tone) {\n\n\t\"use strict\";\n\n\t/**\n\t * @class Tone.Emitter gives classes which extend it\n\t * the ability to listen for and emit events. \n\t * Inspiration and reference from Jerome Etienne's [MicroEvent](https://github.com/jeromeetienne/microevent.js).\n\t * MIT (c) 2011 Jerome Etienne.\n\t * \n\t * @extends {Tone}\n\t */\n\tTone.Emitter = function(){\n\t\t/**\n\t\t * Contains all of the events.\n\t\t * @private\n\t\t * @type {Object}\n\t\t */\n\t\tthis._events = {};\n\t};\n\n\tTone.extend(Tone.Emitter);\n\n\t/**\n\t * Bind a callback to a specific event.\n\t * @param {String} event The name of the event to listen for.\n\t * @param {Function} callback The callback to invoke when the\n\t * event is emitted\n\t * @return {Tone.Emitter} this\n\t */\n\tTone.Emitter.prototype.on = function(event, callback){\n\t\t//split the event\n\t\tvar events = event.split(/\\W+/);\n\t\tfor (var i = 0; i < events.length; i++){\n\t\t\tvar eventName = events[i];\n\t\t\tif (!this._events.hasOwnProperty(eventName)){\n\t\t\t\tthis._events[eventName] = [];\n\t\t\t}\n\t\t\tthis._events[eventName].push(callback);\n\t\t}\n\t\treturn this;\n\t};\n\n\t/**\n\t * Remove the event listener.\n\t * @param {String} event The event to stop listening to.\n\t * @param {Function=} callback The callback which was bound to \n\t * the event with Tone.Emitter.on.\n\t * If no callback is given, all callbacks\n\t * events are removed.\n\t * @return {Tone.Emitter} this\n\t */\n\tTone.Emitter.prototype.off = function(event, callback){\n\t\tvar events = event.split(/\\W+/);\n\t\tfor (var ev = 0; ev < events.length; ev++){\n\t\t\tevent = events[ev];\n\t\t\tif (this._events.hasOwnProperty(event)){\n\t\t\t\tif (Tone.prototype.isUndef(callback)){\n\t\t\t\t\tthis._events[event] = [];\n\t\t\t\t} else {\n\t\t\t\t\tvar eventList = this._events[event];\n\t\t\t\t\tfor (var i = 0; i < eventList.length; i++){\n\t\t\t\t\t\tif (eventList[i] === callback){\n\t\t\t\t\t\t\teventList.splice(i, 1);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\treturn this;\n\t};\n\n\t/**\n\t * Invoke all of the callbacks bound to the event\n\t * with any arguments passed in. \n\t * @param {String} event The name of the event.\n\t * @param {*...} args The arguments to pass to the functions listening.\n\t * @return {Tone.Emitter} this\n\t */\n\tTone.Emitter.prototype.emit = function(event){\n\t\tif (this._events){\n\t\t\tvar args = Array.apply(null, arguments).slice(1);\n\t\t\tif (this._events.hasOwnProperty(event)){\n\t\t\t\tvar eventList = this._events[event];\n\t\t\t\tfor (var i = 0, len = eventList.length; i < len; i++){\n\t\t\t\t\teventList[i].apply(this, args);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\treturn this;\n\t};\n\n\t/**\n\t * Add Emitter functions (on/off/emit) to the object\n\t * @param {Object|Function} object The object or class to extend.\n\t */\n\tTone.Emitter.mixin = function(object){\n\t\tvar functions = [\"on\", \"off\", \"emit\"];\n\t\tobject._events = {};\n\t\tfor (var i = 0; i < functions.length; i++){\n\t\t\tvar func = functions[i];\n\t\t\tvar emitterFunc = Tone.Emitter.prototype[func];\n\t\t\tobject[func] = emitterFunc;\n\t\t}\n\t};\n\n\t/**\n\t * Clean up\n\t * @return {Tone.Emitter} this\n\t */\n\tTone.Emitter.prototype.dispose = function(){\n\t\tTone.prototype.dispose.call(this);\n\t\tthis._events = null;\n\t\treturn this;\n\t};\n\n\treturn Tone.Emitter;\n});","define([\"Tone/core/Tone\"], function(Tone){\n\n\t\"use strict\";\n\n\t/**\n\t * @class Base class for all Signals. Used Internally. \n\t *\n\t * @constructor\n\t * @extends {Tone}\n\t */\n\tTone.SignalBase = function(){};\n\n\tTone.extend(Tone.SignalBase);\n\n\t/**\n\t * When signals connect to other signals or AudioParams, \n\t * they take over the output value of that signal or AudioParam. \n\t * For all other nodes, the behavior is the same as a default connect. \n\t *\n\t * @override\n\t * @param {AudioParam|AudioNode|Tone.Signal|Tone} node \n\t * @param {number} [outputNumber=0] The output number to connect from.\n\t * @param {number} [inputNumber=0] The input number to connect to.\n\t * @returns {Tone.SignalBase} this\n\t */\n\tTone.SignalBase.prototype.connect = function(node, outputNumber, inputNumber){\n\t\t//zero it out so that the signal can have full control\n\t\tif ((Tone.Signal && Tone.Signal === node.constructor) || \n\t\t\t\t(Tone.Param && Tone.Param === node.constructor) || \n\t\t\t\t(Tone.TimelineSignal && Tone.TimelineSignal === node.constructor)){\n\t\t\t//cancel changes\n\t\t\tnode._param.cancelScheduledValues(0);\n\t\t\t//reset the value\n\t\t\tnode._param.value = 0;\n\t\t\t//mark the value as overridden\n\t\t\tnode.overridden = true;\n\t\t} else if (node instanceof AudioParam){\n\t\t\tnode.cancelScheduledValues(0);\n\t\t\tnode.value = 0;\n\t\t} \n\t\tTone.prototype.connect.call(this, node, outputNumber, inputNumber);\n\t\treturn this;\n\t};\n\n\treturn Tone.SignalBase;\n});","define([\"Tone/core/Tone\", \"Tone/type/TimeBase\"], function (Tone) {\n\n\t/**\n\t * @class Tone.Time is a primitive type for encoding Time values. \n\t * Eventually all time values are evaluated to seconds\n\t * using the `eval` method. Tone.Time can be constructed\n\t * with or without the `new` keyword. Tone.Time can be passed\n\t * into the parameter of any method which takes time as an argument. \n\t * @constructor\n\t * @extends {Tone.TimeBase}\n\t * @param {String|Number} val The time value.\n\t * @param {String=} units The units of the value.\n\t * @example\n\t * var t = Tone.Time(\"4n\");//encodes a quarter note\n\t * t.mult(4); // multiply that value by 4\n\t * t.toNotation(); //returns \"1m\"\n\t */\n\tTone.Time = function(val, units){\n\t\tif (this instanceof Tone.Time){\n\n\t\t\t/**\n\t\t\t * If the current clock time should\n\t\t\t * be added to the output\n\t\t\t * @type {Boolean}\n\t\t\t * @private\n\t\t\t */\n\t\t\tthis._plusNow = false;\n\t\t\t\n\t\t\tTone.TimeBase.call(this, val, units);\n\n\t\t} else {\n\t\t\treturn new Tone.Time(val, units);\n\t\t}\n\t};\n\n\tTone.extend(Tone.Time, Tone.TimeBase);\n\n\t//clone the expressions so that \n\t//we can add more without modifying the original\n\tTone.Time.prototype._unaryExpressions = Object.create(Tone.TimeBase.prototype._unaryExpressions);\n\n\t/*\n\t * Adds an additional unary expression\n\t * which quantizes values to the next subdivision\n\t * @type {Object}\n\t * @private\n\t */\n\tTone.Time.prototype._unaryExpressions.quantize = {\n\t\tregexp : /^@/,\n\t\tmethod : function(rh){\n\t\t\treturn Tone.Transport.nextSubdivision(rh());\n\t\t}\n\t};\n\n\t/*\n\t * Adds an additional unary expression\n\t * which adds the current clock time.\n\t * @type {Object}\n\t * @private\n\t */\n\tTone.Time.prototype._unaryExpressions.now = {\n\t\tregexp : /^\\+/,\n\t\tmethod : function(lh){\n\t\t\tthis._plusNow = true;\n\t\t\treturn lh();\n\t\t}\n\t};\n\n\t/**\n\t * Quantize the time by the given subdivision. Optionally add a\n\t * percentage which will move the time value towards the ideal\n\t * quantized value by that percentage. \n\t * @param {Number|Time} val The subdivision to quantize to\n\t * @param {NormalRange} [percent=1] Move the time value\n\t * towards the quantized value by\n\t * a percentage.\n\t * @return {Tone.Time} this\n\t * @example\n\t * Tone.Time(21).quantize(2) //returns 22\n\t * Tone.Time(0.6).quantize(\"4n\", 0.5) //returns 0.55\n\t */\n\tTone.Time.prototype.quantize = function(subdiv, percent){\n\t\tpercent = this.defaultArg(percent, 1);\n\t\tthis._expr = function(expr, subdivision, percent){\n\t\t\texpr = expr();\n\t\t\tsubdivision = subdivision.toSeconds();\n\t\t\tvar multiple = Math.round(expr / subdivision);\n\t\t\tvar ideal = multiple * subdivision;\n\t\t\tvar diff = ideal - expr;\n\t\t\treturn expr + diff * percent;\n\t\t}.bind(this, this._expr, new this.constructor(subdiv), percent);\n\t\treturn this;\n\t};\n\n\t/**\n\t * Adds the clock time to the time expression at the \n\t * moment of evaluation. \n\t * @return {Tone.Time} this\n\t */\n\tTone.Time.prototype.addNow = function(){\n\t\tthis._plusNow = true;\n\t\treturn this;\n\t};\n\n\t/**\n\t * @override\n\t * Override the default value return when no arguments are passed in.\n\t * The default value is 'now'\n\t * @private\n\t */\n\tTone.Time.prototype._defaultExpr = function(){\n\t\tthis._plusNow = true;\n\t\treturn this._noOp;\n\t};\n\n\t/**\n\t * Copies the value of time to this Time\n\t * @param {Tone.Time} time\n\t * @return {Time}\n\t */\n\tTone.Time.prototype.copy = function(time){\n\t\tTone.TimeBase.prototype.copy.call(this, time);\n\t\tthis._plusNow = time._plusNow;\n\t\treturn this;\n\t};\n\n\t//CONVERSIONS//////////////////////////////////////////////////////////////\n\n\t/**\n\t * Convert a Time to Notation. Values will be thresholded to the nearest 128th note. \n\t * @return {Notation} \n\t * @example\n\t * //if the Transport is at 120bpm:\n\t * Tone.Time(2).toNotation();//returns \"1m\"\n\t */\n\tTone.Time.prototype.toNotation = function(){\n\t\tvar time = this.toSeconds();\n\t\tvar testNotations = [\"1m\", \"2n\", \"4n\", \"8n\", \"16n\", \"32n\", \"64n\", \"128n\"];\n\t\tvar retNotation = this._toNotationHelper(time, testNotations);\n\t\t//try the same thing but with tripelets\n\t\tvar testTripletNotations = [\"1m\", \"2n\", \"2t\", \"4n\", \"4t\", \"8n\", \"8t\", \"16n\", \"16t\", \"32n\", \"32t\", \"64n\", \"64t\", \"128n\"];\n\t\tvar retTripletNotation = this._toNotationHelper(time, testTripletNotations);\n\t\t//choose the simpler expression of the two\n\t\tif (retTripletNotation.split(\"+\").length < retNotation.split(\"+\").length){\n\t\t\treturn retTripletNotation;\n\t\t} else {\n\t\t\treturn retNotation;\n\t\t}\n\t};\n\n\t/**\n\t * Helper method for Tone.toNotation\n\t * @param {Number} units \n\t * @param {Array} testNotations\n\t * @return {String}\n\t * @private\n\t */\n\tTone.Time.prototype._toNotationHelper = function(units, testNotations){\n\t\t//the threshold is the last value in the array\n\t\tvar threshold = this._notationToUnits(testNotations[testNotations.length - 1]);\n\t\tvar retNotation = \"\";\n\t\tfor (var i = 0; i < testNotations.length; i++){\n\t\t\tvar notationTime = this._notationToUnits(testNotations[i]);\n\t\t\t//account for floating point errors (i.e. round up if the value is 0.999999)\n\t\t\tvar multiple = units / notationTime;\n\t\t\tvar floatingPointError = 0.000001;\n\t\t\tif (1 - multiple % 1 < floatingPointError){\n\t\t\t\tmultiple += floatingPointError;\n\t\t\t}\n\t\t\tmultiple = Math.floor(multiple);\n\t\t\tif (multiple > 0){\n\t\t\t\tif (multiple === 1){\n\t\t\t\t\tretNotation += testNotations[i];\n\t\t\t\t} else {\n\t\t\t\t\tretNotation += multiple.toString() + \"*\" + testNotations[i];\n\t\t\t\t}\n\t\t\t\tunits -= multiple * notationTime;\n\t\t\t\tif (units < threshold){\n\t\t\t\t\tbreak;\n\t\t\t\t} else {\n\t\t\t\t\tretNotation += \" + \";\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tif (retNotation === \"\"){\n\t\t\tretNotation = \"0\";\n\t\t}\n\t\treturn retNotation;\n\t};\n\n\t/**\n\t * Convert a notation value to the current units\n\t * @param {Notation} notation \n\t * @return {Number} \n\t * @private\n\t */\n\tTone.Time.prototype._notationToUnits = function(notation){\n\t\tvar primaryExprs = this._primaryExpressions;\n\t\tvar notationExprs = [primaryExprs.n, primaryExprs.t, primaryExprs.m];\n\t\tfor (var i = 0; i < notationExprs.length; i++){\n\t\t\tvar expr = notationExprs[i];\n\t\t\tvar match = notation.match(expr.regexp);\n\t\t\tif (match){\n\t\t\t\treturn expr.method.call(this, match[1]);\n\t\t\t}\n\t\t}\n\t};\n\n\t/**\n\t * Return the time encoded as Bars:Beats:Sixteenths.\n\t * @return {BarsBeatsSixteenths}\n\t */\n\tTone.Time.prototype.toBarsBeatsSixteenths = function(){\n\t\tvar quarterTime = this._beatsToUnits(1);\n\t\tvar quarters = this.toSeconds() / quarterTime;\n\t\tvar measures = Math.floor(quarters / this._timeSignature());\n\t\tvar sixteenths = (quarters % 1) * 4;\n\t\tquarters = Math.floor(quarters) % this._timeSignature();\n\t\tsixteenths = sixteenths.toString();\n\t\tif (sixteenths.length > 3){\n\t\t\tsixteenths = parseFloat(sixteenths).toFixed(3);\n\t\t}\n\t\tvar progress = [measures, quarters, sixteenths];\n\t\treturn progress.join(\":\");\n\t};\n\n\t/**\n\t * Return the time in ticks.\n\t * @return {Ticks}\n\t */\n\tTone.Time.prototype.toTicks = function(){\n\t\tvar quarterTime = this._beatsToUnits(1);\n\t\tvar quarters = this.valueOf() / quarterTime;\n\t\treturn Math.floor(quarters * Tone.Transport.PPQ);\n\t};\n\n\t/**\n\t * Return the time in samples\n\t * @return {Samples} \n\t */\n\tTone.Time.prototype.toSamples = function(){\n\t\treturn this.toSeconds() * this.context.sampleRate;\n\t};\n\n\t/**\n\t * Return the time as a frequency value\n\t * @return {Frequency} \n\t * @example\n\t * Tone.Time(2).toFrequency(); //0.5\n\t */\n\tTone.Time.prototype.toFrequency = function(){\n\t\treturn 1/this.toSeconds();\n\t};\n\n\t/**\n\t * Return the time in seconds.\n\t * @return {Seconds} \n\t */\n\tTone.Time.prototype.toSeconds = function(){\n\t\treturn this.valueOf();\n\t};\n\n\t/**\n\t * Return the time in milliseconds.\n\t * @return {Milliseconds} \n\t */\n\tTone.Time.prototype.toMilliseconds = function(){\n\t\treturn this.toSeconds() * 1000;\n\t};\n\n\t/**\n\t * Return the time in seconds.\n\t * @return {Seconds} \n\t */\n\tTone.Time.prototype.valueOf = function(){\n\t\tvar val = this._expr();\n\t\treturn val + (this._plusNow?this.now():0);\n\t};\n\n\treturn Tone.Time;\n});","define([\"Tone/core/Tone\"], function (Tone) {\n\n\t/**\n\t * @class Tone.TimeBase is a flexible encoding of time\n\t * which can be evaluated to and from a string.\n\t * Parsing code modified from https://code.google.com/p/tapdigit/\n\t * Copyright 2011 2012 Ariya Hidayat, New BSD License\n\t * @extends {Tone}\n\t * @param {Time} val The time value as a number or string\n\t * @param {String=} units Unit values\n\t * @example\n\t * Tone.TimeBase(4, \"n\")\n\t * Tone.TimeBase(2, \"t\")\n\t * Tone.TimeBase(\"2t\").add(\"1m\")\n\t * Tone.TimeBase(\"2t + 1m\");\n\t */\n\tTone.TimeBase = function(val, units){\n\n\t\t//allows it to be constructed with or without 'new'\n\t\tif (this instanceof Tone.TimeBase) {\n\n\t\t\t/**\n\t\t\t * Any expressions parsed from the Time\n\t\t\t * @type {Array}\n\t\t\t * @private\n\t\t\t */\n\t\t\tthis._expr = this._noOp;\n\n\t\t\tif (val instanceof Tone.TimeBase){\n\t\t\t\tthis.copy(val);\n\t\t\t} else if (!this.isUndef(units) || this.isNumber(val)){\n\t\t\t\t//default units\n\t\t\t\tunits = this.defaultArg(units, this._defaultUnits);\n\t\t\t\tvar method = this._primaryExpressions[units].method;\n\t\t\t\tthis._expr = method.bind(this, val);\n\t\t\t} else if (this.isString(val)){\n\t\t\t\tthis.set(val);\n\t\t\t} else if (this.isUndef(val)){\n\t\t\t\t//default expression\n\t\t\t\tthis._expr = this._defaultExpr();\n\t\t\t}\n\t\t} else {\n\n\t\t\treturn new Tone.TimeBase(val, units);\n\t\t}\n\t};\n\n\tTone.extend(Tone.TimeBase);\n\n\t/**\n\t * Repalce the current time value with the value\n\t * given by the expression string.\n\t * @param {String} exprString\n\t * @return {Tone.TimeBase} this\n\t */\n\tTone.TimeBase.prototype.set = function(exprString){\n\t\tthis._expr = this._parseExprString(exprString);\n\t\treturn this;\n\t};\n\n\t/**\n\t * Return a clone of the TimeBase object.\n\t * @return {Tone.TimeBase} The new cloned Tone.TimeBase\n\t */\n\tTone.TimeBase.prototype.clone = function(){\n\t\tvar instance = new this.constructor();\n\t\tinstance.copy(this);\n\t\treturn instance;\n\t};\n\n\t/**\n\t * Copies the value of time to this Time\n\t * @param {Tone.TimeBase} time\n\t * @return {TimeBase}\n\t */\n\tTone.TimeBase.prototype.copy = function(time){\n\t\tvar val = time._expr();\n\t\treturn this.set(val);\n\t};\n\n\t///////////////////////////////////////////////////////////////////////////\n\t//\tABSTRACT SYNTAX TREE PARSER\n\t///////////////////////////////////////////////////////////////////////////\n\n\t/**\n\t * All the primary expressions.\n\t * @private\n\t * @type {Object}\n\t */\n\tTone.TimeBase.prototype._primaryExpressions = {\n\t\t\"n\" : {\n\t\t\tregexp : /^(\\d+)n/i,\n\t\t\tmethod : function(value){\n\t\t\t\tvalue = parseInt(value);\n\t\t\t\tif (value === 1){\n\t\t\t\t\treturn this._beatsToUnits(this._timeSignature());\n\t\t\t\t} else {\n\t\t\t\t\treturn this._beatsToUnits(4 / value);\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\t\t\"t\" : {\n\t\t\tregexp : /^(\\d+)t/i,\n\t\t\tmethod : function(value){\n\t\t\t\tvalue = parseInt(value);\n\t\t\t\treturn this._beatsToUnits(8 / (parseInt(value) * 3));\n\t\t\t}\n\t\t},\n\t\t\"m\" : {\n\t\t\tregexp : /^(\\d+)m/i,\n\t\t\tmethod : function(value){\n\t\t\t\treturn this._beatsToUnits(parseInt(value) * this._timeSignature());\n\t\t\t}\n\t\t},\n\t\t\"i\" : {\n\t\t\tregexp : /^(\\d+)i/i,\n\t\t\tmethod : function(value){\n\t\t\t\treturn this._ticksToUnits(parseInt(value));\n\t\t\t}\n\t\t},\n\t\t\"hz\" : {\n\t\t\tregexp : /^(\\d+(?:\\.\\d+)?)hz/i,\n\t\t\tmethod : function(value){\n\t\t\t\treturn this._frequencyToUnits(parseFloat(value));\n\t\t\t}\n\t\t},\n\t\t\"tr\" : {\n\t\t\tregexp : /^(\\d+(?:\\.\\d+)?):(\\d+(?:\\.\\d+)?):?(\\d+(?:\\.\\d+)?)?/,\n\t\t\tmethod : function(m, q, s){\n\t\t\t\tvar total = 0;\n\t\t\t\tif (m && m !== \"0\"){\n\t\t\t\t\ttotal += this._beatsToUnits(this._timeSignature() * parseFloat(m));\n\t\t\t\t}\n\t\t\t\tif (q && q !== \"0\"){\n\t\t\t\t\ttotal += this._beatsToUnits(parseFloat(q));\n\t\t\t\t}\n\t\t\t\tif (s && s !== \"0\"){\n\t\t\t\t\ttotal += this._beatsToUnits(parseFloat(s) / 4);\n\t\t\t\t}\n\t\t\t\treturn total;\n\t\t\t}\n\t\t},\n\t\t\"s\" : {\n\t\t\tregexp : /^(\\d+(?:\\.\\d+)?s)/,\n\t\t\tmethod : function(value){\n\t\t\t\treturn this._secondsToUnits(parseFloat(value));\n\t\t\t}\n\t\t},\n\t\t\"samples\" : {\n\t\t\tregexp : /^(\\d+)samples/,\n\t\t\tmethod : function(value){\n\t\t\t\treturn parseInt(value) / this.context.sampleRate;\n\t\t\t}\n\t\t},\n\t\t\"default\" : {\n\t\t\tregexp : /^(\\d+(?:\\.\\d+)?)/,\n\t\t\tmethod : function(value){\n\t\t\t\treturn this._primaryExpressions[this._defaultUnits].method.call(this, value);\n\t\t\t}\n\t\t}\n\t};\n\n\t/**\n\t * All the binary expressions that TimeBase can accept.\n\t * @private\n\t * @type {Object}\n\t */\n\tTone.TimeBase.prototype._binaryExpressions = {\n\t\t\"+\" : {\n\t\t\tregexp : /^\\+/,\n\t\t\tprecedence : 2,\n\t\t\tmethod : function(lh, rh){\n\t\t\t\treturn lh() + rh();\n\t\t\t}\n\t\t},\n\t\t\"-\" : {\n\t\t\tregexp : /^\\-/,\n\t\t\tprecedence : 2,\n\t\t\tmethod : function(lh, rh){\n\t\t\t\treturn lh() - rh();\n\t\t\t}\n\t\t},\n\t\t\"*\" : {\n\t\t\tregexp : /^\\*/,\n\t\t\tprecedence : 1,\n\t\t\tmethod : function(lh, rh){\n\t\t\t\treturn lh() * rh();\n\t\t\t}\n\t\t},\n\t\t\"/\" : {\n\t\t\tregexp : /^\\//,\n\t\t\tprecedence : 1,\n\t\t\tmethod : function(lh, rh){\n\t\t\t\treturn lh() / rh();\n\t\t\t}\n\t\t}\n\t};\n\n\t/**\n\t * All the unary expressions.\n\t * @private\n\t * @type {Object}\n\t */\n\tTone.TimeBase.prototype._unaryExpressions = {\n\t\t\"neg\" : {\n\t\t\tregexp : /^\\-/,\n\t\t\tmethod : function(lh){\n\t\t\t\treturn -lh();\n\t\t\t}\n\t\t}\n\t};\n\n\t/**\n\t * Syntactic glue which holds expressions together\n\t * @private\n\t * @type {Object}\n\t */\n\tTone.TimeBase.prototype._syntaxGlue = {\n\t\t\"(\" : {\n\t\t\tregexp : /^\\(/\n\t\t},\n\t\t\")\" : {\n\t\t\tregexp : /^\\)/\n\t\t}\n\t};\n\n\t/**\n\t * tokenize the expression based on the Expressions object\n\t * @param {string} expr \n\t * @return {Object} returns two methods on the tokenized list, next and peek\n\t * @private\n\t */\n\tTone.TimeBase.prototype._tokenize = function(expr){\n\t\tvar position = -1;\n\t\tvar tokens = [];\n\n\t\twhile(expr.length > 0){\n\t\t\texpr = expr.trim();\n\t\t\tvar token = getNextToken(expr, this);\n\t\t\ttokens.push(token);\n\t\t\texpr = expr.substr(token.value.length);\n\t\t}\n\n\t\tfunction getNextToken(expr, context){\n\t\t\tvar expressions = [\"_binaryExpressions\", \"_unaryExpressions\", \"_primaryExpressions\", \"_syntaxGlue\"];\n\t\t\tfor (var i = 0; i < expressions.length; i++){\n\t\t\t\tvar group = context[expressions[i]];\n\t\t\t\tfor (var opName in group){\n\t\t\t\t\tvar op = group[opName];\n\t\t\t\t\tvar reg = op.regexp;\n\t\t\t\t\tvar match = expr.match(reg);\n\t\t\t\t\tif (match !== null){\n\t\t\t\t\t\treturn {\n\t\t\t\t\t\t\tmethod : op.method,\n\t\t\t\t\t\t\tprecedence : op.precedence,\n\t\t\t\t\t\t\tregexp : op.regexp,\n\t\t\t\t\t\t\tvalue : match[0],\n\t\t\t\t\t\t};\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\tthrow new SyntaxError(\"Tone.TimeBase: Unexpected token \"+expr);\n\t\t}\n\n\t\treturn {\n\t\t\tnext : function(){\n\t\t\t\treturn tokens[++position];\n\t\t\t},\n\t\t\tpeek : function(){\n\t\t\t\treturn tokens[position + 1];\n\t\t\t}\n\t\t};\n\t};\n\n\t/**\n\t * Given a token, find the value within the groupName\n\t * @param {Object} token\n\t * @param {String} groupName\n\t * @param {Number} precedence\n\t * @private\n\t */\n\tTone.TimeBase.prototype._matchGroup = function(token, group, prec) {\n\t\tvar ret = false;\n\t\tif (!this.isUndef(token)){\n\t\t\tfor (var opName in group){\n\t\t\t\tvar op = group[opName];\n\t\t\t\tif (op.regexp.test(token.value)){\n\t\t\t\t\tif (!this.isUndef(prec)){\n\t\t\t\t\t\tif(op.precedence === prec){\t\n\t\t\t\t\t\t\treturn op;\n\t\t\t\t\t\t}\n\t\t\t\t\t} else {\n\t\t\t\t\t\treturn op;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\treturn ret;\n\t};\n\n\t/**\n\t * Match a binary expression given the token and the precedence\n\t * @param {Lexer} lexer\n\t * @param {Number} precedence\n\t * @private\n\t */\n\tTone.TimeBase.prototype._parseBinary = function(lexer, precedence){\n\t\tif (this.isUndef(precedence)){\n\t\t\tprecedence = 2;\n\t\t}\n\t\tvar expr;\n\t\tif (precedence < 0){\n\t\t\texpr = this._parseUnary(lexer);\n\t\t} else {\n\t\t\texpr = this._parseBinary(lexer, precedence - 1);\n\t\t}\n\t\tvar token = lexer.peek();\n\t\twhile (token && this._matchGroup(token, this._binaryExpressions, precedence)){\n\t\t\ttoken = lexer.next();\n\t\t\texpr = token.method.bind(this, expr, this._parseBinary(lexer, precedence - 1));\n\t\t\ttoken = lexer.peek();\n\t\t}\n\t\treturn expr;\n\t};\n\n\t/**\n\t * Match a unary expression.\n\t * @param {Lexer} lexer\n\t * @private\n\t */\n\tTone.TimeBase.prototype._parseUnary = function(lexer){\n\t\tvar token, expr;\n\t\ttoken = lexer.peek();\n\t\tvar op = this._matchGroup(token, this._unaryExpressions);\n\t\tif (op) {\n\t\t\ttoken = lexer.next();\n\t\t\texpr = this._parseUnary(lexer);\n\t\t\treturn op.method.bind(this, expr);\n\t\t}\n\t\treturn this._parsePrimary(lexer);\n\t};\n\n\t/**\n\t * Match a primary expression (a value).\n\t * @param {Lexer} lexer\n\t * @private\n\t */\n\tTone.TimeBase.prototype._parsePrimary = function(lexer){\n\t\tvar token, expr;\n\t\ttoken = lexer.peek();\n\t\tif (this.isUndef(token)) {\n\t\t\tthrow new SyntaxError(\"Tone.TimeBase: Unexpected end of expression\");\n\t\t}\n\t\tif (this._matchGroup(token, this._primaryExpressions)) {\n\t\t\ttoken = lexer.next();\n\t\t\tvar matching = token.value.match(token.regexp);\n\t\t\treturn token.method.bind(this, matching[1], matching[2], matching[3]);\n\t\t}\n\t\tif (token && token.value === \"(\"){\n\t\t\tlexer.next();\n\t\t\texpr = this._parseBinary(lexer);\n\t\t\ttoken = lexer.next();\n\t\t\tif (!(token && token.value === \")\")) {\n\t\t\t\tthrow new SyntaxError(\"Expected )\");\n\t\t\t}\n\t\t\treturn expr;\n\t\t}\n\t\tthrow new SyntaxError(\"Tone.TimeBase: Cannot process token \" + token.value);\n\t};\n\n\t/**\n\t * Recursively parse the string expression into a syntax tree.\n\t * @param {string} expr \n\t * @return {Function} the bound method to be evaluated later\n\t * @private\n\t */\n\tTone.TimeBase.prototype._parseExprString = function(exprString){\n\t\tif (!this.isString(exprString)){\n\t\t\texprString = exprString.toString();\n\t\t}\n\t\tvar lexer = this._tokenize(exprString);\n\t\tvar tree = this._parseBinary(lexer);\n\t\treturn tree;\n\t};\n\n\t///////////////////////////////////////////////////////////////////////////\n\t//\tDEFAULTS\n\t///////////////////////////////////////////////////////////////////////////\n\n\t/**\n\t * The initial expression value\n\t * @return {Number} The initial value 0\n\t * @private\n\t */\n\tTone.TimeBase.prototype._noOp = function(){\n\t\treturn 0;\n\t};\n\n\t/**\n\t * The default expression value if no arguments are given\n\t * @private\n\t */\n\tTone.TimeBase.prototype._defaultExpr = function(){\n\t\treturn this._noOp;\n\t};\n\n\t/**\n\t * The default units if none are given.\n\t * @private\n\t */\n\tTone.TimeBase.prototype._defaultUnits = \"s\";\n\n\t///////////////////////////////////////////////////////////////////////////\n\t//\tUNIT CONVERSIONS\n\t///////////////////////////////////////////////////////////////////////////\n\n\t/**\n\t * Returns the value of a frequency in the current units\n\t * @param {Frequency} freq\n\t * @return {Number}\n\t * @private\n\t */\n\tTone.TimeBase.prototype._frequencyToUnits = function(freq){\n\t\treturn 1/freq;\n\t};\n\n\t/**\n\t * Return the value of the beats in the current units\n\t * @param {Number} beats\n\t * @return {Number}\n\t * @private\n\t */\n\tTone.TimeBase.prototype._beatsToUnits = function(beats){\n\t\treturn (60 / Tone.Transport.bpm.value) * beats;\n\t};\n\n\t/**\n\t * Returns the value of a second in the current units\n\t * @param {Seconds} seconds\n\t * @return {Number}\n\t * @private\n\t */\n\tTone.TimeBase.prototype._secondsToUnits = function(seconds){\n\t\treturn seconds;\n\t};\n\n\t/**\n\t * Returns the value of a tick in the current time units\n\t * @param {Ticks} ticks\n\t * @return {Number}\n\t * @private\n\t */\n\tTone.TimeBase.prototype._ticksToUnits = function(ticks){\n\t\treturn ticks * (this._beatsToUnits(1) / Tone.Transport.PPQ);\n\t};\n\n\t/**\n\t * Return the time signature.\n\t * @return {Number}\n\t * @private\n\t */\n\tTone.TimeBase.prototype._timeSignature = function(){\n\t\treturn Tone.Transport.timeSignature;\n\t};\n\n\t///////////////////////////////////////////////////////////////////////////\n\t//\tEXPRESSIONS\n\t///////////////////////////////////////////////////////////////////////////\n\n\t/**\n\t * Push an expression onto the expression list\n\t * @param {Time} val\n\t * @param {String} type\n\t * @param {String} units\n\t * @return {Tone.TimeBase} \n\t * @private\n\t */\n\tTone.TimeBase.prototype._pushExpr = function(val, name, units){\n\t\t//create the expression\n\t\tif (!(val instanceof Tone.TimeBase)){\n\t\t\tval = new this.constructor(val, units);\n\t\t}\n\t\tthis._expr = this._binaryExpressions[name].method.bind(this, this._expr, val._expr);\n\t\treturn this;\n\t};\n\n\t/**\n\t * Add to the current value.\n\t * @param {Time} val The value to add\n\t * @param {String=} units Optional units to use with the value.\n\t * @return {Tone.TimeBase} this\n\t * @example\n\t * Tone.TimeBase(\"2m\").add(\"1m\"); //\"3m\"\n\t */\n\tTone.TimeBase.prototype.add = function(val, units){\n\t\treturn this._pushExpr(val, \"+\", units);\n\t};\n\n\t/**\n\t * Subtract the value from the current time.\n\t * @param {Time} val The value to subtract\n\t * @param {String=} units Optional units to use with the value.\n\t * @return {Tone.TimeBase} this\n\t * @example\n\t * Tone.TimeBase(\"2m\").sub(\"1m\"); //\"1m\"\n\t */\n\tTone.TimeBase.prototype.sub = function(val, units){\n\t\treturn this._pushExpr(val, \"-\", units);\n\t};\n\n\t/**\n\t * Multiply the current value by the given time.\n\t * @param {Time} val The value to multiply\n\t * @param {String=} units Optional units to use with the value.\n\t * @return {Tone.TimeBase} this\n\t * @example\n\t * Tone.TimeBase(\"2m\").mult(\"2\"); //\"4m\"\n\t */\n\tTone.TimeBase.prototype.mult = function(val, units){\n\t\treturn this._pushExpr(val, \"*\", units);\n\t};\n\n\t/**\n\t * Divide the current value by the given time.\n\t * @param {Time} val The value to divide by\n\t * @param {String=} units Optional units to use with the value.\n\t * @return {Tone.TimeBase} this\n\t * @example\n\t * Tone.TimeBase(\"2m\").div(2); //\"1m\"\n\t */\n\tTone.TimeBase.prototype.div = function(val, units){\n\t\treturn this._pushExpr(val, \"/\", units);\n\t};\n\n\t/**\n\t * Evaluate the time value. Returns the time\n\t * in seconds.\n\t * @return {Seconds} \n\t */\n\tTone.TimeBase.prototype.valueOf = function(){\n\t\treturn this._expr();\n\t};\n\n\t/**\n\t * Clean up\n\t * @return {Tone.TimeBase} this\n\t */\n\tTone.TimeBase.prototype.dispose = function(){\n\t\tthis._expr = null;\n\t};\n\n\treturn Tone.TimeBase;\n});","define([\"Tone/core/Tone\", \"Tone/type/Type\"], function(Tone){\n\n\t\"use strict\";\n\n\t/**\n\t * @class Tone.Param wraps the native Web Audio's AudioParam to provide\n\t * additional unit conversion functionality. It also\n\t * serves as a base-class for classes which have a single,\n\t * automatable parameter. \n\t * @extends {Tone}\n\t * @param {AudioParam} param The parameter to wrap.\n\t * @param {Tone.Type} units The units of the audio param.\n\t * @param {Boolean} convert If the param should be converted.\n\t */\n\tTone.Param = function(){\n\n\t\tvar options = this.optionsObject(arguments, [\"param\", \"units\", \"convert\"], Tone.Param.defaults);\n\n\t\t/**\n\t\t * The native parameter to control\n\t\t * @type {AudioParam}\n\t\t * @private\n\t\t */\n\t\tthis._param = this.input = options.param;\n\n\t\t/**\n\t\t * The units of the parameter\n\t\t * @type {Tone.Type}\n\t\t */\n\t\tthis.units = options.units;\n\n\t\t/**\n\t\t * If the value should be converted or not\n\t\t * @type {Boolean}\n\t\t */\n\t\tthis.convert = options.convert;\n\n\t\t/**\n\t\t * True if the signal value is being overridden by \n\t\t * a connected signal.\n\t\t * @readOnly\n\t\t * @type {boolean}\n\t\t * @private\n\t\t */\n\t\tthis.overridden = false;\n\n\t\t/**\n\t\t * If there is an LFO, this is where it is held.\n\t\t * @type {Tone.LFO}\n\t\t * @private\n\t\t */\n\t\tthis._lfo = null;\n\n\t\tif (this.isObject(options.lfo)){\n\t\t\tthis.value = options.lfo;\n\t\t} else if (!this.isUndef(options.value)){\n\t\t\tthis.value = options.value;\n\t\t}\n\t};\n\n\tTone.extend(Tone.Param);\n\t\n\t/**\n\t * Defaults\n\t * @type {Object}\n\t * @const\n\t */\n\tTone.Param.defaults = {\n\t\t\"units\" : Tone.Type.Default,\n\t\t\"convert\" : true,\n\t\t\"param\" : undefined\n\t};\n\n\t/**\n\t * The current value of the parameter. \n\t * @memberOf Tone.Param#\n\t * @type {Number}\n\t * @name value\n\t */\n\tObject.defineProperty(Tone.Param.prototype, \"value\", {\n\t\tget : function(){\n\t\t\treturn this._toUnits(this._param.value);\n\t\t},\n\t\tset : function(value){\n\t\t\tif (this.isObject(value)){\n\t\t\t\t//throw an error if the LFO needs to be included\n\t\t\t\tif (this.isUndef(Tone.LFO)){\n\t\t\t\t\tthrow new Error(\"Include 'Tone.LFO' to use an LFO as a Param value.\");\n\t\t\t\t}\n\t\t\t\t//remove the old one\n\t\t\t\tif (this._lfo){\n\t\t\t\t\tthis._lfo.dispose();\n\t\t\t\t}\n\t\t\t\tthis._lfo = new Tone.LFO(value).start();\n\t\t\t\tthis._lfo.connect(this.input);\n\t\t\t} else {\n\t\t\t\tvar convertedVal = this._fromUnits(value);\n\t\t\t\tthis._param.cancelScheduledValues(0);\n\t\t\t\tthis._param.value = convertedVal;\n\t\t\t}\n\t\t}\n\t});\n\n\t/**\n\t * Convert the given value from the type specified by Tone.Param.units\n\t * into the destination value (such as Gain or Frequency).\n\t * @private\n\t * @param {*} val the value to convert\n\t * @return {number} the number which the value should be set to\n\t */\n\tTone.Param.prototype._fromUnits = function(val){\n\t\tif (this.convert || this.isUndef(this.convert)){\n\t\t\tswitch(this.units){\n\t\t\t\tcase Tone.Type.Time: \n\t\t\t\t\treturn this.toSeconds(val);\n\t\t\t\tcase Tone.Type.Frequency: \n\t\t\t\t\treturn this.toFrequency(val);\n\t\t\t\tcase Tone.Type.Decibels: \n\t\t\t\t\treturn this.dbToGain(val);\n\t\t\t\tcase Tone.Type.NormalRange: \n\t\t\t\t\treturn Math.min(Math.max(val, 0), 1);\n\t\t\t\tcase Tone.Type.AudioRange: \n\t\t\t\t\treturn Math.min(Math.max(val, -1), 1);\n\t\t\t\tcase Tone.Type.Positive: \n\t\t\t\t\treturn Math.max(val, 0);\n\t\t\t\tdefault:\n\t\t\t\t\treturn val;\n\t\t\t}\n\t\t} else {\n\t\t\treturn val;\n\t\t}\n\t};\n\n\t/**\n\t * Convert the parameters value into the units specified by Tone.Param.units.\n\t * @private\n\t * @param {number} val the value to convert\n\t * @return {number}\n\t */\n\tTone.Param.prototype._toUnits = function(val){\n\t\tif (this.convert || this.isUndef(this.convert)){\n\t\t\tswitch(this.units){\n\t\t\t\tcase Tone.Type.Decibels: \n\t\t\t\t\treturn this.gainToDb(val);\n\t\t\t\tdefault:\n\t\t\t\t\treturn val;\n\t\t\t}\n\t\t} else {\n\t\t\treturn val;\n\t\t}\n\t};\n\n\t/**\n\t * the minimum output value\n\t * @type {Number}\n\t * @private\n\t */\n\tTone.Param.prototype._minOutput = 0.00001;\n\n\t/**\n\t * Schedules a parameter value change at the given time.\n\t * @param {*}\tvalue The value to set the signal.\n\t * @param {Time} time The time when the change should occur.\n\t * @returns {Tone.Param} this\n\t * @example\n\t * //set the frequency to \"G4\" in exactly 1 second from now. \n\t * freq.setValueAtTime(\"G4\", \"+1\");\n\t */\n\tTone.Param.prototype.setValueAtTime = function(value, time){\n\t\tvalue = this._fromUnits(value);\n\t\ttime = this.toSeconds(time);\n\t\tif (time <= this.now() + this.blockTime){\n\t\t\tthis._param.value = value;\n\t\t} else {\n\t\t\tthis._param.setValueAtTime(value, time);\n\t\t}\n\t\treturn this;\n\t};\n\n\t/**\n\t * Creates a schedule point with the current value at the current time.\n\t * This is useful for creating an automation anchor point in order to \n\t * schedule changes from the current value. \n\t *\n\t * @param {number=} now (Optionally) pass the now value in. \n\t * @returns {Tone.Param} this\n\t */\n\tTone.Param.prototype.setRampPoint = function(now){\n\t\tnow = this.defaultArg(now, this.now());\n\t\tvar currentVal = this._param.value;\n\t\t// exponentialRampToValueAt cannot ever ramp from or to 0\n\t\t// More info: https://bugzilla.mozilla.org/show_bug.cgi?id=1125600#c2\n\t\tif (currentVal === 0){\n\t\t\tcurrentVal = this._minOutput;\n\t\t}\n\t\tthis._param.setValueAtTime(currentVal, now);\n\t\treturn this;\n\t};\n\n\t/**\n\t * Schedules a linear continuous change in parameter value from the \n\t * previous scheduled parameter value to the given value.\n\t * \n\t * @param {number} value \n\t * @param {Time} endTime \n\t * @returns {Tone.Param} this\n\t */\n\tTone.Param.prototype.linearRampToValueAtTime = function(value, endTime){\n\t\tvalue = this._fromUnits(value);\n\t\tthis._param.linearRampToValueAtTime(value, this.toSeconds(endTime));\n\t\treturn this;\n\t};\n\n\t/**\n\t * Schedules an exponential continuous change in parameter value from \n\t * the previous scheduled parameter value to the given value.\n\t * \n\t * @param {number} value \n\t * @param {Time} endTime \n\t * @returns {Tone.Param} this\n\t */\n\tTone.Param.prototype.exponentialRampToValueAtTime = function(value, endTime){\n\t\tvalue = this._fromUnits(value);\n\t\tvalue = Math.max(this._minOutput, value);\n\t\tthis._param.exponentialRampToValueAtTime(value, this.toSeconds(endTime));\n\t\treturn this;\n\t};\n\n\t/**\n\t * Schedules an exponential continuous change in parameter value from \n\t * the current time and current value to the given value over the \n\t * duration of the rampTime.\n\t * \n\t * @param {number} value The value to ramp to.\n\t * @param {Time} rampTime the time that it takes the \n\t * value to ramp from it's current value\n\t * @param {Time}\t[startTime=now] \tWhen the ramp should start. \n\t * @returns {Tone.Param} this\n\t * @example\n\t * //exponentially ramp to the value 2 over 4 seconds. \n\t * signal.exponentialRampToValue(2, 4);\n\t */\n\tTone.Param.prototype.exponentialRampToValue = function(value, rampTime, startTime){\n\t\tstartTime = this.toSeconds(startTime);\n\t\tthis.setRampPoint(startTime);\n\t\tthis.exponentialRampToValueAtTime(value, startTime + this.toSeconds(rampTime));\n\t\treturn this;\n\t};\n\n\t/**\n\t * Schedules an linear continuous change in parameter value from \n\t * the current time and current value to the given value over the \n\t * duration of the rampTime.\n\t * \n\t * @param {number} value The value to ramp to.\n\t * @param {Time} rampTime the time that it takes the \n\t * value to ramp from it's current value\n\t * @param {Time}\t[startTime=now] \tWhen the ramp should start. \n\t * @returns {Tone.Param} this\n\t * @example\n\t * //linearly ramp to the value 4 over 3 seconds. \n\t * signal.linearRampToValue(4, 3);\n\t */\n\tTone.Param.prototype.linearRampToValue = function(value, rampTime, startTime){\n\t\tstartTime = this.toSeconds(startTime);\n\t\tthis.setRampPoint(startTime);\n\t\tthis.linearRampToValueAtTime(value, startTime + this.toSeconds(rampTime));\n\t\treturn this;\n\t};\n\n\t/**\n\t * Start exponentially approaching the target value at the given time with\n\t * a rate having the given time constant.\n\t * @param {number} value \n\t * @param {Time} startTime \n\t * @param {number} timeConstant \n\t * @returns {Tone.Param} this \n\t */\n\tTone.Param.prototype.setTargetAtTime = function(value, startTime, timeConstant){\n\t\tvalue = this._fromUnits(value);\n\t\t// The value will never be able to approach without timeConstant > 0.\n\t\t// http://www.w3.org/TR/webaudio/#dfn-setTargetAtTime, where the equation\n\t\t// is described. 0 results in a division by 0.\n\t\tvalue = Math.max(this._minOutput, value);\n\t\ttimeConstant = Math.max(this._minOutput, timeConstant);\n\t\tthis._param.setTargetAtTime(value, this.toSeconds(startTime), timeConstant);\n\t\treturn this;\n\t};\n\n\t/**\n\t * Sets an array of arbitrary parameter values starting at the given time\n\t * for the given duration.\n\t * \t\n\t * @param {Array} values \n\t * @param {Time} startTime \n\t * @param {Time} duration \n\t * @returns {Tone.Param} this\n\t */\n\tTone.Param.prototype.setValueCurveAtTime = function(values, startTime, duration){\n\t\tfor (var i = 0; i < values.length; i++){\n\t\t\tvalues[i] = this._fromUnits(values[i]);\n\t\t}\n\t\tthis._param.setValueCurveAtTime(values, this.toSeconds(startTime), this.toSeconds(duration));\n\t\treturn this;\n\t};\n\n\t/**\n\t * Cancels all scheduled parameter changes with times greater than or \n\t * equal to startTime.\n\t * \n\t * @param {Time} startTime\n\t * @returns {Tone.Param} this\n\t */\n\tTone.Param.prototype.cancelScheduledValues = function(startTime){\n\t\tthis._param.cancelScheduledValues(this.toSeconds(startTime));\n\t\treturn this;\n\t};\n\n\t/**\n\t * Ramps to the given value over the duration of the rampTime. \n\t * Automatically selects the best ramp type (exponential or linear)\n\t * depending on the `units` of the signal\n\t * \n\t * @param {number} value \n\t * @param {Time} rampTime \tThe time that it takes the \n\t * value to ramp from it's current value\n\t * @param {Time}\t[startTime=now] \tWhen the ramp should start. \n\t * @returns {Tone.Param} this\n\t * @example\n\t * //ramp to the value either linearly or exponentially \n\t * //depending on the \"units\" value of the signal\n\t * signal.rampTo(0, 10);\n\t * @example\n\t * //schedule it to ramp starting at a specific time\n\t * signal.rampTo(0, 10, 5)\n\t */\n\tTone.Param.prototype.rampTo = function(value, rampTime, startTime){\n\t\trampTime = this.defaultArg(rampTime, 0);\n\t\tif (this.units === Tone.Type.Frequency || this.units === Tone.Type.BPM || this.units === Tone.Type.Decibels){\n\t\t\tthis.exponentialRampToValue(value, rampTime, startTime);\n\t\t} else {\n\t\t\tthis.linearRampToValue(value, rampTime, startTime);\n\t\t}\n\t\treturn this;\n\t};\n\n\t/**\n\t * The LFO created by the signal instance. If none\n\t * was created, this is null.\n\t * @type {Tone.LFO}\n\t * @readOnly\n\t * @memberOf Tone.Param#\n\t * @name lfo\n\t */\n\tObject.defineProperty(Tone.Param.prototype, \"lfo\", {\n\t\tget : function(){\n\t\t\treturn this._lfo;\n\t\t}\n\t});\n\n\t/**\n\t * Clean up\n\t * @returns {Tone.Param} this\n\t */\n\tTone.Param.prototype.dispose = function(){\n\t\tTone.prototype.dispose.call(this);\n\t\tthis._param = null;\n\t\tif (this._lfo){\n\t\t\tthis._lfo.dispose();\n\t\t\tthis._lfo = null;\n\t\t}\n\t\treturn this;\n\t};\n\n\treturn Tone.Param;\n});","'use strict';\n\ndefine(function (require) {\n var p5sound = require('master');\n\n var Add = require('Tone/signal/Add');\n var Mult = require('Tone/signal/Multiply');\n var Scale = require('Tone/signal/Scale');\n\n /**\n *
Creates a signal that oscillates between -1.0 and 1.0.\n * By default, the oscillation takes the form of a sinusoidal\n * shape ('sine'). Additional types include 'triangle',\n * 'sawtooth' and 'square'. The frequency defaults to\n * 440 oscillations per second (440Hz, equal to the pitch of an\n * 'A' note).
\n *\n * @class p5.Oscillator\n * @constructor\n * @param {Number} [freq] frequency defaults to 440Hz\n * @param {String} [type] type of oscillator. Options:\n * 'sine' (default), 'triangle',\n * 'sawtooth', 'square'\n * @example\n *
\n * var osc;\n * var playing = false;\n *\n * function setup() {\n * backgroundColor = color(255,0,255);\n * textAlign(CENTER);\n *\n * osc = new p5.Oscillator();\n * osc.setType('sine');\n * osc.freq(240);\n * osc.amp(0);\n * osc.start();\n * }\n *\n * function draw() {\n * background(backgroundColor)\n * text('click to play', width/2, height/2);\n * }\n *\n * function mouseClicked() {\n * if (mouseX > 0 && mouseX < width && mouseY < height && mouseY > 0) {\n * if (!playing) {\n * // ramp amplitude to 0.5 over 0.05 seconds\n * osc.amp(0.5, 0.05);\n * playing = true;\n * backgroundColor = color(0,255,255);\n * } else {\n * // ramp amplitude to 0 over 0.5 seconds\n * osc.amp(0, 0.5);\n * playing = false;\n * backgroundColor = color(255,0,255);\n * }\n * }\n * }\n *
\n */\n p5.Oscillator = function(freq, type) {\n if (typeof freq === 'string') {\n var f = type;\n type = freq;\n freq = f;\n } if (typeof type === 'number') {\n var f = type;\n type = freq;\n freq = f;\n }\n this.started = false;\n\n // components\n this.phaseAmount = undefined;\n this.oscillator = p5sound.audiocontext.createOscillator();\n this.f = freq || 440.0; // frequency\n this.oscillator.type = type || 'sine';\n this.oscillator.frequency.setValueAtTime(this.f, p5sound.audiocontext.currentTime);\n\n // connections\n this.output = p5sound.audiocontext.createGain();\n\n this._freqMods = []; // modulators connected to this oscillator's frequency\n\n // set default output gain to 0.5\n this.output.gain.value = 0.5;\n this.output.gain.setValueAtTime(0.5, p5sound.audiocontext.currentTime);\n\n this.oscillator.connect(this.output);\n // stereo panning\n this.panPosition = 0.0;\n this.connection = p5sound.input; // connect to p5sound by default\n this.panner = new p5.Panner(this.output, this.connection, 1);\n\n //array of math operation signal chaining\n this.mathOps = [this.output];\n\n // add to the soundArray so we can dispose of the osc later\n p5sound.soundArray.push(this);\n };\n\n /**\n * Start an oscillator. Accepts an optional parameter to\n * determine how long (in seconds from now) until the\n * oscillator starts.\n *\n * @method start\n * @for p5.Oscillator\n * @param {Number} [time] startTime in seconds from now.\n * @param {Number} [frequency] frequency in Hz.\n */\n p5.Oscillator.prototype.start = function(time, f) {\n if (this.started) {\n var now = p5sound.audiocontext.currentTime;\n this.stop(now);\n }\n if (!this.started) {\n var freq = f || this.f;\n var type = this.oscillator.type;\n\n // set old osc free to be garbage collected (memory)\n if (this.oscillator) {\n this.oscillator.disconnect();\n delete this.oscillator;\n }\n\n // var detune = this.oscillator.frequency.value;\n this.oscillator = p5sound.audiocontext.createOscillator();\n this.oscillator.frequency.value = Math.abs(freq);\n this.oscillator.type = type;\n // this.oscillator.detune.value = detune;\n this.oscillator.connect(this.output);\n time = time || 0;\n this.oscillator.start(time + p5sound.audiocontext.currentTime);\n this.freqNode = this.oscillator.frequency;\n\n // if other oscillators are already connected to this osc's freq\n for (var i in this._freqMods) {\n if (typeof this._freqMods[i].connect !== 'undefined') {\n this._freqMods[i].connect(this.oscillator.frequency);\n }\n }\n\n this.started = true;\n }\n };\n\n /**\n * Stop an oscillator. Accepts an optional parameter\n * to determine how long (in seconds from now) until the\n * oscillator stops.\n *\n * @method stop\n * @for p5.Oscillator\n * @param {Number} secondsFromNow Time, in seconds from now.\n */\n p5.Oscillator.prototype.stop = function(time) {\n if (this.started) {\n var t = time || 0;\n var now = p5sound.audiocontext.currentTime;\n this.oscillator.stop(t + now);\n this.started = false;\n }\n };\n\n /**\n * Set the amplitude between 0 and 1.0. Or, pass in an object\n * such as an oscillator to modulate amplitude with an audio signal.\n *\n * @method amp\n * @for p5.Oscillator\n * @param {Number|Object} vol between 0 and 1.0\n * or a modulating signal/oscillator\n * @param {Number} [rampTime] create a fade that lasts rampTime\n * @param {Number} [timeFromNow] schedule this event to happen\n * seconds from now\n * @return {AudioParam} gain If no value is provided,\n * returns the Web Audio API\n * AudioParam that controls\n * this oscillator's\n * gain/amplitude/volume)\n */\n p5.Oscillator.prototype.amp = function(vol, rampTime, tFromNow) {\n var self = this;\n if (typeof vol === 'number') {\n var rampTime = rampTime || 0;\n var tFromNow = tFromNow || 0;\n var now = p5sound.audiocontext.currentTime;\n this.output.gain.linearRampToValueAtTime(vol, now + tFromNow + rampTime);\n }\n\n else if (vol) {\n vol.connect(self.output.gain);\n } else {\n // return the Gain Node\n return this.output.gain;\n }\n };\n\n // these are now the same thing\n p5.Oscillator.prototype.fade = p5.Oscillator.prototype.amp;\n\n p5.Oscillator.prototype.getAmp = function() {\n return this.output.gain.value;\n };\n\n /**\n * Set frequency of an oscillator to a value. Or, pass in an object\n * such as an oscillator to modulate the frequency with an audio signal.\n *\n * @method freq\n * @for p5.Oscillator\n * @param {Number|Object} Frequency Frequency in Hz\n * or modulating signal/oscillator\n * @param {Number} [rampTime] Ramp time (in seconds)\n * @param {Number} [timeFromNow] Schedule this event to happen\n * at x seconds from now\n * @return {AudioParam} Frequency If no value is provided,\n * returns the Web Audio API\n * AudioParam that controls\n * this oscillator's frequency\n * @example\n *
\n * var osc = new p5.Oscillator(300);\n * osc.start();\n * osc.freq(40, 10);\n *
\n */\n p5.Oscillator.prototype.freq = function(val, rampTime, tFromNow) {\n if (typeof val === 'number' && !isNaN(val)) {\n this.f = val;\n var now = p5sound.audiocontext.currentTime;\n var rampTime = rampTime || 0;\n var tFromNow = tFromNow || 0;\n var t = now + tFromNow + rampTime;\n // var currentFreq = this.oscillator.frequency.value;\n // this.oscillator.frequency.cancelScheduledValues(now);\n\n if (rampTime === 0) {\n this.oscillator.frequency.setValueAtTime(val, tFromNow + now);\n } else {\n if (val > 0 ) {\n this.oscillator.frequency.exponentialRampToValueAtTime(val, tFromNow + rampTime + now);\n } else {\n this.oscillator.frequency.linearRampToValueAtTime(val, tFromNow + rampTime + now);\n }\n }\n\n // reset phase if oscillator has a phase\n if (this.phaseAmount) {\n this.phase(this.phaseAmount);\n }\n\n } else if (val) {\n if (val.output) {\n val = val.output;\n }\n val.connect(this.oscillator.frequency);\n\n // keep track of what is modulating this param\n // so it can be re-connected if\n this._freqMods.push( val );\n } else {\n // return the Frequency Node\n return this.oscillator.frequency;\n }\n };\n\n p5.Oscillator.prototype.getFreq = function() {\n return this.oscillator.frequency.value;\n };\n\n /**\n * Set type to 'sine', 'triangle', 'sawtooth' or 'square'.\n *\n * @method setType\n * @for p5.Oscillator\n * @param {String} type 'sine', 'triangle', 'sawtooth' or 'square'.\n */\n p5.Oscillator.prototype.setType = function(type) {\n this.oscillator.type = type;\n };\n\n p5.Oscillator.prototype.getType = function() {\n return this.oscillator.type;\n };\n\n /**\n * Connect to a p5.sound / Web Audio object.\n *\n * @method connect\n * @for p5.Oscillator\n * @param {Object} unit A p5.sound or Web Audio object\n */\n p5.Oscillator.prototype.connect = function(unit) {\n if (!unit) {\n this.panner.connect(p5sound.input);\n }\n else if (unit.hasOwnProperty('input')) {\n this.panner.connect(unit.input);\n this.connection = unit.input;\n }\n else {\n this.panner.connect(unit);\n this.connection = unit;\n }\n };\n\n /**\n * Disconnect all outputs\n *\n * @method disconnect\n * @for p5.Oscillator\n */\n p5.Oscillator.prototype.disconnect = function() {\n if (this.output) {\n this.output.disconnect();\n }\n if (this.panner) {\n this.panner.disconnect();\n if (this.output) {\n this.output.connect(this.panner);\n }\n }\n this.oscMods = [];\n };\n\n /**\n * Pan between Left (-1) and Right (1)\n *\n * @method pan\n * @for p5.Oscillator\n * @param {Number} panning Number between -1 and 1\n * @param {Number} timeFromNow schedule this event to happen\n * seconds from now\n */\n p5.Oscillator.prototype.pan = function(pval, tFromNow) {\n this.panPosition = pval;\n this.panner.pan(pval, tFromNow);\n };\n\n p5.Oscillator.prototype.getPan = function() {\n return this.panPosition;\n };\n\n // get rid of the oscillator\n p5.Oscillator.prototype.dispose = function() {\n // remove reference from soundArray\n var index = p5sound.soundArray.indexOf(this);\n p5sound.soundArray.splice(index, 1);\n\n if (this.oscillator) {\n var now = p5sound.audiocontext.currentTime;\n this.stop(now);\n this.disconnect();\n this.panner = null;\n this.oscillator = null;\n }\n // if it is a Pulse\n if (this.osc2) {\n this.osc2.dispose();\n }\n };\n\n /**\n * Set the phase of an oscillator between 0.0 and 1.0.\n * In this implementation, phase is a delay time\n * based on the oscillator's current frequency.\n *\n * @method phase\n * @for p5.Oscillator\n * @param {Number} phase float between 0.0 and 1.0\n */\n p5.Oscillator.prototype.phase = function(p) {\n var delayAmt = p5.prototype.map(p, 0, 1.0, 0, 1/this.f);\n var now = p5sound.audiocontext.currentTime;\n\n this.phaseAmount = p;\n\n if (!this.dNode) {\n // create a delay node\n this.dNode = p5sound.audiocontext.createDelay();\n // put the delay node in between output and panner\n this.oscillator.disconnect();\n this.oscillator.connect(this.dNode);\n this.dNode.connect(this.output);\n }\n\n // set delay time to match phase:\n this.dNode.delayTime.setValueAtTime(delayAmt, now);\n };\n\n // ========================== //\n // SIGNAL MATH FOR MODULATION //\n // ========================== //\n\n // return sigChain(this, scale, thisChain, nextChain, Scale);\n var sigChain = function(o, mathObj, thisChain, nextChain, type) {\n var chainSource = o.oscillator;\n // if this type of math already exists in the chain, replace it\n for (var i in o.mathOps) {\n if (o.mathOps[i] instanceof type) {\n chainSource.disconnect();\n o.mathOps[i].dispose();\n thisChain = i;\n // assume nextChain is output gain node unless...\n if (thisChain < o.mathOps.length - 2) {\n nextChain = o.mathOps[i+1];\n }\n }\n }\n if (thisChain === o.mathOps.length - 1) {\n o.mathOps.push(nextChain);\n }\n // assume source is the oscillator unless i > 0\n if (i > 0) {\n chainSource = o.mathOps[i-1];\n }\n chainSource.disconnect();\n chainSource.connect(mathObj);\n mathObj.connect(nextChain);\n o.mathOps[thisChain] = mathObj;\n return o;\n };\n\n /**\n * Add a value to the p5.Oscillator's output amplitude,\n * and return the oscillator. Calling this method again\n * will override the initial add() with a new value.\n *\n * @method add\n * @for p5.Oscillator\n * @param {Number} number Constant number to add\n * @return {p5.Oscillator} Oscillator Returns this oscillator\n * with scaled output\n *\n */\n p5.Oscillator.prototype.add = function(num) {\n var add = new Add(num);\n var thisChain = this.mathOps.length-1;\n var nextChain = this.output;\n return sigChain(this, add, thisChain, nextChain, Add);\n };\n\n /**\n * Multiply the p5.Oscillator's output amplitude\n * by a fixed value (i.e. turn it up!). Calling this method\n * again will override the initial mult() with a new value.\n *\n * @method mult\n * @for p5.Oscillator\n * @param {Number} number Constant number to multiply\n * @return {p5.Oscillator} Oscillator Returns this oscillator\n * with multiplied output\n */\n p5.Oscillator.prototype.mult = function(num) {\n var mult = new Mult(num);\n var thisChain = this.mathOps.length-1;\n var nextChain = this.output;\n return sigChain(this, mult, thisChain, nextChain, Mult);\n };\n\n /**\n * Scale this oscillator's amplitude values to a given\n * range, and return the oscillator. Calling this method\n * again will override the initial scale() with new values.\n *\n * @method scale\n * @for p5.Oscillator\n * @param {Number} inMin input range minumum\n * @param {Number} inMax input range maximum\n * @param {Number} outMin input range minumum\n * @param {Number} outMax input range maximum\n * @return {p5.Oscillator} Oscillator Returns this oscillator\n * with scaled output\n */\n p5.Oscillator.prototype.scale = function(inMin, inMax, outMin, outMax) {\n var mapOutMin, mapOutMax;\n if (arguments.length === 4) {\n mapOutMin = p5.prototype.map(outMin, inMin, inMax, 0, 1) - 0.5;\n mapOutMax = p5.prototype.map(outMax, inMin, inMax, 0, 1) - 0.5;\n }\n else {\n mapOutMin = arguments[0];\n mapOutMax = arguments[1];\n }\n var scale = new Scale(mapOutMin, mapOutMax);\n var thisChain = this.mathOps.length-1;\n var nextChain = this.output;\n return sigChain(this, scale, thisChain, nextChain, Scale);\n\n // this.output.disconnect();\n // this.output.connect(scale)\n };\n\n // ============================== //\n // SinOsc, TriOsc, SqrOsc, SawOsc //\n // ============================== //\n\n /**\n * Constructor: new p5.SinOsc().\n * This creates a Sine Wave Oscillator and is\n * equivalent to new p5.Oscillator('sine')\n * or creating a p5.Oscillator and then calling\n * its method setType('sine').\n * See p5.Oscillator for methods.\n *\n * @class p5.SinOsc\n * @constructor\n * @extends p5.Oscillator\n * @param {Number} [freq] Set the frequency\n */\n p5.SinOsc = function(freq) {\n p5.Oscillator.call(this, freq, 'sine');\n };\n\n p5.SinOsc.prototype = Object.create(p5.Oscillator.prototype);\n\n /**\n * Constructor: new p5.TriOsc().\n * This creates a Triangle Wave Oscillator and is\n * equivalent to new p5.Oscillator('triangle')\n * or creating a p5.Oscillator and then calling\n * its method setType('triangle').\n * See p5.Oscillator for methods.\n *\n * @class p5.TriOsc\n * @constructor\n * @extends p5.Oscillator\n * @param {Number} [freq] Set the frequency\n */\n p5.TriOsc = function(freq) {\n p5.Oscillator.call(this, freq, 'triangle');\n };\n\n p5.TriOsc.prototype = Object.create(p5.Oscillator.prototype);\n\n /**\n * Constructor: new p5.SawOsc().\n * This creates a SawTooth Wave Oscillator and is\n * equivalent to new p5.Oscillator('sawtooth')\n * or creating a p5.Oscillator and then calling\n * its method setType('sawtooth').\n * See p5.Oscillator for methods.\n *\n * @class p5.SawOsc\n * @constructor\n * @extends p5.Oscillator\n * @param {Number} [freq] Set the frequency\n */\n p5.SawOsc = function(freq) {\n p5.Oscillator.call(this, freq, 'sawtooth');\n };\n\n p5.SawOsc.prototype = Object.create(p5.Oscillator.prototype);\n\n /**\n * Constructor: new p5.SqrOsc().\n * This creates a Square Wave Oscillator and is\n * equivalent to new p5.Oscillator('square')\n * or creating a p5.Oscillator and then calling\n * its method setType('square').\n * See p5.Oscillator for methods.\n *\n * @class p5.SqrOsc\n * @constructor\n * @extends p5.Oscillator\n * @param {Number} [freq] Set the frequency\n */\n p5.SqrOsc = function(freq) {\n p5.Oscillator.call(this, freq, 'square');\n };\n\n p5.SqrOsc.prototype = Object.create(p5.Oscillator.prototype);\n\n});\n","define([\"Tone/core/Tone\", \"Tone/type/Type\"], function (Tone) {\n\n\t\"use strict\";\n\n\t/**\n\t * @class A Timeline class for scheduling and maintaining state\n\t * along a timeline. All events must have a \"time\" property. \n\t * Internally, events are stored in time order for fast \n\t * retrieval.\n\t * @extends {Tone}\n\t * @param {Positive} [memory=Infinity] The number of previous events that are retained.\n\t */\n\tTone.Timeline = function(){\n\n\t\tvar options = this.optionsObject(arguments, [\"memory\"], Tone.Timeline.defaults);\n\n\t\t/**\n\t\t * The array of scheduled timeline events\n\t\t * @type {Array}\n\t\t * @private\n\t\t */\n\t\tthis._timeline = [];\n\n\t\t/**\n\t\t * An array of items to remove from the list. \n\t\t * @type {Array}\n\t\t * @private\n\t\t */\n\t\tthis._toRemove = [];\n\n\t\t/**\n\t\t * Flag if the tieline is mid iteration\n\t\t * @private\n\t\t * @type {Boolean}\n\t\t */\n\t\tthis._iterating = false;\n\n\t\t/**\n\t\t * The memory of the timeline, i.e.\n\t\t * how many events in the past it will retain\n\t\t * @type {Positive}\n\t\t */\n\t\tthis.memory = options.memory;\n\t};\n\n\tTone.extend(Tone.Timeline);\n\n\t/**\n\t * the default parameters\n\t * @static\n\t * @const\n\t */\n\tTone.Timeline.defaults = {\n\t\t\"memory\" : Infinity\n\t};\n\n\t/**\n\t * The number of items in the timeline.\n\t * @type {Number}\n\t * @memberOf Tone.Timeline#\n\t * @name length\n\t * @readOnly\n\t */\n\tObject.defineProperty(Tone.Timeline.prototype, \"length\", {\n\t\tget : function(){\n\t\t\treturn this._timeline.length;\n\t\t}\n\t});\n\n\t/**\n\t * Insert an event object onto the timeline. Events must have a \"time\" attribute.\n\t * @param {Object} event The event object to insert into the \n\t * timeline. \n\t * @returns {Tone.Timeline} this\n\t */\n\tTone.Timeline.prototype.add = function(event){\n\t\t//the event needs to have a time attribute\n\t\tif (this.isUndef(event.time)){\n\t\t\tthrow new Error(\"Tone.Timeline: events must have a time attribute\");\n\t\t}\n\t\tif (this._timeline.length){\n\t\t\tvar index = this._search(event.time);\n\t\t\tthis._timeline.splice(index + 1, 0, event);\n\t\t} else {\n\t\t\tthis._timeline.push(event);\t\t\t\n\t\t}\n\t\t//if the length is more than the memory, remove the previous ones\n\t\tif (this.length > this.memory){\n\t\t\tvar diff = this.length - this.memory;\n\t\t\tthis._timeline.splice(0, diff);\n\t\t}\n\t\treturn this;\n\t};\n\n\t/**\n\t * Remove an event from the timeline.\n\t * @param {Object} event The event object to remove from the list.\n\t * @returns {Tone.Timeline} this\n\t */\n\tTone.Timeline.prototype.remove = function(event){\n\t\tif (this._iterating){\n\t\t\tthis._toRemove.push(event);\n\t\t} else {\n\t\t\tvar index = this._timeline.indexOf(event);\n\t\t\tif (index !== -1){\n\t\t\t\tthis._timeline.splice(index, 1);\n\t\t\t}\n\t\t}\n\t\treturn this;\n\t};\n\n\t/**\n\t * Get the nearest event whose time is less than or equal to the given time.\n\t * @param {Number} time The time to query.\n\t * @returns {Object} The event object set after that time.\n\t */\n\tTone.Timeline.prototype.get = function(time){\n\t\tvar index = this._search(time);\n\t\tif (index !== -1){\n\t\t\treturn this._timeline[index];\n\t\t} else {\n\t\t\treturn null;\n\t\t}\n\t};\n\n\t/**\n\t * Return the first event in the timeline without removing it\n\t * @returns {Object} The first event object\n\t */\n\tTone.Timeline.prototype.peek = function(){\n\t\treturn this._timeline[0];\n\t};\n\n\t/**\n\t * Return the first event in the timeline and remove it\n\t * @returns {Object} The first event object\n\t */\n\tTone.Timeline.prototype.shift = function(){\n\t\treturn this._timeline.shift();\n\t};\n\n\t/**\n\t * Get the event which is scheduled after the given time.\n\t * @param {Number} time The time to query.\n\t * @returns {Object} The event object after the given time\n\t */\n\tTone.Timeline.prototype.getAfter = function(time){\n\t\tvar index = this._search(time);\n\t\tif (index + 1 < this._timeline.length){\n\t\t\treturn this._timeline[index + 1];\n\t\t} else {\n\t\t\treturn null;\n\t\t}\n\t};\n\n\t/**\n\t * Get the event before the event at the given time.\n\t * @param {Number} time The time to query.\n\t * @returns {Object} The event object before the given time\n\t */\n\tTone.Timeline.prototype.getBefore = function(time){\n\t\tvar len = this._timeline.length;\n\t\t//if it's after the last item, return the last item\n\t\tif (len > 0 && this._timeline[len - 1].time < time){\n\t\t\treturn this._timeline[len - 1];\n\t\t}\n\t\tvar index = this._search(time);\n\t\tif (index - 1 >= 0){\n\t\t\treturn this._timeline[index - 1];\n\t\t} else {\n\t\t\treturn null;\n\t\t}\n\t};\n\n\t/**\n\t * Cancel events after the given time\n\t * @param {Number} time The time to query.\n\t * @returns {Tone.Timeline} this\n\t */\n\tTone.Timeline.prototype.cancel = function(after){\n\t\tif (this._timeline.length > 1){\n\t\t\tvar index = this._search(after);\n\t\t\tif (index >= 0){\n\t\t\t\tif (this._timeline[index].time === after){\n\t\t\t\t\t//get the first item with that time\n\t\t\t\t\tfor (var i = index; i >= 0; i--){\n\t\t\t\t\t\tif (this._timeline[i].time === after){\n\t\t\t\t\t\t\tindex = i;\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tthis._timeline = this._timeline.slice(0, index);\n\t\t\t\t} else {\n\t\t\t\t\tthis._timeline = this._timeline.slice(0, index + 1);\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tthis._timeline = [];\n\t\t\t}\n\t\t} else if (this._timeline.length === 1){\n\t\t\t//the first item's time\n\t\t\tif (this._timeline[0].time >= after){\n\t\t\t\tthis._timeline = [];\n\t\t\t}\n\t\t}\n\t\treturn this;\n\t};\n\n\t/**\n\t * Cancel events before or equal to the given time.\n\t * @param {Number} time The time to cancel before.\n\t * @returns {Tone.Timeline} this\n\t */\n\tTone.Timeline.prototype.cancelBefore = function(time){\n\t\tif (this._timeline.length){\n\t\t\tvar index = this._search(time);\n\t\t\tif (index >= 0){\n\t\t\t\tthis._timeline = this._timeline.slice(index + 1);\n\t\t\t}\n\t\t}\n\t\treturn this;\n\t};\n\n\t/**\n\t * Does a binary serach on the timeline array and returns the \n\t * nearest event index whose time is after or equal to the given time.\n\t * If a time is searched before the first index in the timeline, -1 is returned.\n\t * If the time is after the end, the index of the last item is returned.\n\t * @param {Number} time \n\t * @return {Number} the index in the timeline array \n\t * @private\n\t */\n\tTone.Timeline.prototype._search = function(time){\n\t\tvar beginning = 0;\n\t\tvar len = this._timeline.length;\n\t\tvar end = len;\n\t\tif (len > 0 && this._timeline[len - 1].time <= time){\n\t\t\treturn len - 1;\n\t\t}\n\t\twhile (beginning < end){\n\t\t\t// calculate the midpoint for roughly equal partition\n\t\t\tvar midPoint = Math.floor(beginning + (end - beginning) / 2);\n\t\t\tvar event = this._timeline[midPoint];\n\t\t\tvar nextEvent = this._timeline[midPoint + 1];\n\t\t\tif (event.time === time){\n\t\t\t\t//choose the last one that has the same time\n\t\t\t\tfor (var i = midPoint; i < this._timeline.length; i++){\n\t\t\t\t\tvar testEvent = this._timeline[i];\n\t\t\t\t\tif (testEvent.time === time){\n\t\t\t\t\t\tmidPoint = i;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\treturn midPoint;\n\t\t\t} else if (event.time < time && nextEvent.time > time){\n\t\t\t\treturn midPoint;\n\t\t\t} else if (event.time > time){\n\t\t\t\t//search lower\n\t\t\t\tend = midPoint;\n\t\t\t} else if (event.time < time){\n\t\t\t\t//search upper\n\t\t\t\tbeginning = midPoint + 1;\n\t\t\t} \n\t\t}\n\t\treturn -1;\n\t};\n\n\t/**\n\t * Internal iterator. Applies extra safety checks for \n\t * removing items from the array. \n\t * @param {Function} callback \n\t * @param {Number=} lowerBound \n\t * @param {Number=} upperBound \n\t * @private\n\t */\n\tTone.Timeline.prototype._iterate = function(callback, lowerBound, upperBound){\n\t\tthis._iterating = true;\n\t\tlowerBound = this.defaultArg(lowerBound, 0);\n\t\tupperBound = this.defaultArg(upperBound, this._timeline.length - 1);\n\t\tfor (var i = lowerBound; i <= upperBound; i++){\n\t\t\tcallback(this._timeline[i]);\n\t\t}\n\t\tthis._iterating = false;\n\t\tif (this._toRemove.length > 0){\n\t\t\tfor (var j = 0; j < this._toRemove.length; j++){\n\t\t\t\tvar index = this._timeline.indexOf(this._toRemove[j]);\n\t\t\t\tif (index !== -1){\n\t\t\t\t\tthis._timeline.splice(index, 1);\n\t\t\t\t}\n\t\t\t}\n\t\t\tthis._toRemove = [];\n\t\t}\n\t};\n\n\t/**\n\t * Iterate over everything in the array\n\t * @param {Function} callback The callback to invoke with every item\n\t * @returns {Tone.Timeline} this\n\t */\n\tTone.Timeline.prototype.forEach = function(callback){\n\t\tthis._iterate(callback);\n\t\treturn this;\n\t};\n\n\t/**\n\t * Iterate over everything in the array at or before the given time.\n\t * @param {Number} time The time to check if items are before\n\t * @param {Function} callback The callback to invoke with every item\n\t * @returns {Tone.Timeline} this\n\t */\n\tTone.Timeline.prototype.forEachBefore = function(time, callback){\n\t\t//iterate over the items in reverse so that removing an item doesn't break things\n\t\tvar upperBound = this._search(time);\n\t\tif (upperBound !== -1){\n\t\t\tthis._iterate(callback, 0, upperBound);\n\t\t}\n\t\treturn this;\n\t};\n\n\t/**\n\t * Iterate over everything in the array after the given time.\n\t * @param {Number} time The time to check if items are before\n\t * @param {Function} callback The callback to invoke with every item\n\t * @returns {Tone.Timeline} this\n\t */\n\tTone.Timeline.prototype.forEachAfter = function(time, callback){\n\t\t//iterate over the items in reverse so that removing an item doesn't break things\n\t\tvar lowerBound = this._search(time);\n\t\tthis._iterate(callback, lowerBound + 1);\n\t\treturn this;\n\t};\n\n\t/**\n\t * Iterate over everything in the array at or after the given time. Similar to \n\t * forEachAfter, but includes the item(s) at the given time.\n\t * @param {Number} time The time to check if items are before\n\t * @param {Function} callback The callback to invoke with every item\n\t * @returns {Tone.Timeline} this\n\t */\n\tTone.Timeline.prototype.forEachFrom = function(time, callback){\n\t\t//iterate over the items in reverse so that removing an item doesn't break things\n\t\tvar lowerBound = this._search(time);\n\t\t//work backwards until the event time is less than time\n\t\twhile (lowerBound >= 0 && this._timeline[lowerBound].time >= time){\n\t\t\tlowerBound--;\n\t\t}\n\t\tthis._iterate(callback, lowerBound + 1);\n\t\treturn this;\n\t};\n\n\t/**\n\t * Iterate over everything in the array at the given time\n\t * @param {Number} time The time to check if items are before\n\t * @param {Function} callback The callback to invoke with every item\n\t * @returns {Tone.Timeline} this\n\t */\n\tTone.Timeline.prototype.forEachAtTime = function(time, callback){\n\t\t//iterate over the items in reverse so that removing an item doesn't break things\n\t\tvar upperBound = this._search(time);\n\t\tif (upperBound !== -1){\n\t\t\tthis._iterate(function(event){\n\t\t\t\tif (event.time === time){\n\t\t\t\t\tcallback(event);\n\t\t\t\t} \n\t\t\t}, 0, upperBound);\n\t\t}\n\t\treturn this;\n\t};\n\n\t/**\n\t * Clean up.\n\t * @return {Tone.Timeline} this\n\t */\n\tTone.Timeline.prototype.dispose = function(){\n\t\tTone.prototype.dispose.call(this);\n\t\tthis._timeline = null;\n\t\tthis._toRemove = null;\n\t};\n\n\treturn Tone.Timeline;\n});","define([\"Tone/core/Tone\", \"Tone/signal/Multiply\", \"Tone/signal/Signal\"], function(Tone){\n\n\t\"use strict\";\n\n\t/**\n\t * @class Negate the incoming signal. i.e. an input signal of 10 will output -10\n\t *\n\t * @constructor\n\t * @extends {Tone.SignalBase}\n\t * @example\n\t * var neg = new Tone.Negate();\n\t * var sig = new Tone.Signal(-2).connect(neg);\n\t * //output of neg is positive 2. \n\t */\n\tTone.Negate = function(){\n\t\t/**\n\t\t * negation is done by multiplying by -1\n\t\t * @type {Tone.Multiply}\n\t\t * @private\n\t\t */\n\t\tthis._multiply = this.input = this.output = new Tone.Multiply(-1);\n\t};\n\n\tTone.extend(Tone.Negate, Tone.SignalBase);\n\n\t/**\n\t * clean up\n\t * @returns {Tone.Negate} this\n\t */\n\tTone.Negate.prototype.dispose = function(){\n\t\tTone.prototype.dispose.call(this);\n\t\tthis._multiply.dispose();\n\t\tthis._multiply = null;\n\t\treturn this;\n\t}; \n\n\treturn Tone.Negate;\n});","define([\"Tone/core/Tone\", \"Tone/signal/Signal\", \"Tone/signal/Multiply\", \"Tone/signal/WaveShaper\"], \nfunction(Tone){\n\n\t\"use strict\";\n\n\t/**\n\t * @class GreaterThanZero outputs 1 when the input is strictly greater than zero\n\t * \n\t * @constructor\n\t * @extends {Tone.SignalBase}\n\t * @example\n\t * var gt0 = new Tone.GreaterThanZero();\n\t * var sig = new Tone.Signal(0.01).connect(gt0);\n\t * //the output of gt0 is 1. \n\t * sig.value = 0;\n\t * //the output of gt0 is 0. \n\t */\n\tTone.GreaterThanZero = function(){\n\t\t\n\t\t/**\n\t\t * @type {Tone.WaveShaper}\n\t\t * @private\n\t\t */\n\t\tthis._thresh = this.output = new Tone.WaveShaper(function(val){\n\t\t\tif (val <= 0){\n\t\t\t\treturn 0;\n\t\t\t} else {\n\t\t\t\treturn 1;\n\t\t\t}\n\t\t}, 127);\n\n\t\t/**\n\t\t * scale the first thresholded signal by a large value.\n\t\t * this will help with values which are very close to 0\n\t\t * @type {Tone.Multiply}\n\t\t * @private\n\t\t */\n\t\tthis._scale = this.input = new Tone.Multiply(10000);\n\n\t\t//connections\n\t\tthis._scale.connect(this._thresh);\n\t};\n\n\tTone.extend(Tone.GreaterThanZero, Tone.SignalBase);\n\n\t/**\n\t * dispose method\n\t * @returns {Tone.GreaterThanZero} this\n\t */\n\tTone.GreaterThanZero.prototype.dispose = function(){\n\t\tTone.prototype.dispose.call(this);\n\t\tthis._scale.dispose();\n\t\tthis._scale = null;\n\t\tthis._thresh.dispose();\n\t\tthis._thresh = null;\n\t\treturn this;\n\t};\n\n\treturn Tone.GreaterThanZero;\n});","define([\"Tone/core/Tone\", \"Tone/signal/TimelineSignal\", \"Tone/core/TimelineState\", \n\t\"Tone/core/Emitter\", \"Tone/core/Context\"], function (Tone) {\n\n\t\"use strict\";\n\n\t/**\n\t * @class A sample accurate clock which provides a callback at the given rate. \n\t * While the callback is not sample-accurate (it is still susceptible to\n\t * loose JS timing), the time passed in as the argument to the callback\n\t * is precise. For most applications, it is better to use Tone.Transport\n\t * instead of the Clock by itself since you can synchronize multiple callbacks.\n\t *\n\t * \t@constructor\n\t * @extends {Tone.Emitter}\n\t * \t@param {function} callback The callback to be invoked with the time of the audio event\n\t * \t@param {Frequency} frequency The rate of the callback\n\t * \t@example\n\t * //the callback will be invoked approximately once a second\n\t * //and will print the time exactly once a second apart.\n\t * var clock = new Tone.Clock(function(time){\n\t * \tconsole.log(time);\n\t * }, 1);\n\t */\n\tTone.Clock = function(){\n\n\t\tTone.Emitter.call(this);\n\n\t\tvar options = this.optionsObject(arguments, [\"callback\", \"frequency\"], Tone.Clock.defaults);\n\n\t\t/**\n\t\t * The callback function to invoke at the scheduled tick.\n\t\t * @type {Function}\n\t\t */\n\t\tthis.callback = options.callback;\n\n\t\t/**\n\t\t * The next time the callback is scheduled.\n\t\t * @type {Number}\n\t\t * @private\n\t\t */\n\t\tthis._nextTick = 0;\n\n\t\t/**\n\t\t * The last state of the clock.\n\t\t * @type {State}\n\t\t * @private\n\t\t */\n\t\tthis._lastState = Tone.State.Stopped;\n\n\t\t/**\n\t\t * The rate the callback function should be invoked. \n\t\t * @type {BPM}\n\t\t * @signal\n\t\t */\n\t\tthis.frequency = new Tone.TimelineSignal(options.frequency, Tone.Type.Frequency);\n\t\tthis._readOnly(\"frequency\");\n\n\t\t/**\n\t\t * The number of times the callback was invoked. Starts counting at 0\n\t\t * and increments after the callback was invoked. \n\t\t * @type {Ticks}\n\t\t * @readOnly\n\t\t */\n\t\tthis.ticks = 0;\n\n\t\t/**\n\t\t * The state timeline\n\t\t * @type {Tone.TimelineState}\n\t\t * @private\n\t\t */\n\t\tthis._state = new Tone.TimelineState(Tone.State.Stopped);\n\n\t\t/**\n\t\t * The loop function bound to its context. \n\t\t * This is necessary to remove the event in the end.\n\t\t * @type {Function}\n\t\t * @private\n\t\t */\n\t\tthis._boundLoop = this._loop.bind(this);\n\n\t\t//bind a callback to the worker thread\n \tthis.context.on(\"tick\", this._boundLoop);\n\t};\n\n\tTone.extend(Tone.Clock, Tone.Emitter);\n\n\t/**\n\t * The defaults\n\t * @const\n\t * @type {Object}\n\t */\n\tTone.Clock.defaults = {\n\t\t\"callback\" : Tone.noOp,\n\t\t\"frequency\" : 1,\n\t\t\"lookAhead\" : \"auto\",\n\t};\n\n\t/**\n\t * Returns the playback state of the source, either \"started\", \"stopped\" or \"paused\".\n\t * @type {Tone.State}\n\t * @readOnly\n\t * @memberOf Tone.Clock#\n\t * @name state\n\t */\n\tObject.defineProperty(Tone.Clock.prototype, \"state\", {\n\t\tget : function(){\n\t\t\treturn this._state.getValueAtTime(this.now());\n\t\t}\n\t});\n\n\t/**\n\t * Start the clock at the given time. Optionally pass in an offset\n\t * of where to start the tick counter from.\n\t * @param {Time} time The time the clock should start\n\t * @param {Ticks=} offset Where the tick counter starts counting from.\n\t * @return {Tone.Clock} this\n\t */\n\tTone.Clock.prototype.start = function(time, offset){\n\t\ttime = this.toSeconds(time);\n\t\tif (this._state.getValueAtTime(time) !== Tone.State.Started){\n\t\t\tthis._state.add({\n\t\t\t\t\"state\" : Tone.State.Started, \n\t\t\t\t\"time\" : time,\n\t\t\t\t\"offset\" : offset\n\t\t\t});\n\t\t}\n\t\treturn this;\t\n\t};\n\n\t/**\n\t * Stop the clock. Stopping the clock resets the tick counter to 0.\n\t * @param {Time} [time=now] The time when the clock should stop.\n\t * @returns {Tone.Clock} this\n\t * @example\n\t * clock.stop();\n\t */\n\tTone.Clock.prototype.stop = function(time){\n\t\ttime = this.toSeconds(time);\n\t\tthis._state.cancel(time);\n\t\tthis._state.setStateAtTime(Tone.State.Stopped, time);\n\t\treturn this;\t\n\t};\n\n\n\t/**\n\t * Pause the clock. Pausing does not reset the tick counter.\n\t * @param {Time} [time=now] The time when the clock should stop.\n\t * @returns {Tone.Clock} this\n\t */\n\tTone.Clock.prototype.pause = function(time){\n\t\ttime = this.toSeconds(time);\n\t\tif (this._state.getValueAtTime(time) === Tone.State.Started){\n\t\t\tthis._state.setStateAtTime(Tone.State.Paused, time);\n\t\t}\n\t\treturn this;\t\n\t};\n\n\t/**\n\t * The scheduling loop.\n\t * @param {Number} time The current page time starting from 0\n\t * when the page was loaded.\n\t * @private\n\t */\n\tTone.Clock.prototype._loop = function(){\n\t\t//get the frequency value to compute the value of the next loop\n\t\tvar now = this.now();\n\t\t//if it's started\n\t\tvar lookAhead = this.context.lookAhead;\n\t\tvar updateInterval = this.context.updateInterval;\n\t\tvar lagCompensation = this.context.lag * 2;\n\t\tvar loopInterval = now + lookAhead + updateInterval + lagCompensation;\n\t\twhile (loopInterval > this._nextTick && this._state){\n\t\t\tvar currentState = this._state.getValueAtTime(this._nextTick);\n\t\t\tif (currentState !== this._lastState){\n\t\t\t\tthis._lastState = currentState;\n\t\t\t\tvar event = this._state.get(this._nextTick);\n\t\t\t\t// emit an event\n\t\t\t\tif (currentState === Tone.State.Started){\n\t\t\t\t\t//correct the time\n\t\t\t\t\tthis._nextTick = event.time;\n\t\t\t\t\tif (!this.isUndef(event.offset)){\n\t\t\t\t\t\tthis.ticks = event.offset;\n\t\t\t\t\t}\n\t\t\t\t\tthis.emit(\"start\", event.time, this.ticks);\n\t\t\t\t} else if (currentState === Tone.State.Stopped){\n\t\t\t\t\tthis.ticks = 0;\n\n\t\t\t\t\tthis.emit(\"stop\", event.time);\n\t\t\t\t} else if (currentState === Tone.State.Paused){\n\t\t\t\t\tthis.emit(\"pause\", event.time);\n\t\t\t\t}\n\t\t\t}\n\t\t\tvar tickTime = this._nextTick;\n\t\t\tif (this.frequency){\n\t\t\t\tthis._nextTick += 1 / this.frequency.getValueAtTime(this._nextTick);\n\t\t\t\tif (currentState === Tone.State.Started){\n\t\t\t\t\tthis.callback(tickTime);\n\t\t\t\t\tthis.ticks++;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t};\n\n\t/**\n\t * Returns the scheduled state at the given time.\n\t * @param {Time} time The time to query.\n\t * @return {String} The name of the state input in setStateAtTime.\n\t * @example\n\t * clock.start(\"+0.1\");\n\t * clock.getStateAtTime(\"+0.1\"); //returns \"started\"\n\t */\n\tTone.Clock.prototype.getStateAtTime = function(time){\n\t\ttime = this.toSeconds(time);\n\t\treturn this._state.getValueAtTime(time);\n\t};\n\n\t/**\n\t * Clean up\n\t * @returns {Tone.Clock} this\n\t */\n\tTone.Clock.prototype.dispose = function(){\n\t\tTone.Emitter.prototype.dispose.call(this);\n\t\tthis.context.off(\"tick\", this._boundLoop);\n\t\tthis._writable(\"frequency\");\n\t\tthis.frequency.dispose();\n\t\tthis.frequency = null;\n\t\tthis._boundLoop = null;\n\t\tthis._nextTick = Infinity;\n\t\tthis.callback = null;\n\t\tthis._state.dispose();\n\t\tthis._state = null;\n\t};\n\n\treturn Tone.Clock;\n});","'use strict';\ndefine(function (require) {\n\n var p5sound = require('master');\n var AudioVoice = require('audioVoice');\n var noteToFreq = require('helpers').noteToFreq;\n\n var DEFAULT_SUSTAIN = 0.15;\n\n /**\n * A MonoSynth is used as a single voice for sound synthesis.\n * This is a class to be used in conjunction with the PolySynth\n * class. Custom synthetisers should be built inheriting from\n * this class.\n *\n * @class p5.MonoSynth\n * @constructor\n * @example\n *
\n * var monoSynth;\n *\n * function setup() {\n * var cnv = createCanvas(100, 100);\n * cnv.mousePressed(playSynth);\n *\n * monoSynth = new p5.MonoSynth();\n *\n * textAlign(CENTER);\n * text('click to play', width/2, height/2);\n * }\n *\n * function playSynth() {\n * // time from now (in seconds)\n * var time = 0;\n * // note duration (in seconds)\n * var dur = 0.25;\n * // velocity (volume, from 0 to 1)\n * var v = 0.2;\n *\n * monoSynth.play(\"G3\", v, time, dur);\n * monoSynth.play(\"C4\", v, time += dur, dur);\n *\n * background(random(255), random(255), 255);\n * text('click to play', width/2, height/2);\n * }\n *
\n **/\n\n p5.MonoSynth = function () {\n AudioVoice.call(this);\n\n this.oscillator = new p5.Oscillator();\n\n this.env = new p5.Envelope();\n this.env.setRange(1, 0);\n this.env.setExp(true);\n\n //set params\n this.setADSR(0.02, 0.25, 0.05, 0.35);\n\n // oscillator --> env --> this.output (gain) --> p5.soundOut\n this.oscillator.disconnect();\n this.oscillator.connect(this.output);\n\n this.env.disconnect();\n this.env.setInput(this.output.gain);\n\n // reset oscillator gain to 1.0\n this.oscillator.output.gain.value = 1.0;\n\n this.oscillator.start();\n this.connect();\n\n p5sound.soundArray.push(this);\n };\n\n p5.MonoSynth.prototype = Object.create(p5.AudioVoice.prototype);\n\n /**\n * Play tells the MonoSynth to start playing a note. This method schedules\n * the calling of .triggerAttack and .triggerRelease.\n *\n * @method play\n * @for p5.MonoSynth\n * @param {String | Number} note the note you want to play, specified as a\n * frequency in Hertz (Number) or as a midi\n * value in Note/Octave format (\"C4\", \"Eb3\"...etc\")\n * See \n * Tone. Defaults to 440 hz.\n * @param {Number} [velocity] velocity of the note to play (ranging from 0 to 1)\n * @param {Number} [secondsFromNow] time from now (in seconds) at which to play\n * @param {Number} [sustainTime] time to sustain before releasing the envelope\n * @example\n *
\n * var monoSynth;\n *\n * function setup() {\n * var cnv = createCanvas(100, 100);\n * cnv.mousePressed(playSynth);\n *\n * monoSynth = new p5.MonoSynth();\n *\n * textAlign(CENTER);\n * text('click to play', width/2, height/2);\n * }\n *\n * function playSynth() {\n * // time from now (in seconds)\n * var time = 0;\n * // note duration (in seconds)\n * var dur = 1/6;\n * // note velocity (volume, from 0 to 1)\n * var v = random();\n *\n * monoSynth.play(\"Fb3\", v, 0, dur);\n * monoSynth.play(\"Gb3\", v, time += dur, dur);\n *\n * background(random(255), random(255), 255);\n * text('click to play', width/2, height/2);\n * }\n *
\n *\n */\n p5.MonoSynth.prototype.play = function (note, velocity, secondsFromNow, susTime) {\n this.triggerAttack(note, velocity, ~~secondsFromNow);\n this.triggerRelease(~~secondsFromNow + (susTime || DEFAULT_SUSTAIN));\n };\n\n /**\n * Trigger the Attack, and Decay portion of the Envelope.\n * Similar to holding down a key on a piano, but it will\n * hold the sustain level until you let go.\n *\n * @param {String | Number} note the note you want to play, specified as a\n * frequency in Hertz (Number) or as a midi\n * value in Note/Octave format (\"C4\", \"Eb3\"...etc\")\n * See \n * Tone. Defaults to 440 hz\n * @param {Number} [velocity] velocity of the note to play (ranging from 0 to 1)\n * @param {Number} [secondsFromNow] time from now (in seconds) at which to play\n * @method triggerAttack\n * @for p5.MonoSynth\n * @example\n *
\n * var monoSynth = new p5.MonoSynth();\n *\n * function mousePressed() {\n * monoSynth.triggerAttack(\"E3\");\n * }\n *\n * function mouseReleased() {\n * monoSynth.triggerRelease();\n * }\n *
\n */\n p5.MonoSynth.prototype.triggerAttack = function (note, velocity, secondsFromNow) {\n var secondsFromNow = ~~secondsFromNow;\n var freq = noteToFreq(note);\n var vel = velocity || 0.1;\n this.oscillator.freq(freq, 0, secondsFromNow);\n this.env.ramp(this.output.gain, secondsFromNow, vel);\n };\n\n /**\n * Trigger the release of the Envelope. This is similar to releasing\n * the key on a piano and letting the sound fade according to the\n * release level and release time.\n *\n * @param {Number} secondsFromNow time to trigger the release\n * @method triggerRelease\n * @for p5.MonoSynth\n * @example\n *
\n * var monoSynth = new p5.MonoSynth();\n *\n * function mousePressed() {\n * monoSynth.triggerAttack(\"E3\");\n * }\n *\n * function mouseReleased() {\n * monoSynth.triggerRelease();\n * }\n *
\n */\n p5.MonoSynth.prototype.triggerRelease = function (secondsFromNow) {\n var secondsFromNow = secondsFromNow || 0;\n this.env.ramp(this.output.gain, secondsFromNow, 0);\n };\n\n /**\n * Set values like a traditional\n * \n * ADSR envelope\n * .\n *\n * @method setADSR\n * @for p5.MonoSynth\n * @param {Number} attackTime Time (in seconds before envelope\n * reaches Attack Level\n * @param {Number} [decayTime] Time (in seconds) before envelope\n * reaches Decay/Sustain Level\n * @param {Number} [susRatio] Ratio between attackLevel and releaseLevel, on a scale from 0 to 1,\n * where 1.0 = attackLevel, 0.0 = releaseLevel.\n * The susRatio determines the decayLevel and the level at which the\n * sustain portion of the envelope will sustain.\n * For example, if attackLevel is 0.4, releaseLevel is 0,\n * and susAmt is 0.5, the decayLevel would be 0.2. If attackLevel is\n * increased to 1.0 (using setRange),\n * then decayLevel would increase proportionally, to become 0.5.\n * @param {Number} [releaseTime] Time in seconds from now (defaults to 0)\n */\n p5.MonoSynth.prototype.setADSR = function (attack,decay,sustain,release) {\n this.env.setADSR(attack, decay, sustain, release);\n };\n\n\n /**\n * Getters and Setters\n * @property {Number} attack\n * @for p5.MonoSynth\n */\n /**\n * @property {Number} decay\n * @for p5.MonoSynth\n */\n /**\n * @property {Number} sustain\n * @for p5.MonoSynth\n */\n /**\n * @property {Number} release\n * @for p5.MonoSynth\n */\n Object.defineProperties(p5.MonoSynth.prototype, {\n 'attack': {\n get : function() {\n return this.env.aTime;\n },\n set : function(attack) {\n this.env.setADSR(attack, this.env.dTime,\n this.env.sPercent, this.env.rTime);\n }\n },\n 'decay': {\n get : function() {\n return this.env.dTime;\n },\n set : function(decay) {\n this.env.setADSR(this.env.aTime, decay,\n this.env.sPercent, this.env.rTime);\n }\n },\n 'sustain': {\n get : function() {\n return this.env.sPercent;\n },\n set : function(sustain) {\n this.env.setADSR(this.env.aTime, this.env.dTime,\n sustain, this.env.rTime);\n }\n },\n 'release': {\n get : function() {\n return this.env.rTime;\n },\n set : function(release) {\n this.env.setADSR(this.env.aTime, this.env.dTime,\n this.env.sPercent, release);\n }\n },\n });\n\n\n /**\n * MonoSynth amp\n * @method amp\n * @for p5.MonoSynth\n * @param {Number} vol desired volume\n * @param {Number} [rampTime] Time to reach new volume\n * @return {Number} new volume value\n */\n p5.MonoSynth.prototype.amp = function(vol, rampTime) {\n var t = rampTime || 0;\n if (typeof vol !== 'undefined') {\n this.oscillator.amp(vol, t);\n }\n return this.oscillator.amp().value;\n };\n\n /**\n * Connect to a p5.sound / Web Audio object.\n *\n * @method connect\n * @for p5.MonoSynth\n * @param {Object} unit A p5.sound or Web Audio object\n */\n\n p5.MonoSynth.prototype.connect = function(unit) {\n var u = unit || p5sound.input;\n this.output.connect(u.input ? u.input : u);\n };\n\n /**\n * Disconnect all outputs\n *\n * @method disconnect\n * @for p5.MonoSynth\n */\n p5.MonoSynth.prototype.disconnect = function() {\n if (this.output) {\n this.output.disconnect();\n }\n };\n\n\n /**\n * Get rid of the MonoSynth and free up its resources / memory.\n *\n * @method dispose\n * @for p5.MonoSynth\n */\n p5.MonoSynth.prototype.dispose = function() {\n AudioVoice.prototype.dispose.apply(this);\n\n if (this.env) {\n this.env.dispose();\n }\n if (this.oscillator) {\n this.oscillator.dispose();\n }\n };\n\n});\n","'use strict';\ndefine(function() {\n var p5sound = require('master');\n\n /**\n * Base class for monophonic synthesizers. Any extensions of this class\n * should follow the API and implement the methods below in order to\n * remain compatible with p5.PolySynth();\n *\n * @class p5.AudioVoice\n * @constructor\n */\n p5.AudioVoice = function () {\n\t this.ac = p5sound.audiocontext;\n\t this.output = this.ac.createGain();\n\t this.connect();\n\t p5sound.soundArray.push(this);\n };\n\n p5.AudioVoice.prototype.play = function (note, velocity, secondsFromNow, sustime) {\n };\n\n p5.AudioVoice.prototype.triggerAttack = function (note, velocity, secondsFromNow) {\n };\n\n p5.AudioVoice.prototype.triggerRelease = function (secondsFromNow) {\n };\n\n p5.AudioVoice.prototype.amp = function(vol, rampTime) {\n };\n\n /**\n * Connect to p5 objects or Web Audio Nodes\n * @method connect\n * @for p5.AudioVoice\n * @param {Object} unit\n */\n p5.AudioVoice.prototype.connect = function(unit) {\n var u = unit || p5sound.input;\n this.output.connect(u.input ? u.input : u);\n };\n\n /**\n * Disconnect from soundOut\n * @method disconnect\n * @for p5.AudioVoice\n */\n p5.AudioVoice.prototype.disconnect = function() {\n this.output.disconnect();\n };\n\n p5.AudioVoice.prototype.dispose = function() {\n if (this.output) {\n this.output.disconnect();\n delete this.output;\n }\n };\n\n return p5.AudioVoice;\n});\n","'use strict';\ndefine(function (require) {\n\n var p5sound = require('master');\n var TimelineSignal = require('Tone/signal/TimelineSignal');\n var noteToFreq = require('helpers').noteToFreq;\n\n /**\n * An AudioVoice is used as a single voice for sound synthesis.\n * The PolySynth class holds an array of AudioVoice, and deals\n * with voices allocations, with setting notes to be played, and\n * parameters to be set.\n *\n * @class p5.PolySynth\n * @constructor\n *\n * @param {Number} [synthVoice] A monophonic synth voice inheriting\n * the AudioVoice class. Defaults to p5.MonoSynth\n * @param {Number} [maxVoices] Number of voices, defaults to 8;\n * @example\n *
\n * var polySynth;\n *\n * function setup() {\n * var cnv = createCanvas(100, 100);\n * cnv.mousePressed(playSynth);\n *\n * polySynth = new p5.PolySynth();\n *\n * textAlign(CENTER);\n * text('click to play', width/2, height/2);\n * }\n *\n * function playSynth() {\n * // note duration (in seconds)\n * var dur = 1.5;\n *\n * // time from now (in seconds)\n * var time = 0;\n *\n * // velocity (volume, from 0 to 1)\n * var vel = 0.1;\n *\n * // notes can overlap with each other\n * polySynth.play(\"G2\", vel, 0, dur);\n * polySynth.play(\"C3\", vel, time += 1/3, dur);\n * polySynth.play(\"G3\", vel, time += 1/3, dur);\n *\n * background(random(255), random(255), 255);\n * text('click to play', width/2, height/2);\n * }\n *
\n **/\n p5.PolySynth = function(audioVoice, maxVoices) {\n //audiovoices will contain maxVoices many monophonic synths\n this.audiovoices = [];\n\n /**\n * An object that holds information about which notes have been played and\n * which notes are currently being played. New notes are added as keys\n * on the fly. While a note has been attacked, but not released, the value of the\n * key is the audiovoice which is generating that note. When notes are released,\n * the value of the key becomes undefined.\n * @property notes\n */\n this.notes = {};\n\n //indices of the most recently used, and least recently used audiovoice\n this._newest = 0;\n this._oldest = 0;\n\n /**\n * A PolySynth must have at least 1 voice, defaults to 8\n * @property polyvalue\n */\n this.maxVoices = maxVoices || 8;\n\n /**\n * Monosynth that generates the sound for each note that is triggered. The\n * p5.PolySynth defaults to using the p5.MonoSynth as its voice.\n * @property AudioVoice\n */\n this.AudioVoice = audioVoice === undefined ? p5.MonoSynth : audioVoice;\n\n /**\n * This value must only change as a note is attacked or released. Due to delay\n * and sustain times, Tone.TimelineSignal is required to schedule the change in value.\n\t * @private\n * @property {Tone.TimelineSignal} _voicesInUse\n */\n this._voicesInUse = new TimelineSignal(0);\n\n this.output = p5sound.audiocontext.createGain();\n this.connect();\n\n //Construct the appropriate number of audiovoices\n this._allocateVoices();\n p5sound.soundArray.push(this);\n };\n\n /**\n * Construct the appropriate number of audiovoices\n * @private\n * @for p5.PolySynth\n * @method _allocateVoices\n */\n p5.PolySynth.prototype._allocateVoices = function() {\n for(var i = 0; i< this.maxVoices; i++) {\n this.audiovoices.push(new this.AudioVoice());\n this.audiovoices[i].disconnect();\n this.audiovoices[i].connect(this.output);\n }\n };\n\n /**\n * Play a note by triggering noteAttack and noteRelease with sustain time\n *\n * @method play\n * @for p5.PolySynth\n * @param {Number} [note] midi note to play (ranging from 0 to 127 - 60 being a middle C)\n * @param {Number} [velocity] velocity of the note to play (ranging from 0 to 1)\n * @param {Number} [secondsFromNow] time from now (in seconds) at which to play\n * @param {Number} [sustainTime] time to sustain before releasing the envelope\n * @example\n *
\n * var polySynth;\n *\n * function setup() {\n * var cnv = createCanvas(100, 100);\n * cnv.mousePressed(playSynth);\n *\n * polySynth = new p5.PolySynth();\n *\n * textAlign(CENTER);\n * text('click to play', width/2, height/2);\n * }\n *\n * function playSynth() {\n * // note duration (in seconds)\n * var dur = 0.1;\n *\n * // time from now (in seconds)\n * var time = 0;\n *\n * // velocity (volume, from 0 to 1)\n * var vel = 0.1;\n *\n * polySynth.play(\"G2\", vel, 0, dur);\n * polySynth.play(\"C3\", vel, 0, dur);\n * polySynth.play(\"G3\", vel, 0, dur);\n *\n * background(random(255), random(255), 255);\n * text('click to play', width/2, height/2);\n * }\n *
\n */\n p5.PolySynth.prototype.play = function (note,velocity, secondsFromNow, susTime) {\n var susTime = susTime || 1;\n this.noteAttack(note, velocity, secondsFromNow);\n this.noteRelease(note, secondsFromNow + susTime);\n };\n\n\n /**\n * noteADSR sets the envelope for a specific note that has just been triggered.\n * Using this method modifies the envelope of whichever audiovoice is being used\n * to play the desired note. The envelope should be reset before noteRelease is called\n * in order to prevent the modified envelope from being used on other notes.\n *\n * @method noteADSR\n * @for p5.PolySynth\n * @param {Number} [note] Midi note on which ADSR should be set.\n * @param {Number} [attackTime] Time (in seconds before envelope\n * reaches Attack Level\n * @param {Number} [decayTime] Time (in seconds) before envelope\n * reaches Decay/Sustain Level\n * @param {Number} [susRatio] Ratio between attackLevel and releaseLevel, on a scale from 0 to 1,\n * where 1.0 = attackLevel, 0.0 = releaseLevel.\n * The susRatio determines the decayLevel and the level at which the\n * sustain portion of the envelope will sustain.\n * For example, if attackLevel is 0.4, releaseLevel is 0,\n * and susAmt is 0.5, the decayLevel would be 0.2. If attackLevel is\n * increased to 1.0 (using setRange),\n * then decayLevel would increase proportionally, to become 0.5.\n * @param {Number} [releaseTime] Time in seconds from now (defaults to 0)\n **/\n\n p5.PolySynth.prototype.noteADSR = function (note,a,d,s,r,timeFromNow) {\n var now = p5sound.audiocontext.currentTime;\n var timeFromNow = timeFromNow || 0;\n var t = now + timeFromNow\n this.audiovoices[ this.notes[note].getValueAtTime(t) ].setADSR(a,d,s,r);\n };\n\n\n /**\n * Set the PolySynths global envelope. This method modifies the envelopes of each\n * monosynth so that all notes are played with this envelope.\n *\n * @method setADSR\n * @for p5.PolySynth\n * @param {Number} [attackTime] Time (in seconds before envelope\n * reaches Attack Level\n * @param {Number} [decayTime] Time (in seconds) before envelope\n * reaches Decay/Sustain Level\n * @param {Number} [susRatio] Ratio between attackLevel and releaseLevel, on a scale from 0 to 1,\n * where 1.0 = attackLevel, 0.0 = releaseLevel.\n * The susRatio determines the decayLevel and the level at which the\n * sustain portion of the envelope will sustain.\n * For example, if attackLevel is 0.4, releaseLevel is 0,\n * and susAmt is 0.5, the decayLevel would be 0.2. If attackLevel is\n * increased to 1.0 (using setRange),\n * then decayLevel would increase proportionally, to become 0.5.\n * @param {Number} [releaseTime] Time in seconds from now (defaults to 0)\n **/\n p5.PolySynth.prototype.setADSR = function(a,d,s,r) {\n this.audiovoices.forEach(function(voice) {\n voice.setADSR(a,d,s,r);\n });\n };\n\n /**\n * Trigger the Attack, and Decay portion of a MonoSynth.\n * Similar to holding down a key on a piano, but it will\n * hold the sustain level until you let go.\n *\n * @method noteAttack\n * @for p5.PolySynth\n * @param {Number} [note] midi note on which attack should be triggered.\n * @param {Number} [velocity] velocity of the note to play (ranging from 0 to 1)/\n * @param {Number} [secondsFromNow] time from now (in seconds)\n * @example\n *
\n * var polySynth = new p5.PolySynth();\n * var pitches = [\"G\", \"D\", \"G\", \"C\"];\n * var octaves = [2, 3, 4];\n *\n * function mousePressed() {\n * // play a chord: multiple notes at the same time\n * for (var i = 0; i < 4; i++) {\n * var note = random(pitches) + random(octaves);\n * polySynth.noteAttack(note, 0.1);\n * }\n * }\n *\n * function mouseReleased() {\n * // release all voices\n * polySynth.noteRelease();\n * }\n *
\n */\n p5.PolySynth.prototype.noteAttack = function (_note, _velocity, secondsFromNow) {\n //this value goes to the audiovoices which handle their own scheduling\n var secondsFromNow = ~~secondsFromNow;\n\n //this value is used by this._voicesInUse\n var acTime = p5sound.audiocontext.currentTime + secondsFromNow;\n\n //Convert note to frequency if necessary. This is because entries into this.notes\n //should be based on frequency for the sake of consistency.\n var note = noteToFreq(_note);\n var velocity = _velocity || 0.1;\n\n var currentVoice;\n\n //Release the note if it is already playing\n if (this.notes[note] && this.notes[note].getValueAtTime(acTime) !== null) {\n this.noteRelease(note, 0);\n }\n\n //Check to see how many voices are in use at the time the note will start\n if (this._voicesInUse.getValueAtTime(acTime) < this.maxVoices) {\n currentVoice = Math.max(~~this._voicesInUse.getValueAtTime(acTime), 0);\n }\n //If we are exceeding the polyvalue, bump off the oldest notes and replace\n //with a new note\n else {\n currentVoice = this._oldest;\n\n var oldestNote = p5.prototype.freqToMidi(this.audiovoices[this._oldest].oscillator.freq().value);\n this.noteRelease(oldestNote);\n this._oldest = ( this._oldest + 1 ) % (this.maxVoices - 1);\n }\n\n //Overrite the entry in the notes object. A note (frequency value)\n //corresponds to the index of the audiovoice that is playing it\n this.notes[note] = new TimelineSignal();\n this.notes[note].setValueAtTime(currentVoice, acTime);\n\n //Find the scheduled change in this._voicesInUse that will be previous to this new note\n //Add 1 and schedule this value at time 't', when this note will start playing\n var previousVal = this._voicesInUse._searchBefore(acTime) === null ? 0 : this._voicesInUse._searchBefore(acTime).value;\n this._voicesInUse.setValueAtTime(previousVal + 1, acTime);\n\n //Then update all scheduled values that follow to increase by 1\n this._updateAfter(acTime, 1);\n\n this._newest = currentVoice;\n //The audiovoice handles the actual scheduling of the note\n if (typeof velocity === 'number') {\n var maxRange = 1 / this._voicesInUse.getValueAtTime(acTime) * 2;\n velocity = velocity > maxRange ? maxRange : velocity;\n }\n this.audiovoices[currentVoice].triggerAttack(note, velocity, secondsFromNow);\n };\n\n /**\n * Private method to ensure accurate values of this._voicesInUse\n * Any time a new value is scheduled, it is necessary to increment all subsequent\n * scheduledValues after attack, and decrement all subsequent\n * scheduledValues after release\n *\n * @private\n * @for p5.PolySynth\n * @param {[type]} time [description]\n * @param {[type]} value [description]\n * @return {[type]} [description]\n */\n p5.PolySynth.prototype._updateAfter = function(time, value) {\n if(this._voicesInUse._searchAfter(time) === null) {\n return;\n } else{\n this._voicesInUse._searchAfter(time).value += value;\n var nextTime = this._voicesInUse._searchAfter(time).time;\n this._updateAfter(nextTime, value);\n }\n };\n\n\n /**\n * Trigger the Release of an AudioVoice note. This is similar to releasing\n * the key on a piano and letting the sound fade according to the\n * release level and release time.\n *\n * @method noteRelease\n * @for p5.PolySynth\n * @param {Number} [note] midi note on which attack should be triggered.\n * If no value is provided, all notes will be released.\n * @param {Number} [secondsFromNow] time to trigger the release\n * @example\n *
\n * var pitches = [\"G\", \"D\", \"G\", \"C\"];\n * var octaves = [2, 3, 4];\n * var polySynth = new p5.PolySynth();\n *\n * function mousePressed() {\n * // play a chord: multiple notes at the same time\n * for (var i = 0; i < 4; i++) {\n * var note = random(pitches) + random(octaves);\n * polySynth.noteAttack(note, 0.1);\n * }\n * }\n *\n * function mouseReleased() {\n * // release all voices\n * polySynth.noteRelease();\n * }\n *
\n *\n */\n p5.PolySynth.prototype.noteRelease = function (_note,secondsFromNow) {\n var now = p5sound.audiocontext.currentTime;\n var tFromNow = secondsFromNow || 0;\n var t = now + tFromNow;\n\n // if a note value is not provided, release all voices\n if (!_note) {\n this.audiovoices.forEach(function(voice) {\n voice.triggerRelease(tFromNow)\n });\n this._voicesInUse.setValueAtTime(0, t);\n for (var n in this.notes) {\n this.notes[n].dispose();\n delete this.notes[n];\n }\n return;\n }\n\n //Make sure note is in frequency inorder to query the this.notes object\n var note = noteToFreq(_note);\n\n if (!this.notes[note] || this.notes[note].getValueAtTime(t) === null) {\n console.warn('Cannot release a note that is not already playing');\n } else {\n //Find the scheduled change in this._voicesInUse that will be previous to this new note\n //subtract 1 and schedule this value at time 't', when this note will stop playing\n var previousVal = Math.max(~~this._voicesInUse.getValueAtTime(t).value, 1);\n this._voicesInUse.setValueAtTime(previousVal - 1, t);\n //Then update all scheduled values that follow to decrease by 1 but never go below 0\n if (previousVal > 0) {\n this._updateAfter(t, -1);\n }\n\n this.audiovoices[ this.notes[note].getValueAtTime(t) ].triggerRelease(tFromNow);\n this.notes[note].dispose();\n delete this.notes[note];\n\n this._newest = this._newest === 0 ? 0 : (this._newest - 1) % (this.maxVoices - 1);\n }\n\n };\n\n /**\n * Connect to a p5.sound / Web Audio object.\n *\n * @method connect\n * @for p5.PolySynth\n * @param {Object} unit A p5.sound or Web Audio object\n */\n p5.PolySynth.prototype.connect = function (unit) {\n var u = unit || p5sound.input;\n this.output.connect(u.input ? u.input : u);\n };\n\n /**\n * Disconnect all outputs\n *\n * @method disconnect\n * @for p5.PolySynth\n */\n p5.PolySynth.prototype.disconnect = function() {\n if (this.output) {\n this.output.disconnect();\n }\n };\n\n /**\n * Get rid of the MonoSynth and free up its resources / memory.\n *\n * @method dispose\n * @for p5.PolySynth\n */\n p5.PolySynth.prototype.dispose = function() {\n this.audiovoices.forEach(function(voice) {\n voice.dispose();\n });\n\n if (this.output) {\n this.output.disconnect();\n delete this.output;\n }\n };\n\n});\n","'use strict';\n\ndefine(function (require) {\n\n require('audioworklet-polyfill');\n require('shims');\n require('audiocontext');\n var p5SOUND = require('master');\n require('helpers');\n require('errorHandler');\n require('audioWorklet');\n require('panner');\n require('soundfile');\n require('amplitude');\n require('fft');\n require('signal');\n require('oscillator');\n require('envelope');\n require('pulse');\n require('noise');\n require('audioin');\n require('filter');\n require('eq');\n require('panner3d');\n require('listener3d');\n require('delay');\n require('reverb');\n require('metro');\n require('looper');\n require('soundLoop');\n require('compressor');\n require('soundRecorder');\n require('peakDetect');\n require('gain');\n require('monosynth');\n require('polysynth');\n require('distortion');\n require('audioVoice');\n require('monosynth');\n require('polysynth');\n\n return p5SOUND;\n\n});\n","!function(){var e,t=[];function r(e){var r=this,n={},i=-1;this.parameters.forEach(function(e,o){var s=t[++i]||(t[i]=new Float32Array(r.bufferSize));s.fill(e.value),n[o]=s}),this.processor.realm.exec(\"self.sampleRate=sampleRate=\"+this.context.sampleRate+\";self.currentTime=currentTime=\"+this.context.currentTime);var s=o(e.inputBuffer),a=o(e.outputBuffer);this.instance.process([s],[a],n)}function o(e){for(var t=[],r=0;r= this.sampleLimit) {\\n this.stop();\\n return true;\\n }\\n\\n var input = inputs[0];\\n var output = outputs[0];\\n\\n for (var channel = 0; channel < output.length; ++channel) {\\n var inputChannel = input[channel];\\n\\n if (channel === 0) {\\n this.leftBuffers.push(inputChannel);\\n\\n if (this.numInputChannels === 1) {\\n this.rightBuffers.push(inputChannel);\\n }\\n } else if (channel === 1 && this.numInputChannels > 1) {\\n this.rightBuffers.push(inputChannel);\\n }\\n }\\n\\n this.recordedSamples += output[0].length;\\n return true;\\n }\\n }, {\\n key: \\\"record\\\",\\n value: function record(duration) {\\n if (duration) {\\n this.sampleLimit = Math.round(duration * sampleRate);\\n }\\n\\n this.recording = true;\\n }\\n }, {\\n key: \\\"stop\\\",\\n value: function stop() {\\n this.recording = false;\\n var buffers = this.getBuffers();\\n var leftBuffer = buffers[0].buffer;\\n var rightBuffer = buffers[1].buffer;\\n this.port.postMessage({\\n name: 'buffers',\\n leftBuffer: leftBuffer,\\n rightBuffer: rightBuffer\\n }, [leftBuffer, rightBuffer]);\\n this.clear();\\n }\\n }, {\\n key: \\\"getBuffers\\\",\\n value: function getBuffers() {\\n var buffers = [];\\n buffers.push(this.mergeBuffers(this.leftBuffers));\\n buffers.push(this.mergeBuffers(this.rightBuffers));\\n return buffers;\\n }\\n }, {\\n key: \\\"mergeBuffers\\\",\\n value: function mergeBuffers(channelBuffer) {\\n var result = new Float32Array(this.recordedSamples);\\n var offset = 0;\\n var lng = channelBuffer.length;\\n\\n for (var i = 0; i < lng; i++) {\\n var buffer = channelBuffer[i];\\n result.set(buffer, offset);\\n offset += buffer.length;\\n }\\n\\n return result;\\n }\\n }, {\\n key: \\\"clear\\\",\\n value: function clear() {\\n this.leftBuffers = [];\\n this.rightBuffers = [];\\n this.recordedSamples = 0;\\n this.sampleLimit = null;\\n }\\n }]);\\n\\n return RecorderProcessor;\\n}(_wrapNativeSuper(AudioWorkletProcessor));\\n\\nregisterProcessor(processorNames.recorderProcessor, RecorderProcessor);\"","export default \"function _typeof(obj) { if (typeof Symbol === \\\"function\\\" && typeof Symbol.iterator === \\\"symbol\\\") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === \\\"function\\\" && obj.constructor === Symbol && obj !== Symbol.prototype ? \\\"symbol\\\" : typeof obj; }; } return _typeof(obj); }\\n\\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\\\"Cannot call a class as a function\\\"); } }\\n\\nfunction _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if (\\\"value\\\" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }\\n\\nfunction _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }\\n\\nfunction _possibleConstructorReturn(self, call) { if (call && (_typeof(call) === \\\"object\\\" || typeof call === \\\"function\\\")) { return call; } return _assertThisInitialized(self); }\\n\\nfunction _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError(\\\"this hasn't been initialised - super() hasn't been called\\\"); } return self; }\\n\\nfunction _inherits(subClass, superClass) { if (typeof superClass !== \\\"function\\\" && superClass !== null) { throw new TypeError(\\\"Super expression must either be null or a function\\\"); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, writable: true, configurable: true } }); if (superClass) _setPrototypeOf(subClass, superClass); }\\n\\nfunction _wrapNativeSuper(Class) { var _cache = typeof Map === \\\"function\\\" ? new Map() : undefined; _wrapNativeSuper = function _wrapNativeSuper(Class) { if (Class === null || !_isNativeFunction(Class)) return Class; if (typeof Class !== \\\"function\\\") { throw new TypeError(\\\"Super expression must either be null or a function\\\"); } if (typeof _cache !== \\\"undefined\\\") { if (_cache.has(Class)) return _cache.get(Class); _cache.set(Class, Wrapper); } function Wrapper() { return _construct(Class, arguments, _getPrototypeOf(this).constructor); } Wrapper.prototype = Object.create(Class.prototype, { constructor: { value: Wrapper, enumerable: false, writable: true, configurable: true } }); return _setPrototypeOf(Wrapper, Class); }; return _wrapNativeSuper(Class); }\\n\\nfunction isNativeReflectConstruct() { if (typeof Reflect === \\\"undefined\\\" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === \\\"function\\\") return true; try { Date.prototype.toString.call(Reflect.construct(Date, [], function () {})); return true; } catch (e) { return false; } }\\n\\nfunction _construct(Parent, args, Class) { if (isNativeReflectConstruct()) { _construct = Reflect.construct; } else { _construct = function _construct(Parent, args, Class) { var a = [null]; a.push.apply(a, args); var Constructor = Function.bind.apply(Parent, a); var instance = new Constructor(); if (Class) _setPrototypeOf(instance, Class.prototype); return instance; }; } return _construct.apply(null, arguments); }\\n\\nfunction _isNativeFunction(fn) { return Function.toString.call(fn).indexOf(\\\"[native code]\\\") !== -1; }\\n\\nfunction _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); }\\n\\nfunction _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); }; return _getPrototypeOf(o); }\\n\\n// import processor name via preval.require so that it's available as a value at compile time\\nvar processorNames = {\\n \\\"recorderProcessor\\\": \\\"recorder-processor\\\",\\n \\\"soundFileProcessor\\\": \\\"sound-file-processor\\\",\\n \\\"amplitudeProcessor\\\": \\\"amplitude-processor\\\"\\n};\\n\\nvar SoundFileProcessor =\\n/*#__PURE__*/\\nfunction (_AudioWorkletProcesso) {\\n _inherits(SoundFileProcessor, _AudioWorkletProcesso);\\n\\n function SoundFileProcessor() {\\n var _this;\\n\\n _classCallCheck(this, SoundFileProcessor);\\n\\n _this = _possibleConstructorReturn(this, _getPrototypeOf(SoundFileProcessor).call(this));\\n _this.paused = false;\\n\\n _this.port.onmessage = function (event) {\\n var data = event.data;\\n\\n if (data.name === 'play') {\\n _this.paused = false;\\n } else if (data.name === 'pause') {\\n _this.paused = true;\\n }\\n };\\n\\n return _this;\\n }\\n\\n _createClass(SoundFileProcessor, [{\\n key: \\\"process\\\",\\n value: function process(inputs) {\\n var input = inputs[0];\\n var inputChannel = input[0];\\n var position = inputChannel[inputChannel.length - 1];\\n\\n if (!this.paused) {\\n this.port.postMessage({\\n name: 'position',\\n position: position\\n });\\n }\\n\\n return true;\\n }\\n }]);\\n\\n return SoundFileProcessor;\\n}(_wrapNativeSuper(AudioWorkletProcessor));\\n\\nregisterProcessor(processorNames.soundFileProcessor, SoundFileProcessor);\"","export default \"function _typeof(obj) { if (typeof Symbol === \\\"function\\\" && typeof Symbol.iterator === \\\"symbol\\\") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === \\\"function\\\" && obj.constructor === Symbol && obj !== Symbol.prototype ? \\\"symbol\\\" : typeof obj; }; } return _typeof(obj); }\\n\\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\\\"Cannot call a class as a function\\\"); } }\\n\\nfunction _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if (\\\"value\\\" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }\\n\\nfunction _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }\\n\\nfunction _possibleConstructorReturn(self, call) { if (call && (_typeof(call) === \\\"object\\\" || typeof call === \\\"function\\\")) { return call; } return _assertThisInitialized(self); }\\n\\nfunction _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError(\\\"this hasn't been initialised - super() hasn't been called\\\"); } return self; }\\n\\nfunction _inherits(subClass, superClass) { if (typeof superClass !== \\\"function\\\" && superClass !== null) { throw new TypeError(\\\"Super expression must either be null or a function\\\"); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, writable: true, configurable: true } }); if (superClass) _setPrototypeOf(subClass, superClass); }\\n\\nfunction _wrapNativeSuper(Class) { var _cache = typeof Map === \\\"function\\\" ? new Map() : undefined; _wrapNativeSuper = function _wrapNativeSuper(Class) { if (Class === null || !_isNativeFunction(Class)) return Class; if (typeof Class !== \\\"function\\\") { throw new TypeError(\\\"Super expression must either be null or a function\\\"); } if (typeof _cache !== \\\"undefined\\\") { if (_cache.has(Class)) return _cache.get(Class); _cache.set(Class, Wrapper); } function Wrapper() { return _construct(Class, arguments, _getPrototypeOf(this).constructor); } Wrapper.prototype = Object.create(Class.prototype, { constructor: { value: Wrapper, enumerable: false, writable: true, configurable: true } }); return _setPrototypeOf(Wrapper, Class); }; return _wrapNativeSuper(Class); }\\n\\nfunction isNativeReflectConstruct() { if (typeof Reflect === \\\"undefined\\\" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === \\\"function\\\") return true; try { Date.prototype.toString.call(Reflect.construct(Date, [], function () {})); return true; } catch (e) { return false; } }\\n\\nfunction _construct(Parent, args, Class) { if (isNativeReflectConstruct()) { _construct = Reflect.construct; } else { _construct = function _construct(Parent, args, Class) { var a = [null]; a.push.apply(a, args); var Constructor = Function.bind.apply(Parent, a); var instance = new Constructor(); if (Class) _setPrototypeOf(instance, Class.prototype); return instance; }; } return _construct.apply(null, arguments); }\\n\\nfunction _isNativeFunction(fn) { return Function.toString.call(fn).indexOf(\\\"[native code]\\\") !== -1; }\\n\\nfunction _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); }\\n\\nfunction _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); }; return _getPrototypeOf(o); }\\n\\n// import processor name via preval.require so that it's available as a value at compile time\\nvar processorNames = {\\n \\\"recorderProcessor\\\": \\\"recorder-processor\\\",\\n \\\"soundFileProcessor\\\": \\\"sound-file-processor\\\",\\n \\\"amplitudeProcessor\\\": \\\"amplitude-processor\\\"\\n};\\n\\nvar AmplitudeProcessor =\\n/*#__PURE__*/\\nfunction (_AudioWorkletProcesso) {\\n _inherits(AmplitudeProcessor, _AudioWorkletProcesso);\\n\\n function AmplitudeProcessor(options) {\\n var _this;\\n\\n _classCallCheck(this, AmplitudeProcessor);\\n\\n _this = _possibleConstructorReturn(this, _getPrototypeOf(AmplitudeProcessor).call(this));\\n var processorOptions = options.processorOptions || {};\\n _this.smoothing = processorOptions.smoothing || 0;\\n _this.normalize = processorOptions.normalize || false;\\n _this.stereoVol = [0, 0];\\n _this.stereoVolNorm = [0, 0];\\n _this.volMax = 0.001;\\n\\n _this.port.onmessage = function (event) {\\n var data = event.data;\\n\\n if (data.name === 'toggleNormalize') {\\n _this.normalize = data.normalize;\\n } else if (data.name === 'smoothing') {\\n _this.smoothing = Math.max(0, Math.min(1, data.smoothing));\\n }\\n };\\n\\n return _this;\\n } // TO DO make this stereo / dependent on # of audio channels\\n\\n\\n _createClass(AmplitudeProcessor, [{\\n key: \\\"process\\\",\\n value: function process(inputs, outputs) {\\n var input = inputs[0];\\n var output = outputs[0];\\n var smoothing = this.smoothing;\\n\\n for (var channel = 0; channel < input.length; ++channel) {\\n var inputBuffer = input[channel];\\n var bufLength = inputBuffer.length;\\n var sum = 0;\\n\\n for (var i = 0; i < bufLength; i++) {\\n var x = inputBuffer[i];\\n\\n if (this.normalize) {\\n sum += Math.max(Math.min(x / this.volMax, 1), -1) * Math.max(Math.min(x / this.volMax, 1), -1);\\n } else {\\n sum += x * x;\\n }\\n } // ... then take the square root of the sum.\\n\\n\\n var rms = Math.sqrt(sum / bufLength);\\n this.stereoVol[channel] = Math.max(rms, this.stereoVol[channel] * smoothing);\\n this.volMax = Math.max(this.stereoVol[channel], this.volMax);\\n } // calculate stero normalized volume and add volume from all channels together\\n\\n\\n var volSum = 0;\\n\\n for (var index = 0; index < this.stereoVol.length; index++) {\\n this.stereoVolNorm[index] = Math.max(Math.min(this.stereoVol[index] / this.volMax, 1), 0);\\n volSum += this.stereoVol[index];\\n } // volume is average of channels\\n\\n\\n var volume = volSum / this.stereoVol.length; // normalized value\\n\\n var volNorm = Math.max(Math.min(volume / this.volMax, 1), 0);\\n this.port.postMessage({\\n name: 'amplitude',\\n volume: volume,\\n volNorm: volNorm,\\n stereoVol: this.stereoVol,\\n stereoVolNorm: this.stereoVolNorm\\n }); // pass input through to output\\n\\n for (var _channel = 0; _channel < output.length; ++_channel) {\\n output[_channel].set(input[_channel]);\\n }\\n\\n return true;\\n }\\n }]);\\n\\n return AmplitudeProcessor;\\n}(_wrapNativeSuper(AudioWorkletProcessor));\\n\\nregisterProcessor(processorNames.amplitudeProcessor, AmplitudeProcessor);\"","'use strict';\n\ndefine(function (require) {\n\n var p5sound = require('master');\n var ac = p5sound.audiocontext;\n\n // Stereo panner\n // if there is a stereo panner node use it\n if(typeof ac.createStereoPanner !== 'undefined') {\n p5.Panner = function (input, output) {\n this.stereoPanner = this.input = ac.createStereoPanner();\n input.connect(this.stereoPanner);\n this.stereoPanner.connect(output);\n };\n\n p5.Panner.prototype.pan = function(val, tFromNow) {\n var time = tFromNow || 0;\n var t = ac.currentTime + time;\n\n this.stereoPanner.pan.linearRampToValueAtTime(val, t);\n };\n\n //not implemented because stereopanner\n //node does not require this and will automatically\n //convert single channel or multichannel to stereo.\n //tested with single and stereo, not with (>2) multichannel\n p5.Panner.prototype.inputChannels = function() {};\n\n p5.Panner.prototype.connect = function(obj) {\n this.stereoPanner.connect(obj);\n };\n\n p5.Panner.prototype.disconnect = function() {\n if (this.stereoPanner) {\n this.stereoPanner.disconnect();\n }\n };\n\n } else {\n // if there is no createStereoPanner object\n // such as in safari 7.1.7 at the time of writing this\n // use this method to create the effect\n p5.Panner = function(input, output, numInputChannels) {\n this.input = ac.createGain();\n input.connect(this.input);\n\n this.left = ac.createGain();\n this.right = ac.createGain();\n this.left.channelInterpretation = 'discrete';\n this.right.channelInterpretation = 'discrete';\n\n // if input is stereo\n if (numInputChannels > 1) {\n this.splitter = ac.createChannelSplitter(2);\n this.input.connect(this.splitter);\n\n this.splitter.connect(this.left, 1);\n this.splitter.connect(this.right, 0);\n }\n else {\n this.input.connect(this.left);\n this.input.connect(this.right);\n }\n\n this.output = ac.createChannelMerger(2);\n this.left.connect(this.output, 0, 1);\n this.right.connect(this.output, 0, 0);\n this.output.connect(output);\n };\n\n // -1 is left, +1 is right\n p5.Panner.prototype.pan = function(val, tFromNow) {\n var time = tFromNow || 0;\n var t = ac.currentTime + time;\n var v = (val + 1) / 2;\n var rightVal = Math.cos(v*Math.PI/2);\n var leftVal = Math.sin(v * Math.PI/2);\n this.left.gain.linearRampToValueAtTime(leftVal, t);\n this.right.gain.linearRampToValueAtTime(rightVal, t);\n };\n\n p5.Panner.prototype.inputChannels = function(numChannels) {\n if (numChannels === 1) {\n this.input.disconnect();\n this.input.connect(this.left);\n this.input.connect(this.right);\n } else if (numChannels === 2) {\n if (typeof(this.splitter === 'undefined')) {\n this.splitter = ac.createChannelSplitter(2);\n }\n this.input.disconnect();\n this.input.connect(this.splitter);\n this.splitter.connect(this.left, 1);\n this.splitter.connect(this.right, 0);\n }\n };\n\n p5.Panner.prototype.connect = function(obj) {\n this.output.connect(obj);\n };\n\n p5.Panner.prototype.disconnect = function() {\n if (this.output) {\n this.output.disconnect();\n }\n };\n }\n});\n","'use strict';\n\ndefine(function (require) {\n\n var CustomError = require('errorHandler');\n var p5sound = require('master');\n var ac = p5sound.audiocontext;\n var midiToFreq = require('helpers').midiToFreq;\n var convertToWav = require('helpers').convertToWav;\n var processorNames = require('./audioWorklet/processorNames');\n\n /**\n *
SoundFile object with a path to a file.
\n *\n *
The p5.SoundFile may not be available immediately because\n * it loads the file information asynchronously.
\n *\n *
To do something with the sound as soon as it loads\n * pass the name of a function as the second parameter.
\n *\n *
Only one file path is required. However, audio file formats\n * (i.e. mp3, ogg, wav and m4a/aac) are not supported by all\n * web browsers. If you want to ensure compatability, instead of a single\n * file path, you may include an Array of filepaths, and the browser will\n * choose a format that works.
\n *\n * @class p5.SoundFile\n * @constructor\n * @param {String|Array} path path to a sound file (String). Optionally,\n * you may include multiple file formats in\n * an array. Alternately, accepts an object\n * from the HTML5 File API, or a p5.File.\n * @param {Function} [successCallback] Name of a function to call once file loads\n * @param {Function} [errorCallback] Name of a function to call if file fails to\n * load. This function will receive an error or\n * XMLHttpRequest object with information\n * about what went wrong.\n * @param {Function} [whileLoadingCallback] Name of a function to call while file\n * is loading. That function will\n * receive progress of the request to\n * load the sound file\n * (between 0 and 1) as its first\n * parameter. This progress\n * does not account for the additional\n * time needed to decode the audio data.\n *\n * @example\n *
\n */\n p5.SoundFile = function(paths, onload, onerror, whileLoading) {\n if (typeof paths !== 'undefined') {\n if (typeof paths === 'string' || typeof paths[0] === 'string') {\n var path = p5.prototype._checkFileFormats(paths);\n this.url = path;\n }\n else if(typeof paths === 'object') {\n if (!(window.File && window.FileReader && window.FileList && window.Blob)) {\n // The File API isn't supported in this browser\n throw 'Unable to load file because the File API is not supported';\n }\n }\n\n // if type is a p5.File...get the actual file\n if (paths.file) {\n paths = paths.file;\n }\n\n this.file = paths;\n }\n\n // private _onended callback, set by the method: onended(callback)\n this._onended = function() {};\n\n this._looping = false;\n this._playing = false;\n this._paused = false;\n this._pauseTime = 0;\n\n // cues for scheduling events with addCue() removeCue()\n this._cues = [];\n this._cueIDCounter = 0;\n\n // position of the most recently played sample\n this._lastPos = 0;\n this._counterNode = null;\n this._workletNode = null;\n\n // array of sources so that they can all be stopped!\n this.bufferSourceNodes = [];\n\n // current source\n this.bufferSourceNode = null;\n\n this.buffer = null;\n this.playbackRate = 1;\n\n this.input = p5sound.audiocontext.createGain();\n this.output = p5sound.audiocontext.createGain();\n\n this.reversed = false;\n\n // start and end of playback / loop\n this.startTime = 0;\n this.endTime = null;\n this.pauseTime = 0;\n\n // \"restart\" would stop playback before retriggering\n this.mode = 'sustain';\n\n // time that playback was started, in millis\n this.startMillis = null;\n\n // stereo panning\n this.panPosition = 0.0;\n this.panner = new p5.Panner(this.output, p5sound.input, 2);\n\n // it is possible to instantiate a soundfile with no path\n if (this.url || this.file) {\n this.load(onload, onerror);\n }\n\n // add this p5.SoundFile to the soundArray\n p5sound.soundArray.push(this);\n\n if (typeof whileLoading === 'function') {\n this._whileLoading = whileLoading;\n } else {\n this._whileLoading = function() {};\n }\n\n this._clearOnEnd = _clearOnEnd.bind(this);\n };\n\n // register preload handling of loadSound\n p5.prototype.registerPreloadMethod('loadSound', p5.prototype);\n\n /**\n * loadSound() returns a new p5.SoundFile from a specified\n * path. If called during preload(), the p5.SoundFile will be ready\n * to play in time for setup() and draw(). If called outside of\n * preload, the p5.SoundFile will not be ready immediately, so\n * loadSound accepts a callback as the second parameter. Using a\n * \n * local server is recommended when loading external files.\n *\n * @method loadSound\n * @for p5\n * @param {String|Array} path Path to the sound file, or an array with\n * paths to soundfiles in multiple formats\n * i.e. ['sound.ogg', 'sound.mp3'].\n * Alternately, accepts an object: either\n * from the HTML5 File API, or a p5.File.\n * @param {Function} [successCallback] Name of a function to call once file loads\n * @param {Function} [errorCallback] Name of a function to call if there is\n * an error loading the file.\n * @param {Function} [whileLoading] Name of a function to call while file is loading.\n * This function will receive the percentage loaded\n * so far, from 0.0 to 1.0.\n * @return {SoundFile} Returns a p5.SoundFile\n * @example\n *
\n */\n p5.prototype.loadSound = function(path, callback, onerror, whileLoading) {\n // if loading locally without a server\n if (window.location.origin.indexOf('file://') > -1 && window.cordova === 'undefined' ) {\n window.alert('This sketch may require a server to load external files. Please see http://bit.ly/1qcInwS');\n }\n\n var self = this;\n var s = new p5.SoundFile(path, function() {\n if(typeof callback === 'function') {\n callback.apply(self, arguments);\n }\n\n if (typeof self._decrementPreload === 'function') {\n self._decrementPreload();\n }\n }, onerror, whileLoading);\n\n return s;\n };\n\n /**\n * This is a helper function that the p5.SoundFile calls to load\n * itself. Accepts a callback (the name of another function)\n * as an optional parameter.\n *\n * @private\n * @for p5.SoundFile\n * @param {Function} [successCallback] Name of a function to call once file loads\n * @param {Function} [errorCallback] Name of a function to call if there is an error\n */\n p5.SoundFile.prototype.load = function(callback, errorCallback) {\n var self = this;\n var errorTrace = new Error().stack;\n\n if (this.url !== undefined && this.url !== '') {\n var request = new XMLHttpRequest();\n request.addEventListener('progress', function(evt) {\n self._updateProgress(evt);\n }, false);\n request.open('GET', this.url, true);\n request.responseType = 'arraybuffer';\n\n request.onload = function() {\n if (request.status === 200) {\n // on sucess loading file:\n if (!self.panner) return;\n ac.decodeAudioData(request.response,\n // success decoding buffer:\n function(buff) {\n if (!self.panner) return;\n self.buffer = buff;\n self.panner.inputChannels(buff.numberOfChannels);\n if (callback) {\n callback(self);\n }\n },\n // error decoding buffer. \"e\" is undefined in Chrome 11/22/2015\n function() {\n if (!self.panner) return;\n var err = new CustomError('decodeAudioData', errorTrace, self.url);\n var msg = 'AudioContext error at decodeAudioData for ' + self.url;\n if (errorCallback) {\n err.msg = msg;\n errorCallback(err);\n } else {\n console.error(msg +'\\n The error stack trace includes: \\n' + err.stack);\n }\n }\n );\n }\n // if request status != 200, it failed\n else {\n if (!self.panner) return;\n var err = new CustomError('loadSound', errorTrace, self.url);\n var msg = 'Unable to load ' + self.url + '. The request status was: ' +\n request.status + ' (' + request.statusText + ')';\n\n if (errorCallback) {\n err.message = msg;\n errorCallback(err);\n } else {\n console.error(msg +'\\n The error stack trace includes: \\n' + err.stack);\n }\n }\n };\n\n // if there is another error, aside from 404...\n request.onerror = function() {\n var err = new CustomError('loadSound', errorTrace, self.url);\n var msg = 'There was no response from the server at ' + self.url + '. Check the url and internet connectivity.';\n\n if (errorCallback) {\n err.message = msg;\n errorCallback(err);\n } else {\n console.error(msg +'\\n The error stack trace includes: \\n' + err.stack);\n }\n };\n\n request.send();\n }\n else if (this.file !== undefined) {\n var reader = new FileReader();\n reader.onload = function() {\n if (!self.panner) return;\n ac.decodeAudioData(reader.result, function(buff) {\n if (!self.panner) return;\n self.buffer = buff;\n self.panner.inputChannels(buff.numberOfChannels);\n if (callback) {\n callback(self);\n }\n });\n };\n reader.onerror = function(e) {\n if (!self.panner) return;\n if (onerror) {\n onerror(e);\n }\n };\n reader.readAsArrayBuffer(this.file);\n }\n };\n\n // TO DO: use this method to create a loading bar that shows progress during file upload/decode.\n p5.SoundFile.prototype._updateProgress = function(evt) {\n if (evt.lengthComputable) {\n var percentComplete = evt.loaded / evt.total * 0.99;\n this._whileLoading(percentComplete, evt);\n // ...\n } else {\n // Unable to compute progress information since the total size is unknown\n this._whileLoading('size unknown');\n }\n };\n\n /**\n * Returns true if the sound file finished loading successfully.\n *\n * @method isLoaded\n * @for p5.SoundFile\n * @return {Boolean}\n */\n p5.SoundFile.prototype.isLoaded = function() {\n if (this.buffer) {\n return true;\n } else {\n return false;\n }\n };\n\n /**\n * Play the p5.SoundFile\n *\n * @method play\n * @for p5.SoundFile\n * @param {Number} [startTime] (optional) schedule playback to start (in seconds from now).\n * @param {Number} [rate] (optional) playback rate\n * @param {Number} [amp] (optional) amplitude (volume)\n * of playback\n * @param {Number} [cueStart] (optional) cue start time in seconds\n * @param {Number} [duration] (optional) duration of playback in seconds\n */\n p5.SoundFile.prototype.play = function(startTime, rate, amp, _cueStart, duration) {\n if (!this.output) {\n console.warn('SoundFile.play() called after dispose');\n return;\n }\n\n var now = p5sound.audiocontext.currentTime;\n var cueStart, cueEnd;\n var time = startTime || 0;\n if (time < 0) {\n time = 0;\n }\n\n time = time + now;\n\n if (typeof rate !== 'undefined') {\n this.rate(rate);\n }\n\n if (typeof amp !== 'undefined') {\n this.setVolume(amp);\n }\n\n // TO DO: if already playing, create array of buffers for easy stop()\n if (this.buffer) {\n\n // reset the pause time (if it was paused)\n this._pauseTime = 0;\n\n // handle restart playmode\n if (this.mode === 'restart' && this.buffer && this.bufferSourceNode) {\n this.bufferSourceNode.stop(time);\n this._counterNode.stop(time);\n }\n\n //dont create another instance if already playing\n if (this.mode === 'untildone' && this.isPlaying()) {\n return;\n }\n // make a new source and counter. They are automatically assigned playbackRate and buffer\n this.bufferSourceNode = this._initSourceNode();\n\n // garbage collect counterNode and create a new one\n delete this._counterNode;\n this._counterNode = this._initCounterNode();\n\n if (_cueStart) {\n if (_cueStart >=0 && _cueStart < this.buffer.duration) {\n // this.startTime = cueStart;\n cueStart = _cueStart;\n } else { throw 'start time out of range'; }\n } else {\n cueStart = 0;\n }\n\n if (duration) {\n // if duration is greater than buffer.duration, just play entire file anyway rather than throw an error\n duration = duration <= this.buffer.duration - cueStart ? duration : this.buffer.duration;\n }\n\n // if it was paused, play at the pause position\n if (this._paused) {\n this.bufferSourceNode.start(time, this.pauseTime, duration);\n this._counterNode.start(time, this.pauseTime, duration);\n } else {\n this.bufferSourceNode.start(time, cueStart, duration);\n this._counterNode.start(time, cueStart, duration);\n }\n\n this._playing = true;\n this._paused = false;\n\n // add source to sources array, which is used in stopAll()\n this.bufferSourceNodes.push(this.bufferSourceNode);\n this.bufferSourceNode._arrayIndex = this.bufferSourceNodes.length - 1;\n\n this.bufferSourceNode.addEventListener('ended', this._clearOnEnd);\n }\n // If soundFile hasn't loaded the buffer yet, throw an error\n else {\n throw 'not ready to play file, buffer has yet to load. Try preload()';\n }\n\n // if looping, will restart at original time\n this.bufferSourceNode.loop = this._looping;\n this._counterNode.loop = this._looping;\n\n if (this._looping === true) {\n cueEnd = duration ? duration : cueStart - 0.000000000000001;\n this.bufferSourceNode.loopStart = cueStart;\n this.bufferSourceNode.loopEnd = cueEnd;\n this._counterNode.loopStart = cueStart;\n this._counterNode.loopEnd = cueEnd;\n }\n\n this._workletNode.port.postMessage({ name: 'play' });\n };\n\n\n /**\n * p5.SoundFile has two play modes: restart and\n * sustain. Play Mode determines what happens to a\n * p5.SoundFile if it is triggered while in the middle of playback.\n * In sustain mode, playback will continue simultaneous to the\n * new playback. In restart mode, play() will stop playback\n * and start over. With untilDone, a sound will play only if it's\n * not already playing. Sustain is the default mode.\n *\n * @method playMode\n * @for p5.SoundFile\n * @param {String} str 'restart' or 'sustain' or 'untilDone'\n * @example\n *
\n * var mySound;\n * function preload(){\n * mySound = loadSound('assets/Damscray_DancingTiger.mp3');\n * }\n * function mouseClicked() {\n * mySound.playMode('sustain');\n * mySound.play();\n * }\n * function keyPressed() {\n * mySound.playMode('restart');\n * mySound.play();\n * }\n *\n *
\n */\n p5.SoundFile.prototype.playMode = function(str) {\n var s = str.toLowerCase();\n\n // if restart, stop all other sounds from playing\n if (s === 'restart' && this.buffer && this.bufferSourceNode) {\n for (var i = 0; i < this.bufferSourceNodes.length - 1; i++) {\n var now = p5sound.audiocontext.currentTime;\n this.bufferSourceNodes[i].stop(now);\n }\n }\n\n // set play mode to effect future playback\n if (s === 'restart' || s === 'sustain' || s === 'untildone') {\n this.mode = s;\n } else {\n throw 'Invalid play mode. Must be either \"restart\" or \"sustain\"';\n }\n };\n\n /**\n * Pauses a file that is currently playing. If the file is not\n * playing, then nothing will happen.\n *\n * After pausing, .play() will resume from the paused\n * position.\n * If p5.SoundFile had been set to loop before it was paused,\n * it will continue to loop after it is unpaused with .play().\n *\n * @method pause\n * @for p5.SoundFile\n * @param {Number} [startTime] (optional) schedule event to occur\n * seconds from now\n * @example\n *
\n */\n p5.SoundFile.prototype.pause = function(startTime) {\n var now = p5sound.audiocontext.currentTime;\n var time = startTime || 0;\n var pTime = time + now;\n\n if (this.isPlaying() && this.buffer && this.bufferSourceNode) {\n this._workletNode.port.postMessage({ name: 'pause' });\n\n this.pauseTime = this.currentTime();\n this.bufferSourceNode.stop(pTime);\n this._counterNode.stop(pTime);\n this._paused = true;\n this._playing = false;\n\n this._pauseTime = this.currentTime();\n // TO DO: make sure play() still starts from orig start position\n } else {\n this._pauseTime = 0;\n }\n };\n\n /**\n * Loop the p5.SoundFile. Accepts optional parameters to set the\n * playback rate, playback volume, loopStart, loopEnd.\n *\n * @method loop\n * @for p5.SoundFile\n * @param {Number} [startTime] (optional) schedule event to occur\n * seconds from now\n * @param {Number} [rate] (optional) playback rate\n * @param {Number} [amp] (optional) playback volume\n * @param {Number} [cueLoopStart] (optional) startTime in seconds\n * @param {Number} [duration] (optional) loop duration in seconds\n */\n p5.SoundFile.prototype.loop = function(startTime, rate, amp, loopStart, duration) {\n this._looping = true;\n this.play(startTime, rate, amp, loopStart, duration);\n };\n\n /**\n * Set a p5.SoundFile's looping flag to true or false. If the sound\n * is currently playing, this change will take effect when it\n * reaches the end of the current playback.\n *\n * @method setLoop\n * @for p5.SoundFile\n * @param {Boolean} Boolean set looping to true or false\n */\n p5.SoundFile.prototype.setLoop = function(bool) {\n if (bool === true) {\n this._looping = true;\n }\n else if (bool === false) {\n this._looping = false;\n }\n else {\n throw 'Error: setLoop accepts either true or false';\n }\n if (this.bufferSourceNode) {\n this.bufferSourceNode.loop = this._looping;\n this._counterNode.loop = this._looping;\n }\n };\n\n /**\n * Returns 'true' if a p5.SoundFile is currently looping and playing, 'false' if not.\n *\n * @method isLooping\n * @for p5.SoundFile\n * @return {Boolean}\n */\n p5.SoundFile.prototype.isLooping = function() {\n if (!this.bufferSourceNode) {\n return false;\n }\n if (this._looping === true && this.isPlaying() === true) {\n return true;\n }\n return false;\n };\n\n /**\n * Returns true if a p5.SoundFile is playing, false if not (i.e.\n * paused or stopped).\n *\n * @method isPlaying\n * @for p5.SoundFile\n * @return {Boolean}\n */\n p5.SoundFile.prototype.isPlaying = function() {\n return this._playing;\n };\n\n /**\n * Returns true if a p5.SoundFile is paused, false if not (i.e.\n * playing or stopped).\n *\n * @method isPaused\n * @for p5.SoundFile\n * @return {Boolean}\n */\n p5.SoundFile.prototype.isPaused = function() {\n return this._paused;\n };\n\n /**\n * Stop soundfile playback.\n *\n * @method stop\n * @for p5.SoundFile\n * @param {Number} [startTime] (optional) schedule event to occur\n * in seconds from now\n */\n p5.SoundFile.prototype.stop = function(timeFromNow) {\n var time = timeFromNow || 0;\n\n if (this.mode === 'sustain' || this.mode === 'untildone') {\n this.stopAll(time);\n this._playing = false;\n this.pauseTime = 0;\n this._paused = false;\n }\n else if (this.buffer && this.bufferSourceNode) {\n var now = p5sound.audiocontext.currentTime;\n var t = time || 0;\n this.pauseTime = 0;\n this.bufferSourceNode.stop(now + t);\n this._counterNode.stop(now + t);\n this._playing = false;\n this._paused = false;\n }\n };\n\n /**\n * Stop playback on all of this soundfile's sources.\n * @private\n */\n p5.SoundFile.prototype.stopAll = function(_time) {\n var now = p5sound.audiocontext.currentTime;\n var time = _time || 0;\n if (this.buffer && this.bufferSourceNode) {\n for (var i in this.bufferSourceNodes) {\n const bufferSourceNode = this.bufferSourceNodes[i];\n if (!!bufferSourceNode) {\n try {\n bufferSourceNode.stop(now + time);\n } catch(e) {\n // this was throwing errors only on Safari\n }\n }\n }\n this._counterNode.stop(now + time);\n this._onended(this);\n }\n };\n\n /**\n * Multiply the output volume (amplitude) of a sound file\n * between 0.0 (silence) and 1.0 (full volume).\n * 1.0 is the maximum amplitude of a digital sound, so multiplying\n * by greater than 1.0 may cause digital distortion. To\n * fade, provide a rampTime parameter. For more\n * complex fades, see the Envelope class.\n *\n * Alternately, you can pass in a signal source such as an\n * oscillator to modulate the amplitude with an audio signal.\n *\n * @method setVolume\n * @for p5.SoundFile\n * @param {Number|Object} volume Volume (amplitude) between 0.0\n * and 1.0 or modulating signal/oscillator\n * @param {Number} [rampTime] Fade for t seconds\n * @param {Number} [timeFromNow] Schedule this event to happen at\n * t seconds in the future\n */\n p5.SoundFile.prototype.setVolume = function(vol, _rampTime, _tFromNow) {\n if (typeof vol === 'number') {\n var rampTime = _rampTime || 0;\n var tFromNow = _tFromNow || 0;\n var now = p5sound.audiocontext.currentTime;\n var currentVol = this.output.gain.value;\n this.output.gain.cancelScheduledValues(now + tFromNow);\n this.output.gain.linearRampToValueAtTime(currentVol, now + tFromNow);\n this.output.gain.linearRampToValueAtTime(vol, now + tFromNow + rampTime);\n }\n else if (vol) {\n vol.connect(this.output.gain);\n } else {\n // return the Gain Node\n return this.output.gain;\n }\n };\n\n // same as setVolume, to match Processing Sound\n p5.SoundFile.prototype.amp = p5.SoundFile.prototype.setVolume;\n\n // these are the same thing\n p5.SoundFile.prototype.fade = p5.SoundFile.prototype.setVolume;\n\n p5.SoundFile.prototype.getVolume = function() {\n return this.output.gain.value;\n };\n\n /**\n * Set the stereo panning of a p5.sound object to\n * a floating point number between -1.0 (left) and 1.0 (right).\n * Default is 0.0 (center).\n *\n * @method pan\n * @for p5.SoundFile\n * @param {Number} [panValue] Set the stereo panner\n * @param {Number} [timeFromNow] schedule this event to happen\n * seconds from now\n * @example\n *
\n *\n * var ball = {};\n * var soundFile;\n *\n * function preload() {\n * soundFormats('ogg', 'mp3');\n * soundFile = loadSound('assets/beatbox.mp3');\n * }\n *\n * function draw() {\n * background(0);\n * ball.x = constrain(mouseX, 0, width);\n * ellipse(ball.x, height/2, 20, 20)\n * }\n *\n * function mousePressed(){\n * // map the ball's x location to a panning degree\n * // between -1.0 (left) and 1.0 (right)\n * var panning = map(ball.x, 0., width,-1.0, 1.0);\n * soundFile.pan(panning);\n * soundFile.play();\n * }\n *
\n */\n p5.SoundFile.prototype.pan = function(pval, tFromNow) {\n this.panPosition = pval;\n this.panner.pan(pval, tFromNow);\n };\n\n /**\n * Returns the current stereo pan position (-1.0 to 1.0)\n *\n * @method getPan\n * @for p5.SoundFile\n * @return {Number} Returns the stereo pan setting of the Oscillator\n * as a number between -1.0 (left) and 1.0 (right).\n * 0.0 is center and default.\n */\n p5.SoundFile.prototype.getPan = function() {\n return this.panPosition;\n };\n\n /**\n * Set the playback rate of a sound file. Will change the speed and the pitch.\n * Values less than zero will reverse the audio buffer.\n *\n * @method rate\n * @for p5.SoundFile\n * @param {Number} [playbackRate] Set the playback rate. 1.0 is normal,\n * .5 is half-speed, 2.0 is twice as fast.\n * Values less than zero play backwards.\n * @example\n *
\n * var song;\n *\n * function preload() {\n * song = loadSound('assets/Damscray_DancingTiger.mp3');\n * }\n *\n * function setup() {\n * song.loop();\n * }\n *\n * function draw() {\n * background(200);\n *\n * // Set the rate to a range between 0.1 and 4\n * // Changing the rate also alters the pitch\n * var speed = map(mouseY, 0.1, height, 0, 2);\n * speed = constrain(speed, 0.01, 4);\n * song.rate(speed);\n *\n * // Draw a circle to show what is going on\n * stroke(0);\n * fill(51, 100);\n * ellipse(mouseX, 100, 48, 48);\n * }\n *\n * \n *
\n *\n */\n p5.SoundFile.prototype.rate = function(playbackRate) {\n var reverse = false;\n if (typeof playbackRate === 'undefined') {\n return this.playbackRate;\n }\n\n this.playbackRate = playbackRate;\n\n if (playbackRate === 0) {\n playbackRate = 0.0000000000001;\n }\n\n else if (playbackRate < 0 && !this.reversed) {\n playbackRate = Math.abs(playbackRate);\n reverse = true;\n }\n\n else if (playbackRate > 0 && this.reversed) {\n reverse = true;\n }\n\n if (this.bufferSourceNode) {\n var now = p5sound.audiocontext.currentTime;\n this.bufferSourceNode.playbackRate.cancelScheduledValues(now);\n this.bufferSourceNode.playbackRate.linearRampToValueAtTime(Math.abs(playbackRate), now);\n this._counterNode.playbackRate.cancelScheduledValues(now);\n this._counterNode.playbackRate.linearRampToValueAtTime(Math.abs(playbackRate), now);\n }\n\n if (reverse) {\n this.reverseBuffer();\n }\n return this.playbackRate;\n };\n\n // TO DO: document this\n p5.SoundFile.prototype.setPitch = function(num) {\n var newPlaybackRate = midiToFreq(num) / midiToFreq(60);\n this.rate(newPlaybackRate);\n };\n\n p5.SoundFile.prototype.getPlaybackRate = function() {\n return this.playbackRate;\n };\n\n /**\n * Returns the duration of a sound file in seconds.\n *\n * @method duration\n * @for p5.SoundFile\n * @return {Number} The duration of the soundFile in seconds.\n */\n p5.SoundFile.prototype.duration = function() {\n // Return Duration\n if (this.buffer) {\n return this.buffer.duration;\n } else {\n return 0;\n }\n };\n\n /**\n * Return the current position of the p5.SoundFile playhead, in seconds.\n * Time is relative to the normal buffer direction, so if `reverseBuffer`\n * has been called, currentTime will count backwards.\n *\n * @method currentTime\n * @for p5.SoundFile\n * @return {Number} currentTime of the soundFile in seconds.\n */\n p5.SoundFile.prototype.currentTime = function() {\n return this.reversed\n ? Math.abs(this._lastPos - this.buffer.length) / ac.sampleRate\n : this._lastPos / ac.sampleRate;\n };\n\n /**\n * Move the playhead of the song to a position, in seconds. Start timing\n * and playback duration. If none are given, will reset the file to play\n * entire duration from start to finish.\n *\n * @method jump\n * @for p5.SoundFile\n * @param {Number} cueTime cueTime of the soundFile in seconds.\n * @param {Number} duration duration in seconds.\n */\n p5.SoundFile.prototype.jump = function(cueTime, duration) {\n if (cueTime < 0 || cueTime > this.buffer.duration) {\n throw 'jump time out of range';\n }\n if (duration > this.buffer.duration - cueTime) {\n throw 'end time out of range';\n }\n\n var cTime = cueTime || 0;\n var dur = duration || undefined;\n if (this.isPlaying()) {\n this.stop(0);\n }\n this.play(0, this.playbackRate, this.output.gain.value, cTime, dur);\n };\n\n /**\n * Return the number of channels in a sound file.\n * For example, Mono = 1, Stereo = 2.\n *\n * @method channels\n * @for p5.SoundFile\n * @return {Number} [channels]\n */\n p5.SoundFile.prototype.channels = function() {\n return this.buffer.numberOfChannels;\n };\n\n /**\n * Return the sample rate of the sound file.\n *\n * @method sampleRate\n * @for p5.SoundFile\n * @return {Number} [sampleRate]\n */\n p5.SoundFile.prototype.sampleRate = function() {\n return this.buffer.sampleRate;\n };\n\n /**\n * Return the number of samples in a sound file.\n * Equal to sampleRate * duration.\n *\n * @method frames\n * @for p5.SoundFile\n * @return {Number} [sampleCount]\n */\n p5.SoundFile.prototype.frames = function() {\n return this.buffer.length;\n };\n\n /**\n * Returns an array of amplitude peaks in a p5.SoundFile that can be\n * used to draw a static waveform. Scans through the p5.SoundFile's\n * audio buffer to find the greatest amplitudes. Accepts one\n * parameter, 'length', which determines size of the array.\n * Larger arrays result in more precise waveform visualizations.\n *\n * Inspired by Wavesurfer.js.\n *\n * @method getPeaks\n * @for p5.SoundFile\n * @params {Number} [length] length is the size of the returned array.\n * Larger length results in more precision.\n * Defaults to 5*width of the browser window.\n * @returns {Float32Array} Array of peaks.\n */\n p5.SoundFile.prototype.getPeaks = function(length) {\n\n if (this.buffer) {\n // set length to window's width if no length is provided\n if (!length) {\n length = window.width*5;\n }\n if (this.buffer) {\n var buffer = this.buffer;\n var sampleSize = buffer.length / length;\n var sampleStep = ~~(sampleSize / 10) || 1;\n var channels = buffer.numberOfChannels;\n var peaks = new Float32Array(Math.round(length));\n\n for (var c = 0; c < channels; c++) {\n var chan = buffer.getChannelData(c);\n for (var i = 0; i < length; i++) {\n var start = ~~(i*sampleSize);\n var end = ~~(start + sampleSize);\n var max = 0;\n for (var j = start; j < end; j+= sampleStep) {\n var value = chan[j];\n if (value > max) {\n max = value;\n // faster than Math.abs\n } else if (-value > max) {\n max = value;\n }\n }\n if (c === 0 || Math.abs(max) > peaks[i]) {\n peaks[i] = max;\n }\n }\n }\n\n return peaks;\n }\n }\n\n else {\n throw 'Cannot load peaks yet, buffer is not loaded';\n }\n };\n\n /**\n * Reverses the p5.SoundFile's buffer source.\n * Playback must be handled separately (see example).\n *\n * @method reverseBuffer\n * @for p5.SoundFile\n * @example\n *
\n * var drum;\n *\n * function preload() {\n * drum = loadSound('assets/drum.mp3');\n * }\n *\n * function setup() {\n * drum.reverseBuffer();\n * drum.play();\n * }\n *\n * \n *
\n */\n p5.SoundFile.prototype.reverseBuffer = function() {\n if (this.buffer) {\n var currentPos = this._lastPos / ac.sampleRate;\n var curVol = this.getVolume();\n this.setVolume(0, 0.001);\n\n const numChannels = this.buffer.numberOfChannels;\n for (var i = 0; i < numChannels; i++) {\n this.buffer.getChannelData(i).reverse();\n }\n // set reversed flag\n this.reversed = !this.reversed;\n\n if (currentPos) {\n this.jump(this.duration() - currentPos);\n }\n this.setVolume(curVol, 0.001);\n } else {\n throw 'SoundFile is not done loading';\n }\n };\n\n /**\n * Schedule an event to be called when the soundfile\n * reaches the end of a buffer. If the soundfile is\n * playing through once, this will be called when it\n * ends. If it is looping, it will be called when\n * stop is called.\n *\n * @method onended\n * @for p5.SoundFile\n * @param {Function} callback function to call when the\n * soundfile has ended.\n */\n p5.SoundFile.prototype.onended = function(callback) {\n this._onended = callback;\n return this;\n };\n\n p5.SoundFile.prototype.add = function() {\n // TO DO\n };\n\n p5.SoundFile.prototype.dispose = function() {\n var now = p5sound.audiocontext.currentTime;\n\n // remove reference to soundfile\n var index = p5sound.soundArray.indexOf(this);\n p5sound.soundArray.splice(index, 1);\n\n this.stop(now);\n if (this.buffer && this.bufferSourceNode) {\n for (var i = 0; i < this.bufferSourceNodes.length - 1; i++) {\n if (this.bufferSourceNodes[i] !== null) {\n this.bufferSourceNodes[i].disconnect();\n try {\n this.bufferSourceNodes[i].stop(now);\n } catch(e) {\n console.warning('no buffer source node to dispose');\n }\n this.bufferSourceNodes[i] = null;\n }\n }\n if ( this.isPlaying() ) {\n try {\n this._counterNode.stop(now);\n } catch(e) {\n console.log(e);\n }\n this._counterNode = null;\n }\n }\n if (this.output) {\n this.output.disconnect();\n this.output = null;\n }\n if (this.panner) {\n this.panner.disconnect();\n this.panner = null;\n }\n };\n\n /**\n * Connects the output of a p5sound object to input of another\n * p5.sound object. For example, you may connect a p5.SoundFile to an\n * FFT or an Effect. If no parameter is given, it will connect to\n * the master output. Most p5sound objects connect to the master\n * output when they are created.\n *\n * @method connect\n * @for p5.SoundFile\n * @param {Object} [object] Audio object that accepts an input\n */\n p5.SoundFile.prototype.connect = function(unit) {\n if (!unit) {\n this.panner.connect(p5sound.input);\n }\n else {\n if (unit.hasOwnProperty('input')) {\n this.panner.connect(unit.input);\n } else {\n this.panner.connect(unit);\n }\n }\n };\n\n /**\n * Disconnects the output of this p5sound object.\n *\n * @method disconnect\n * @for p5.SoundFile\n */\n p5.SoundFile.prototype.disconnect = function() {\n if (this.panner) {\n this.panner.disconnect();\n }\n };\n\n /**\n */\n p5.SoundFile.prototype.getLevel = function() {\n console.warn('p5.SoundFile.getLevel has been removed from the library. Use p5.Amplitude instead');\n };\n\n /**\n * Reset the source for this SoundFile to a\n * new path (URL).\n *\n * @method setPath\n * @for p5.SoundFile\n * @param {String} path path to audio file\n * @param {Function} callback Callback\n */\n p5.SoundFile.prototype.setPath = function(p, callback) {\n var path = p5.prototype._checkFileFormats(p);\n this.url = path;\n this.load(callback);\n };\n\n /**\n * Replace the current Audio Buffer with a new Buffer.\n *\n * @method setBuffer\n * @for p5.SoundFile\n * @param {Array} buf Array of Float32 Array(s). 2 Float32 Arrays\n * will create a stereo source. 1 will create\n * a mono source.\n */\n p5.SoundFile.prototype.setBuffer = function(buf) {\n var numChannels = buf.length;\n var size = buf[0].length;\n var newBuffer = ac.createBuffer(numChannels, size, ac.sampleRate);\n\n if (!(buf[0] instanceof Float32Array)) {\n buf[0] = new Float32Array(buf[0]);\n }\n\n for (var channelNum = 0; channelNum < numChannels; channelNum++) {\n var channel = newBuffer.getChannelData( channelNum );\n channel.set(buf[channelNum]);\n }\n\n this.buffer = newBuffer;\n\n // set numbers of channels on input to the panner\n this.panner.inputChannels(numChannels);\n };\n\n //////////////////////////////////////////////////\n // script processor node with an empty buffer to help\n // keep a sample-accurate position in playback buffer.\n // Inspired by Chinmay Pendharkar's technique for Sonoport --> http://bit.ly/1HwdCsV\n // Copyright [2015] [Sonoport (Asia) Pte. Ltd.],\n // Licensed under the Apache License http://apache.org/licenses/LICENSE-2.0\n ////////////////////////////////////////////////////////////////////////////////////\n\n var _createCounterBuffer = function(buffer) {\n const len = buffer.length;\n const audioBuf = ac.createBuffer( 1, buffer.length, ac.sampleRate );\n const arrayBuffer = audioBuf.getChannelData(0);\n for (var index = 0; index < len; index++) {\n arrayBuffer[index] = index;\n }\n return audioBuf;\n };\n\n // initialize counterNode, set its initial buffer and playbackRate\n p5.SoundFile.prototype._initCounterNode = function() {\n var self = this;\n var now = ac.currentTime;\n var cNode = ac.createBufferSource();\n\n // dispose of worklet node if it already exists\n if (self._workletNode) {\n self._workletNode.disconnect();\n delete self._workletNode;\n }\n self._workletNode = new AudioWorkletNode(ac, processorNames.soundFileProcessor);\n self._workletNode.port.onmessage = function(event) {\n if (event.data.name === 'position') {\n this._lastPos = event.data.position;\n\n // do any callbacks that have been scheduled\n this._onTimeUpdate(self._lastPos);\n }\n }.bind(self);\n\n // create counter buffer of the same length as self.buffer\n cNode.buffer = _createCounterBuffer( self.buffer );\n\n cNode.playbackRate.setValueAtTime(self.playbackRate, now);\n\n cNode.connect(self._workletNode);\n self._workletNode.connect(p5.soundOut._silentNode);\n\n return cNode;\n };\n\n // initialize sourceNode, set its initial buffer and playbackRate\n p5.SoundFile.prototype._initSourceNode = function() {\n var bufferSourceNode = ac.createBufferSource();\n bufferSourceNode.buffer = this.buffer;\n bufferSourceNode.playbackRate.value = this.playbackRate;\n bufferSourceNode.connect(this.output);\n return bufferSourceNode;\n };\n\n /**\n * processPeaks returns an array of timestamps where it thinks there is a beat.\n *\n * This is an asynchronous function that processes the soundfile in an offline audio context,\n * and sends the results to your callback function.\n *\n * The process involves running the soundfile through a lowpass filter, and finding all of the\n * peaks above the initial threshold. If the total number of peaks are below the minimum number of peaks,\n * it decreases the threshold and re-runs the analysis until either minPeaks or minThreshold are reached.\n *\n * @method processPeaks\n * @for p5.SoundFile\n * @param {Function} callback a function to call once this data is returned\n * @param {Number} [initThreshold] initial threshold defaults to 0.9\n * @param {Number} [minThreshold] minimum threshold defaults to 0.22\n * @param {Number} [minPeaks] minimum number of peaks defaults to 200\n * @return {Array} Array of timestamped peaks\n */\n p5.SoundFile.prototype.processPeaks = function(callback, _initThreshold, _minThreshold, _minPeaks) {\n var bufLen = this.buffer.length;\n var sampleRate = this.buffer.sampleRate;\n var buffer = this.buffer;\n var allPeaks = [];\n\n var initialThreshold = _initThreshold || 0.9,\n threshold = initialThreshold,\n minThreshold = _minThreshold || 0.22,\n minPeaks = _minPeaks || 200;\n\n // Create offline context\n var offlineContext = new window.OfflineAudioContext(1, bufLen, sampleRate);\n\n // create buffer source\n var source = offlineContext.createBufferSource();\n source.buffer = buffer;\n\n // Create filter. TO DO: allow custom setting of filter\n var filter = offlineContext.createBiquadFilter();\n filter.type = 'lowpass';\n source.connect(filter);\n filter.connect(offlineContext.destination);\n\n // start playing at time:0\n source.start(0);\n offlineContext.startRendering(); // Render the song\n\n // act on the result\n offlineContext.oncomplete = function(e) {\n if (!self.panner) return;\n var filteredBuffer = e.renderedBuffer;\n var bufferData = filteredBuffer.getChannelData(0);\n\n\n // step 1:\n // create Peak instances, add them to array, with strength and sampleIndex\n do {\n allPeaks = getPeaksAtThreshold(bufferData, threshold);\n threshold -= 0.005;\n } while (Object.keys(allPeaks).length < minPeaks && threshold >= minThreshold);\n\n\n // step 2:\n // find intervals for each peak in the sampleIndex, add tempos array\n var intervalCounts = countIntervalsBetweenNearbyPeaks(allPeaks);\n\n // step 3: find top tempos\n var groups = groupNeighborsByTempo(intervalCounts, filteredBuffer.sampleRate);\n\n // sort top intervals\n var topTempos = groups.sort(function(intA, intB) {\n return intB.count - intA.count;\n\n }).splice(0,5);\n\n // set this SoundFile's tempo to the top tempo ??\n this.tempo = topTempos[0].tempo;\n\n // step 4:\n // new array of peaks at top tempo within a bpmVariance\n var bpmVariance = 5;\n var tempoPeaks = getPeaksAtTopTempo(allPeaks, topTempos[0].tempo, filteredBuffer.sampleRate, bpmVariance);\n\n callback(tempoPeaks);\n };\n };\n\n // process peaks\n var Peak = function(amp, i) {\n this.sampleIndex = i;\n this.amplitude = amp;\n this.tempos = [];\n this.intervals = [];\n };\n\n // 1. for processPeaks() Function to identify peaks above a threshold\n // returns an array of peak indexes as frames (samples) of the original soundfile\n function getPeaksAtThreshold(data, threshold) {\n var peaksObj = {};\n var length = data.length;\n\n for (var i = 0; i < length; i++) {\n if (data[i] > threshold) {\n var amp = data[i];\n var peak = new Peak(amp, i);\n peaksObj[i] = peak;\n // Skip forward ~ 1/8s to get past this peak.\n i += 6000;\n }\n i++;\n }\n return peaksObj;\n }\n\n // 2. for processPeaks()\n function countIntervalsBetweenNearbyPeaks(peaksObj) {\n var intervalCounts = [];\n var peaksArray = Object.keys(peaksObj).sort();\n\n for (var index = 0; index < peaksArray.length; index++) {\n\n // find intervals in comparison to nearby peaks\n for (var i = 0; i < 10; i++) {\n var startPeak = peaksObj[peaksArray[index]];\n var endPeak = peaksObj[peaksArray[index + i]];\n\n if (startPeak && endPeak) {\n var startPos = startPeak.sampleIndex;\n var endPos = endPeak.sampleIndex;\n var interval = endPos - startPos;\n\n // add a sample interval to the startPeak in the allPeaks array\n if (interval > 0) {\n startPeak.intervals.push(interval);\n }\n\n // tally the intervals and return interval counts\n var foundInterval = intervalCounts.some(function(intervalCount) {\n if (intervalCount.interval === interval) {\n intervalCount.count++;\n return intervalCount;\n }\n });\n\n // store with JSON like formatting\n if (!foundInterval) {\n intervalCounts.push({\n interval: interval,\n count: 1,\n });\n }\n }\n }\n }\n\n return intervalCounts;\n }\n\n\n // 3. for processPeaks --> find tempo\n function groupNeighborsByTempo(intervalCounts, sampleRate) {\n var tempoCounts = [];\n\n intervalCounts.forEach(function(intervalCount) {\n\n try {\n // Convert an interval to tempo\n var theoreticalTempo = Math.abs( 60 / (intervalCount.interval / sampleRate ) );\n\n theoreticalTempo = mapTempo(theoreticalTempo);\n\n var foundTempo = tempoCounts.some(function(tempoCount) {\n if (tempoCount.tempo === theoreticalTempo)\n return tempoCount.count += intervalCount.count;\n });\n if (!foundTempo) {\n if (isNaN(theoreticalTempo)) {\n return;\n }\n tempoCounts.push({\n tempo: Math.round(theoreticalTempo),\n count: intervalCount.count\n });\n }\n } catch(e) {\n throw e;\n }\n\n });\n\n return tempoCounts;\n }\n\n // 4. for processPeaks - get peaks at top tempo\n function getPeaksAtTopTempo(peaksObj, tempo, sampleRate, bpmVariance) {\n var peaksAtTopTempo = [];\n var peaksArray = Object.keys(peaksObj).sort();\n\n // TO DO: filter out peaks that have the tempo and return\n for (var i = 0; i < peaksArray.length; i++) {\n var key = peaksArray[i];\n var peak = peaksObj[key];\n\n for (var j = 0; j < peak.intervals.length; j++) {\n var intervalBPM = Math.round(Math.abs( 60 / (peak.intervals[j] / sampleRate) ) );\n\n intervalBPM = mapTempo(intervalBPM);\n\n if ( Math.abs(intervalBPM - tempo) < bpmVariance ) {\n // convert sampleIndex to seconds\n peaksAtTopTempo.push(peak.sampleIndex/sampleRate);\n }\n }\n }\n\n // filter out peaks that are very close to each other\n peaksAtTopTempo = peaksAtTopTempo.filter(function(peakTime, index, arr) {\n var dif = arr[index + 1] - peakTime;\n if (dif > 0.01) {\n return true;\n }\n });\n\n return peaksAtTopTempo;\n }\n\n // helper function for processPeaks\n function mapTempo(theoreticalTempo) {\n // these scenarios create infinite while loop\n if (!isFinite(theoreticalTempo) || theoreticalTempo === 0 ) {\n return;\n }\n\n // Adjust the tempo to fit within the 90-180 BPM range\n while (theoreticalTempo < 90) theoreticalTempo *= 2;\n while (theoreticalTempo > 180 && theoreticalTempo > 90) theoreticalTempo /= 2;\n\n return theoreticalTempo;\n }\n\n\n /*** SCHEDULE EVENTS ***/\n\n // Cue inspired by JavaScript setTimeout, and the\n // Tone.js Transport Timeline Event, MIT License Yotam Mann 2015 tonejs.org\n var Cue = function(callback, time, id, val) {\n this.callback = callback;\n this.time = time;\n this.id = id;\n this.val = val;\n };\n\n /**\n * Schedule events to trigger every time a MediaElement\n * (audio/video) reaches a playback cue point.\n *\n * Accepts a callback function, a time (in seconds) at which to trigger\n * the callback, and an optional parameter for the callback.\n *\n * Time will be passed as the first parameter to the callback function,\n * and param will be the second parameter.\n *\n *\n * @method addCue\n * @for p5.SoundFile\n * @param {Number} time Time in seconds, relative to this media\n * element's playback. For example, to trigger\n * an event every time playback reaches two\n * seconds, pass in the number 2. This will be\n * passed as the first parameter to\n * the callback function.\n * @param {Function} callback Name of a function that will be\n * called at the given time. The callback will\n * receive time and (optionally) param as its\n * two parameters.\n * @param {Object} [value] An object to be passed as the\n * second parameter to the\n * callback function.\n * @return {Number} id ID of this cue,\n * useful for removeCue(id)\n * @example\n *
\n */\n p5.SoundFile.prototype.addCue = function(time, callback, val) {\n var id = this._cueIDCounter++;\n\n var cue = new Cue(callback, time, id, val);\n this._cues.push(cue);\n\n // if (!this.elt.ontimeupdate) {\n // this.elt.ontimeupdate = this._onTimeUpdate.bind(this);\n // }\n\n return id;\n };\n\n /**\n * Remove a callback based on its ID. The ID is returned by the\n * addCue method.\n *\n * @method removeCue\n * @for p5.SoundFile\n * @param {Number} id ID of the cue, as returned by addCue\n */\n p5.SoundFile.prototype.removeCue = function(id) {\n var cueLength = this._cues.length;\n for (var i = 0; i < cueLength; i++) {\n var cue = this._cues[i];\n if (cue.id === id) {\n this._cues.splice(i, 1);\n break;\n }\n }\n\n if (this._cues.length === 0) {\n // TO DO: remove callback\n // this.elt.ontimeupdate = null\n }\n };\n\n /**\n * Remove all of the callbacks that had originally been scheduled\n * via the addCue method.\n *\n * @method clearCues\n */\n p5.SoundFile.prototype.clearCues = function() {\n this._cues = [];\n // this.elt.ontimeupdate = null;\n };\n\n // private method that checks for cues to be fired if events\n // have been scheduled using addCue(callback, time).\n p5.SoundFile.prototype._onTimeUpdate = function(position) {\n var playbackTime = position/this.buffer.sampleRate;\n var cueLength = this._cues.length;\n\n for (var i = 0 ; i < cueLength; i++) {\n var cue = this._cues[i];\n var callbackTime = cue.time;\n var val = cue.val;\n\n if (this._prevTime < callbackTime && callbackTime <= playbackTime) {\n\n // pass the scheduled callbackTime as parameter to the callback\n cue.callback(val);\n }\n\n }\n\n this._prevTime = playbackTime;\n };\n\n /**\n * Save a p5.SoundFile as a .wav file. The browser will prompt the user\n * to download the file to their device. To upload a file to a server, see\n * getBlob\n *\n * @method save\n * @for p5.SoundFile\n * @param {String} [fileName] name of the resulting .wav file.\n * @example\n *
\n * var inp, button, mySound;\n * var fileName = 'cool';\n * function preload() {\n * mySound = loadSound('assets/doorbell.mp3');\n * }\n * function setup() {\n * btn = createButton('click to save file');\n * btn.position(0, 0);\n * btn.mouseClicked(handleMouseClick);\n * }\n *\n * function handleMouseClick() {\n * mySound.save(fileName);\n * }\n *
\n */\n p5.SoundFile.prototype.save = function(fileName) {\n const dataView = convertToWav(this.buffer);\n p5.prototype.saveSound([dataView], fileName, 'wav');\n };\n\n /**\n * This method is useful for sending a SoundFile to a server. It returns the\n * .wav-encoded audio data as a \"Blob\".\n * A Blob is a file-like data object that can be uploaded to a server\n * with an http request. We'll\n * use the `httpDo` options object to send a POST request with some\n * specific options: we encode the request as `multipart/form-data`,\n * and attach the blob as one of the form values using `FormData`.\n *\n *\n * @method getBlob\n * @for p5.SoundFile\n * @returns {Blob} A file-like data object\n * @example\n *
\n *\n * function preload() {\n * mySound = loadSound('assets/doorbell.mp3');\n * }\n *\n * function setup() {\n * noCanvas();\n * var soundBlob = mySound.getBlob();\n *\n * // Now we can send the blob to a server...\n * var serverUrl = 'https://jsonplaceholder.typicode.com/posts';\n * var httpRequestOptions = {\n * method: 'POST',\n * body: new FormData().append('soundBlob', soundBlob),\n * headers: new Headers({\n * 'Content-Type': 'multipart/form-data'\n * })\n * };\n * httpDo(serverUrl, httpRequestOptions);\n *\n * // We can also create an `ObjectURL` pointing to the Blob\n * var blobUrl = URL.createObjectURL(soundBlob);\n *\n * // The `
\n */\n p5.SoundFile.prototype.getBlob = function() {\n const dataView = convertToWav(this.buffer);\n return new Blob([dataView], { type: 'audio/wav' });\n };\n\n // event handler to remove references to the bufferSourceNode when it is done playing\n function _clearOnEnd(e) {\n const thisBufferSourceNode = e.target;\n const soundFile = this;\n\n // delete this.bufferSourceNode from the sources array when it is done playing:\n thisBufferSourceNode._playing = false;\n thisBufferSourceNode.removeEventListener('ended', soundFile._clearOnEnd);\n\n // call the onended callback\n soundFile._onended(soundFile);\n\n soundFile.bufferSourceNodes.forEach(function (n, i) {\n if (n._playing === false) {\n soundFile.bufferSourceNodes.splice(i);\n }\n });\n\n if (soundFile.bufferSourceNodes.length === 0) {\n soundFile._playing = false;\n }\n }\n});\n","'use strict';\n\ndefine(function (require) {\n var p5sound = require('master');\n var processorNames = require('./audioWorklet/processorNames');\n\n /**\n * Amplitude measures volume between 0.0 and 1.0.\n * Listens to all p5sound by default, or use setInput()\n * to listen to a specific sound source. Accepts an optional\n * smoothing value, which defaults to 0.\n *\n * @class p5.Amplitude\n * @constructor\n * @param {Number} [smoothing] between 0.0 and .999 to smooth\n * amplitude readings (defaults to 0)\n * @example\n *
\n * var sound, amplitude, cnv;\n *\n * function preload(){\n * sound = loadSound('assets/beat.mp3');\n * }\n * function setup() {\n * cnv = createCanvas(100,100);\n * amplitude = new p5.Amplitude();\n *\n * // start / stop the sound when canvas is clicked\n * cnv.mouseClicked(function() {\n * if (sound.isPlaying() ){\n * sound.stop();\n * } else {\n * sound.play();\n * }\n * });\n * }\n * function draw() {\n * background(0);\n * fill(255);\n * var level = amplitude.getLevel();\n * var size = map(level, 0, 1, 0, 200);\n * ellipse(width/2, height/2, size, size);\n * }\n *\n *
\n */\n p5.Amplitude = function(smoothing) {\n\n // Set to 2048 for now. In future iterations, this should be inherited or parsed from p5sound's default\n this.bufferSize = 2048;\n\n // set audio context\n this.audiocontext = p5sound.audiocontext;\n this._workletNode = new AudioWorkletNode(this.audiocontext, processorNames.amplitudeProcessor, {\n outputChannelCount: [1],\n processorOptions: {\n normalize: false,\n smoothing: smoothing || 0\n }\n });\n\n this._workletNode.port.onmessage = function(event) {\n if (event.data.name === 'amplitude') {\n this.volume = event.data.volume;\n this.volNorm = event.data.volNorm;\n this.stereoVol = event.data.stereoVol;\n this.stereoVolNorm = event.data.stereoVolNorm;\n }\n }.bind(this);\n\n // for connections\n this.input = this._workletNode;\n\n this.output = this.audiocontext.createGain();\n\n // the variables to return\n this.volume = 0;\n this.volNorm = 0;\n this.stereoVol = [0, 0];\n this.stereoVolNorm = [0, 0];\n\n this.normalize = false;\n\n this._workletNode.connect(this.output);\n this.output.gain.value = 0;\n\n // this may only be necessary because of a Chrome bug\n this.output.connect(this.audiocontext.destination);\n\n // connect to p5sound master output by default, unless set by input()\n p5sound.meter.connect(this._workletNode);\n\n // add this p5.SoundFile to the soundArray\n p5sound.soundArray.push(this);\n };\n\n /**\n * Connects to the p5sound instance (master output) by default.\n * Optionally, you can pass in a specific source (i.e. a soundfile).\n *\n * @method setInput\n * @for p5.Amplitude\n * @param {soundObject|undefined} [snd] set the sound source\n * (optional, defaults to\n * master output)\n * @param {Number|undefined} [smoothing] a range between 0.0 and 1.0\n * to smooth amplitude readings\n * @example\n *
\n * function preload(){\n * sound1 = loadSound('assets/beat.mp3');\n * sound2 = loadSound('assets/drum.mp3');\n * }\n * function setup(){\n * amplitude = new p5.Amplitude();\n * sound1.play();\n * sound2.play();\n * amplitude.setInput(sound2);\n * }\n * function draw() {\n * background(0);\n * fill(255);\n * var level = amplitude.getLevel();\n * var size = map(level, 0, 1, 0, 200);\n * ellipse(width/2, height/2, size, size);\n * }\n * function mouseClicked(){\n * sound1.stop();\n * sound2.stop();\n * }\n *
\n */\n p5.Amplitude.prototype.setInput = function(source, smoothing) {\n\n p5sound.meter.disconnect();\n\n if (smoothing) {\n this._workletNode.parameters.get('smoothing').value = smoothing;\n }\n\n // connect to the master out of p5s instance if no snd is provided\n if (source == null) {\n console.log('Amplitude input source is not ready! Connecting to master output instead');\n p5sound.meter.connect(this._workletNode);\n }\n\n // if it is a p5.Signal\n else if (source instanceof p5.Signal) {\n source.output.connect(this._workletNode);\n }\n // connect to the sound if it is available\n else if (source) {\n source.connect(this._workletNode);\n this._workletNode.disconnect();\n this._workletNode.connect(this.output);\n }\n\n // otherwise, connect to the master out of p5s instance (default)\n else {\n p5sound.meter.connect(this._workletNode);\n }\n };\n\n p5.Amplitude.prototype.connect = function(unit) {\n if (unit) {\n if (unit.hasOwnProperty('input')) {\n this.output.connect(unit.input);\n } else {\n this.output.connect(unit);\n }\n } else {\n this.output.connect(this.panner.connect(p5sound.input));\n }\n };\n\n p5.Amplitude.prototype.disconnect = function() {\n if (this.output) {\n this.output.disconnect();\n }\n };\n\n /**\n * Returns a single Amplitude reading at the moment it is called.\n * For continuous readings, run in the draw loop.\n *\n * @method getLevel\n * @for p5.Amplitude\n * @param {Number} [channel] Optionally return only channel 0 (left) or 1 (right)\n * @return {Number} Amplitude as a number between 0.0 and 1.0\n * @example\n *
\n * function preload(){\n * sound = loadSound('assets/beat.mp3');\n * }\n * function setup() {\n * amplitude = new p5.Amplitude();\n * sound.play();\n * }\n * function draw() {\n * background(0);\n * fill(255);\n * var level = amplitude.getLevel();\n * var size = map(level, 0, 1, 0, 200);\n * ellipse(width/2, height/2, size, size);\n * }\n * function mouseClicked(){\n * sound.stop();\n * }\n *
\n */\n p5.Amplitude.prototype.getLevel = function(channel) {\n if (typeof channel !== 'undefined') {\n if (this.normalize) {\n return this.stereoVolNorm[channel];\n } else {\n return this.stereoVol[channel];\n }\n }\n else if (this.normalize) {\n return this.volNorm;\n }\n else {\n return this.volume;\n }\n };\n\n /**\n * Determines whether the results of Amplitude.process() will be\n * Normalized. To normalize, Amplitude finds the difference the\n * loudest reading it has processed and the maximum amplitude of\n * 1.0. Amplitude adds this difference to all values to produce\n * results that will reliably map between 0.0 and 1.0. However,\n * if a louder moment occurs, the amount that Normalize adds to\n * all the values will change. Accepts an optional boolean parameter\n * (true or false). Normalizing is off by default.\n *\n * @method toggleNormalize\n * @for p5.Amplitude\n * @param {boolean} [boolean] set normalize to true (1) or false (0)\n */\n p5.Amplitude.prototype.toggleNormalize = function(bool) {\n if (typeof bool === 'boolean') {\n this.normalize = bool;\n }\n else {\n this.normalize = !this.normalize;\n }\n this._workletNode.port.postMessage({ name: 'toggleNormalize', normalize: this.normalize });\n };\n\n /**\n * Smooth Amplitude analysis by averaging with the last analysis\n * frame. Off by default.\n *\n * @method smooth\n * @for p5.Amplitude\n * @param {Number} set smoothing from 0.0 <= 1\n */\n p5.Amplitude.prototype.smooth = function(s) {\n if (s >= 0 && s < 1) {\n this._workletNode.port.postMessage({ name: 'smoothing', smoothing: s });\n } else {\n console.log('Error: smoothing must be between 0 and 1');\n }\n };\n\n p5.Amplitude.prototype.dispose = function() {\n // remove reference from soundArray\n var index = p5sound.soundArray.indexOf(this);\n p5sound.soundArray.splice(index, 1);\n\n if (this.input) {\n this.input.disconnect();\n delete this.input;\n }\n if (this.output) {\n this.output.disconnect();\n delete this.output;\n }\n\n this._workletNode.disconnect();\n delete this._workletNode;\n };\n\n});\n","'use strict';\n\ndefine(function(require) {\n var p5sound = require('master');\n\n /**\n *
FFT (Fast Fourier Transform) is an analysis algorithm that\n * isolates individual\n * \n * audio frequencies within a waveform.
\n *\n *
Once instantiated, a p5.FFT object can return an array based on\n * two types of analyses: • FFT.waveform() computes\n * amplitude values along the time domain. The array indices correspond\n * to samples across a brief moment in time. Each value represents\n * amplitude of the waveform at that sample of time. \n * • FFT.analyze() computes amplitude values along the\n * frequency domain. The array indices correspond to frequencies (i.e.\n * pitches), from the lowest to the highest that humans can hear. Each\n * value represents amplitude at that slice of the frequency spectrum.\n * Use with getEnergy() to measure amplitude at specific\n * frequencies, or within a range of frequencies.
\n *\n *
FFT analyzes a very short snapshot of sound called a sample\n * buffer. It returns an array of amplitude measurements, referred\n * to as bins. The array is 1024 bins long by default.\n * You can change the bin array length, but it must be a power of 2\n * between 16 and 1024 in order for the FFT algorithm to function\n * correctly. The actual size of the FFT buffer is twice the\n * number of bins, so given a standard sample rate, the buffer is\n * 2048/44100 seconds long.
\n *\n *\n * @class p5.FFT\n * @constructor\n * @param {Number} [smoothing] Smooth results of Freq Spectrum.\n * 0.0 < smoothing < 1.0.\n * Defaults to 0.8.\n * @param {Number} [bins] Length of resulting array.\n * Must be a power of two between\n * 16 and 1024. Defaults to 1024.\n * @example\n *
\n * function preload(){\n * sound = loadSound('assets/Damscray_DancingTiger.mp3');\n * }\n *\n * function setup(){\n * var cnv = createCanvas(100,100);\n * cnv.mouseClicked(togglePlay);\n * fft = new p5.FFT();\n * sound.amp(0.2);\n * }\n *\n * function draw(){\n * background(0);\n *\n * var spectrum = fft.analyze();\n * noStroke();\n * fill(0,255,0); // spectrum is green\n * for (var i = 0; i< spectrum.length; i++){\n * var x = map(i, 0, spectrum.length, 0, width);\n * var h = -height + map(spectrum[i], 0, 255, height, 0);\n * rect(x, height, width / spectrum.length, h )\n * }\n *\n * var waveform = fft.waveform();\n * noFill();\n * beginShape();\n * stroke(255,0,0); // waveform is red\n * strokeWeight(1);\n * for (var i = 0; i< waveform.length; i++){\n * var x = map(i, 0, waveform.length, 0, width);\n * var y = map( waveform[i], -1, 1, 0, height);\n * vertex(x,y);\n * }\n * endShape();\n *\n * text('click to play/pause', 4, 10);\n * }\n *\n * // fade sound if mouse is over canvas\n * function togglePlay() {\n * if (sound.isPlaying()) {\n * sound.pause();\n * } else {\n * sound.loop();\n * }\n * }\n *
\n */\n p5.FFT = function(smoothing, bins) {\n this.input = this.analyser = p5sound.audiocontext.createAnalyser();\n\n Object.defineProperties(this, {\n bins: {\n get: function() {\n return this.analyser.fftSize / 2;\n },\n set: function(b) {\n this.analyser.fftSize = b * 2;\n },\n configurable: true,\n enumerable: true\n },\n smoothing: {\n get: function() {\n return this.analyser.smoothingTimeConstant;\n },\n set: function(s) {\n this.analyser.smoothingTimeConstant = s;\n },\n configurable: true,\n enumerable: true\n }\n });\n\n // set default smoothing and bins\n this.smooth(smoothing);\n this.bins = bins || 1024;\n\n // default connections to p5sound fftMeter\n p5sound.fftMeter.connect(this.analyser);\n\n this.freqDomain = new Uint8Array(this.analyser.frequencyBinCount);\n this.timeDomain = new Uint8Array(this.analyser.frequencyBinCount);\n\n // predefined frequency ranges, these will be tweakable\n this.bass = [20, 140];\n this.lowMid = [140, 400];\n this.mid = [400, 2600];\n this.highMid = [2600, 5200];\n this.treble = [5200, 14000];\n\n // add this p5.SoundFile to the soundArray\n p5sound.soundArray.push(this);\n };\n\n /**\n * Set the input source for the FFT analysis. If no source is\n * provided, FFT will analyze all sound in the sketch.\n *\n * @method setInput\n * @for p5.FFT\n * @param {Object} [source] p5.sound object (or web audio API source node)\n */\n p5.FFT.prototype.setInput = function(source) {\n if (!source) {\n p5sound.fftMeter.connect(this.analyser);\n } else {\n if (source.output) {\n source.output.connect(this.analyser);\n } else if (source.connect) {\n source.connect(this.analyser);\n }\n p5sound.fftMeter.disconnect();\n }\n };\n\n /**\n * Returns an array of amplitude values (between -1.0 and +1.0) that represent\n * a snapshot of amplitude readings in a single buffer. Length will be\n * equal to bins (defaults to 1024). Can be used to draw the waveform\n * of a sound.\n *\n * @method waveform\n * @for p5.FFT\n * @param {Number} [bins] Must be a power of two between\n * 16 and 1024. Defaults to 1024.\n * @param {String} [precision] If any value is provided, will return results\n * in a Float32 Array which is more precise\n * than a regular array.\n * @return {Array} Array Array of amplitude values (-1 to 1)\n * over time. Array length = bins.\n *\n */\n p5.FFT.prototype.waveform = function() {\n var bins, mode, normalArray;\n\n for (var i = 0; i < arguments.length; i++) {\n if (typeof arguments[i] === 'number') {\n bins = arguments[i];\n this.analyser.fftSize = bins * 2;\n }\n if (typeof arguments[i] === 'string') {\n mode = arguments[i];\n }\n }\n\n // getFloatFrequencyData doesnt work in Safari as of 5/2015\n if (mode && !p5.prototype._isSafari()) {\n timeToFloat(this, this.timeDomain);\n this.analyser.getFloatTimeDomainData(this.timeDomain);\n return this.timeDomain;\n } else {\n timeToInt(this, this.timeDomain);\n this.analyser.getByteTimeDomainData(this.timeDomain);\n var normalArray = new Array();\n for (var j = 0; j < this.timeDomain.length; j++) {\n var scaled = p5.prototype.map(this.timeDomain[j], 0, 255, -1, 1);\n normalArray.push(scaled);\n }\n return normalArray;\n }\n };\n\n /**\n * Returns an array of amplitude values (between 0 and 255)\n * across the frequency spectrum. Length is equal to FFT bins\n * (1024 by default). The array indices correspond to frequencies\n * (i.e. pitches), from the lowest to the highest that humans can\n * hear. Each value represents amplitude at that slice of the\n * frequency spectrum. Must be called prior to using\n * getEnergy().\n *\n * @method analyze\n * @for p5.FFT\n * @param {Number} [bins] Must be a power of two between\n * 16 and 1024. Defaults to 1024.\n * @param {Number} [scale] If \"dB,\" returns decibel\n * float measurements between\n * -140 and 0 (max).\n * Otherwise returns integers from 0-255.\n * @return {Array} spectrum Array of energy (amplitude/volume)\n * values across the frequency spectrum.\n * Lowest energy (silence) = 0, highest\n * possible is 255.\n * @example\n *
\n * var osc;\n * var fft;\n *\n * function setup(){\n * createCanvas(100,100);\n * osc = new p5.Oscillator();\n * osc.amp(0);\n * osc.start();\n * fft = new p5.FFT();\n * }\n *\n * function draw(){\n * background(0);\n *\n * var freq = map(mouseX, 0, 800, 20, 15000);\n * freq = constrain(freq, 1, 20000);\n * osc.freq(freq);\n *\n * var spectrum = fft.analyze();\n * noStroke();\n * fill(0,255,0); // spectrum is green\n * for (var i = 0; i< spectrum.length; i++){\n * var x = map(i, 0, spectrum.length, 0, width);\n * var h = -height + map(spectrum[i], 0, 255, height, 0);\n * rect(x, height, width / spectrum.length, h );\n * }\n *\n * stroke(255);\n * text('Freq: ' + round(freq)+'Hz', 10, 10);\n *\n * isMouseOverCanvas();\n * }\n *\n * // only play sound when mouse is over canvas\n * function isMouseOverCanvas() {\n * var mX = mouseX, mY = mouseY;\n * if (mX > 0 && mX < width && mY < height && mY > 0) {\n * osc.amp(0.5, 0.2);\n * } else {\n * osc.amp(0, 0.2);\n * }\n * }\n *
\n *\n *\n */\n p5.FFT.prototype.analyze = function() {\n var mode;\n\n for (var i = 0; i < arguments.length; i++) {\n if (typeof arguments[i] === 'number') {\n this.bins = arguments[i];\n this.analyser.fftSize = this.bins * 2;\n }\n if (typeof arguments[i] === 'string') {\n mode = arguments[i];\n }\n }\n\n if (mode && mode.toLowerCase() === 'db') {\n freqToFloat(this);\n this.analyser.getFloatFrequencyData(this.freqDomain);\n return this.freqDomain;\n } else {\n freqToInt(this, this.freqDomain);\n this.analyser.getByteFrequencyData(this.freqDomain);\n var normalArray = Array.apply([], this.freqDomain);\n \n return normalArray;\n }\n };\n\n /**\n * Returns the amount of energy (volume) at a specific\n * \n * frequency, or the average amount of energy between two\n * frequencies. Accepts Number(s) corresponding\n * to frequency (in Hz), or a String corresponding to predefined\n * frequency ranges (\"bass\", \"lowMid\", \"mid\", \"highMid\", \"treble\").\n * Returns a range between 0 (no energy/volume at that frequency) and\n * 255 (maximum energy).\n * NOTE: analyze() must be called prior to getEnergy(). Analyze()\n * tells the FFT to analyze frequency data, and getEnergy() uses\n * the results determine the value at a specific frequency or\n * range of frequencies.\n *\n * @method getEnergy\n * @for p5.FFT\n * @param {Number|String} frequency1 Will return a value representing\n * energy at this frequency. Alternately,\n * the strings \"bass\", \"lowMid\" \"mid\",\n * \"highMid\", and \"treble\" will return\n * predefined frequency ranges.\n * @param {Number} [frequency2] If a second frequency is given,\n * will return average amount of\n * energy that exists between the\n * two frequencies.\n * @return {Number} Energy Energy (volume/amplitude) from\n * 0 and 255.\n *\n */\n p5.FFT.prototype.getEnergy = function(frequency1, frequency2) {\n var nyquist = p5sound.audiocontext.sampleRate / 2;\n\n if (frequency1 === 'bass') {\n frequency1 = this.bass[0];\n frequency2 = this.bass[1];\n } else if (frequency1 === 'lowMid') {\n frequency1 = this.lowMid[0];\n frequency2 = this.lowMid[1];\n } else if (frequency1 === 'mid') {\n frequency1 = this.mid[0];\n frequency2 = this.mid[1];\n } else if (frequency1 === 'highMid') {\n frequency1 = this.highMid[0];\n frequency2 = this.highMid[1];\n } else if (frequency1 === 'treble') {\n frequency1 = this.treble[0];\n frequency2 = this.treble[1];\n }\n\n if (typeof frequency1 !== 'number') {\n throw 'invalid input for getEnergy()';\n } else if (!frequency2) {\n // if only one parameter:\n var index = Math.round(frequency1 / nyquist * this.freqDomain.length);\n return this.freqDomain[index];\n } else if (frequency1 && frequency2) {\n // if two parameters:\n // if second is higher than first\n if (frequency1 > frequency2) {\n var swap = frequency2;\n frequency2 = frequency1;\n frequency1 = swap;\n }\n var lowIndex = Math.round(frequency1 / nyquist * this.freqDomain.length);\n var highIndex = Math.round(frequency2 / nyquist * this.freqDomain.length);\n\n var total = 0;\n var numFrequencies = 0;\n // add up all of the values for the frequencies\n for (var i = lowIndex; i <= highIndex; i++) {\n total += this.freqDomain[i];\n numFrequencies += 1;\n }\n // divide by total number of frequencies\n var toReturn = total / numFrequencies;\n return toReturn;\n } else {\n throw 'invalid input for getEnergy()';\n }\n };\n\n // compatability with v.012, changed to getEnergy in v.0121. Will be deprecated...\n p5.FFT.prototype.getFreq = function(freq1, freq2) {\n console.log('getFreq() is deprecated. Please use getEnergy() instead.');\n var x = this.getEnergy(freq1, freq2);\n return x;\n };\n\n /**\n * Returns the\n * \n * spectral centroid of the input signal.\n * NOTE: analyze() must be called prior to getCentroid(). Analyze()\n * tells the FFT to analyze frequency data, and getCentroid() uses\n * the results determine the spectral centroid.\n *\n * @method getCentroid\n * @for p5.FFT\n * @return {Number} Spectral Centroid Frequency Frequency of the spectral centroid in Hz.\n *\n *\n * @example\n *
\n *\n *\n *function setup(){\n * cnv = createCanvas(100,100);\n * sound = new p5.AudioIn();\n * sound.start();\n * fft = new p5.FFT();\n * sound.connect(fft);\n *}\n *\n *\n *function draw(){\n *\n * var centroidplot = 0.0;\n * var spectralCentroid = 0;\n *\n *\n * background(0);\n * stroke(0,255,0);\n * var spectrum = fft.analyze();\n * fill(0,255,0); // spectrum is green\n *\n * //draw the spectrum\n * for (var i = 0; i< spectrum.length; i++){\n * var x = map(log(i), 0, log(spectrum.length), 0, width);\n * var h = map(spectrum[i], 0, 255, 0, height);\n * var rectangle_width = (log(i+1)-log(i))*(width/log(spectrum.length));\n * rect(x, height, rectangle_width, -h )\n * }\n\n * var nyquist = 22050;\n *\n * // get the centroid\n * spectralCentroid = fft.getCentroid();\n *\n * // the mean_freq_index calculation is for the display.\n * var mean_freq_index = spectralCentroid/(nyquist/spectrum.length);\n *\n * centroidplot = map(log(mean_freq_index), 0, log(spectrum.length), 0, width);\n *\n *\n * stroke(255,0,0); // the line showing where the centroid is will be red\n *\n * rect(centroidplot, 0, width / spectrum.length, height)\n * noStroke();\n * fill(255,255,255); // text is white\n * text(\"centroid: \", 10, 20);\n * text(round(spectralCentroid)+\" Hz\", 10, 40);\n *}\n *
\n */\n p5.FFT.prototype.getCentroid = function() {\n var nyquist = p5sound.audiocontext.sampleRate / 2;\n var cumulative_sum = 0;\n var centroid_normalization = 0;\n\n for (var i = 0; i < this.freqDomain.length; i++) {\n cumulative_sum += i * this.freqDomain[i];\n centroid_normalization += this.freqDomain[i];\n }\n\n var mean_freq_index = 0;\n\n if (centroid_normalization !== 0) {\n mean_freq_index = cumulative_sum / centroid_normalization;\n }\n\n var spec_centroid_freq =\n mean_freq_index * (nyquist / this.freqDomain.length);\n return spec_centroid_freq;\n };\n\n /**\n * Smooth FFT analysis by averaging with the last analysis frame.\n *\n * @method smooth\n * @param {Number} smoothing 0.0 < smoothing < 1.0.\n * Defaults to 0.8.\n */\n p5.FFT.prototype.smooth = function(s) {\n if (typeof s !== 'undefined') {\n this.smoothing = s;\n }\n return this.smoothing;\n };\n\n p5.FFT.prototype.dispose = function() {\n // remove reference from soundArray\n var index = p5sound.soundArray.indexOf(this);\n p5sound.soundArray.splice(index, 1);\n\n if (this.analyser) {\n this.analyser.disconnect();\n delete this.analyser;\n }\n };\n\n /**\n * Returns an array of average amplitude values for a given number\n * of frequency bands split equally. N defaults to 16.\n * NOTE: analyze() must be called prior to linAverages(). Analyze()\n * tells the FFT to analyze frequency data, and linAverages() uses\n * the results to group them into a smaller set of averages.\n *\n * @method linAverages\n * @for p5.FFT\n * @param {Number} N Number of returned frequency groups\n * @return {Array} linearAverages Array of average amplitude values for each group\n */\n p5.FFT.prototype.linAverages = function(N) {\n var N = N || 16; // This prevents undefined, null or 0 values of N\n\n var spectrum = this.freqDomain;\n var spectrumLength = spectrum.length;\n var spectrumStep = Math.floor(spectrumLength / N);\n\n var linearAverages = new Array(N);\n // Keep a second index for the current average group and place the values accordingly\n // with only one loop in the spectrum data\n var groupIndex = 0;\n\n for (var specIndex = 0; specIndex < spectrumLength; specIndex++) {\n linearAverages[groupIndex] =\n linearAverages[groupIndex] !== undefined\n ? (linearAverages[groupIndex] + spectrum[specIndex]) / 2\n : spectrum[specIndex];\n\n // Increase the group index when the last element of the group is processed\n if (specIndex % spectrumStep === spectrumStep - 1) {\n groupIndex++;\n }\n }\n\n return linearAverages;\n };\n\n /**\n * Returns an array of average amplitude values of the spectrum, for a given\n * set of \n * Octave Bands\n * NOTE: analyze() must be called prior to logAverages(). Analyze()\n * tells the FFT to analyze frequency data, and logAverages() uses\n * the results to group them into a smaller set of averages.\n *\n * @method logAverages\n * @for p5.FFT\n * @param {Array} octaveBands Array of Octave Bands objects for grouping\n * @return {Array} logAverages Array of average amplitude values for each group\n */\n p5.FFT.prototype.logAverages = function(octaveBands) {\n var nyquist = p5sound.audiocontext.sampleRate / 2;\n var spectrum = this.freqDomain;\n var spectrumLength = spectrum.length;\n\n var logAverages = new Array(octaveBands.length);\n // Keep a second index for the current average group and place the values accordingly\n // With only one loop in the spectrum data\n var octaveIndex = 0;\n\n for (var specIndex = 0; specIndex < spectrumLength; specIndex++) {\n var specIndexFrequency = Math.round(\n specIndex * nyquist / this.freqDomain.length\n );\n\n // Increase the group index if the current frequency exceeds the limits of the band\n if (specIndexFrequency > octaveBands[octaveIndex].hi) {\n octaveIndex++;\n }\n\n logAverages[octaveIndex] =\n logAverages[octaveIndex] !== undefined\n ? (logAverages[octaveIndex] + spectrum[specIndex]) / 2\n : spectrum[specIndex];\n }\n\n return logAverages;\n };\n\n /**\n * Calculates and Returns the 1/N\n * Octave Bands\n * N defaults to 3 and minimum central frequency to 15.625Hz.\n * (1/3 Octave Bands ~= 31 Frequency Bands)\n * Setting fCtr0 to a central value of a higher octave will ignore the lower bands\n * and produce less frequency groups.\n *\n * @method getOctaveBands\n * @for p5.FFT\n * @param {Number} N Specifies the 1/N type of generated octave bands\n * @param {Number} fCtr0 Minimum central frequency for the lowest band\n * @return {Array} octaveBands Array of octave band objects with their bounds\n */\n p5.FFT.prototype.getOctaveBands = function(N, fCtr0) {\n var N = N || 3; // Default to 1/3 Octave Bands\n var fCtr0 = fCtr0 || 15.625; // Minimum central frequency, defaults to 15.625Hz\n\n var octaveBands = [];\n var lastFrequencyBand = {\n lo: fCtr0 / Math.pow(2, 1 / (2 * N)),\n ctr: fCtr0,\n hi: fCtr0 * Math.pow(2, 1 / (2 * N))\n };\n octaveBands.push(lastFrequencyBand);\n\n var nyquist = p5sound.audiocontext.sampleRate / 2;\n while (lastFrequencyBand.hi < nyquist) {\n var newFrequencyBand = {};\n newFrequencyBand.lo = lastFrequencyBand.hi;\n newFrequencyBand.ctr = lastFrequencyBand.ctr * Math.pow(2, 1 / N);\n newFrequencyBand.hi = newFrequencyBand.ctr * Math.pow(2, 1 / (2 * N));\n\n octaveBands.push(newFrequencyBand);\n lastFrequencyBand = newFrequencyBand;\n }\n\n return octaveBands;\n };\n\n // helper methods to convert type from float (dB) to int (0-255)\n var freqToFloat = function(fft) {\n if (fft.freqDomain instanceof Float32Array === false) {\n fft.freqDomain = new Float32Array(fft.analyser.frequencyBinCount);\n }\n };\n var freqToInt = function(fft) {\n if (fft.freqDomain instanceof Uint8Array === false) {\n fft.freqDomain = new Uint8Array(fft.analyser.frequencyBinCount);\n }\n };\n var timeToFloat = function(fft) {\n if (fft.timeDomain instanceof Float32Array === false) {\n fft.timeDomain = new Float32Array(fft.analyser.frequencyBinCount);\n }\n };\n var timeToInt = function(fft) {\n if (fft.timeDomain instanceof Uint8Array === false) {\n fft.timeDomain = new Uint8Array(fft.analyser.frequencyBinCount);\n }\n };\n});\n","'use strict';\n\ndefine(function (require) {\n\n // Signal is built with the Tone.js signal by Yotam Mann\n // https://github.com/TONEnoTONE/Tone.js/\n var Signal = require('Tone/signal/Signal');\n var Add = require('Tone/signal/Add');\n var Mult = require('Tone/signal/Multiply');\n var Scale = require('Tone/signal/Scale');\n\n /**\n *
p5.Signal is a constant audio-rate signal used by p5.Oscillator\n * and p5.Envelope for modulation math.
\n *\n *
This is necessary because Web Audio is processed on a seprate clock.\n * For example, the p5 draw loop runs about 60 times per second. But\n * the audio clock must process samples 44100 times per second. If we\n * want to add a value to each of those samples, we can't do it in the\n * draw loop, but we can do it by adding a constant-rate audio signal.This class mostly functions behind the scenes in p5.sound, and returns\n * a Tone.Signal from the Tone.js library by Yotam Mann.\n * If you want to work directly with audio signals for modular\n * synthesis, check out\n * tone.js.
\n *\n * @class p5.Signal\n * @constructor\n * @return {Tone.Signal} A Signal object from the Tone.js library\n * @example\n *
\n * function setup() {\n * carrier = new p5.Oscillator('sine');\n * carrier.amp(1); // set amplitude\n * carrier.freq(220); // set frequency\n * carrier.start(); // start oscillating\n *\n * modulator = new p5.Oscillator('sawtooth');\n * modulator.disconnect();\n * modulator.amp(1);\n * modulator.freq(4);\n * modulator.start();\n *\n * // Modulator's default amplitude range is -1 to 1.\n * // Multiply it by -200, so the range is -200 to 200\n * // then add 220 so the range is 20 to 420\n * carrier.freq( modulator.mult(-200).add(220) );\n * }\n *
\n */\n p5.Signal = function(value) {\n var s = new Signal(value);\n // p5sound.soundArray.push(s);\n return s; // TODO: is this really a constructor?\n };\n\n /**\n * Fade to value, for smooth transitions\n *\n * @method fade\n * @for p5.Signal\n * @param {Number} value Value to set this signal\n * @param {Number} [secondsFromNow] Length of fade, in seconds from now\n */\n Signal.prototype.fade = Signal.prototype.linearRampToValueAtTime;\n Mult.prototype.fade = Signal.prototype.fade;\n Add.prototype.fade = Signal.prototype.fade;\n Scale.prototype.fade = Signal.prototype.fade;\n\n\n /**\n * Connect a p5.sound object or Web Audio node to this\n * p5.Signal so that its amplitude values can be scaled.\n *\n * @method setInput\n * @for p5.Signal\n * @param {Object} input\n */\n Signal.prototype.setInput = function(_input) {\n _input.connect(this);\n };\n Mult.prototype.setInput = Signal.prototype.setInput;\n Add.prototype.setInput = Signal.prototype.setInput;\n Scale.prototype.setInput = Signal.prototype.setInput;\n\n\n // signals can add / mult / scale themselves\n\n /**\n * Add a constant value to this audio signal,\n * and return the resulting audio signal. Does\n * not change the value of the original signal,\n * instead it returns a new p5.SignalAdd.\n *\n * @method add\n * @for p5.Signal\n * @param {Number} number\n * @return {p5.Signal} object\n */\n Signal.prototype.add = function(num) {\n var add = new Add(num);\n // add.setInput(this);\n this.connect(add);\n return add;\n };\n Mult.prototype.add = Signal.prototype.add;\n Add.prototype.add = Signal.prototype.add;\n Scale.prototype.add = Signal.prototype.add;\n\n /**\n * Multiply this signal by a constant value,\n * and return the resulting audio signal. Does\n * not change the value of the original signal,\n * instead it returns a new p5.SignalMult.\n *\n * @method mult\n * @for p5.Signal\n * @param {Number} number to multiply\n * @return {p5.Signal} object\n */\n Signal.prototype.mult = function(num) {\n var mult = new Mult(num);\n // mult.setInput(this);\n this.connect(mult);\n return mult;\n };\n Mult.prototype.mult = Signal.prototype.mult;\n Add.prototype.mult = Signal.prototype.mult;\n Scale.prototype.mult = Signal.prototype.mult;\n\n /**\n * Scale this signal value to a given range,\n * and return the result as an audio signal. Does\n * not change the value of the original signal,\n * instead it returns a new p5.SignalScale.\n *\n * @method scale\n * @for p5.Signal\n * @param {Number} number to multiply\n * @param {Number} inMin input range minumum\n * @param {Number} inMax input range maximum\n * @param {Number} outMin input range minumum\n * @param {Number} outMax input range maximum\n * @return {p5.Signal} object\n */\n Signal.prototype.scale = function(inMin, inMax, outMin, outMax) {\n var mapOutMin, mapOutMax;\n if (arguments.length === 4) {\n mapOutMin = p5.prototype.map(outMin, inMin, inMax, 0, 1) - 0.5;\n mapOutMax = p5.prototype.map(outMax, inMin, inMax, 0, 1) - 0.5;\n }\n else {\n mapOutMin = arguments[0];\n mapOutMax = arguments[1];\n }\n var scale = new Scale(mapOutMin, mapOutMax);\n this.connect(scale);\n return scale;\n };\n Mult.prototype.scale = Signal.prototype.scale;\n Add.prototype.scale = Signal.prototype.scale;\n Scale.prototype.scale = Signal.prototype.scale;\n\n});\n\n\n","define([\"Tone/core/Tone\", \"Tone/type/TimeBase\"], function (Tone) {\n\n\t/**\n\t * @class Tone.Frequency is a primitive type for encoding Frequency values. \n\t * Eventually all time values are evaluated to hertz\n\t * using the `eval` method. \n\t * @constructor\n\t * @extends {Tone.TimeBase}\n\t * @param {String|Number} val The time value.\n\t * @param {String=} units The units of the value.\n\t * @example\n\t * Tone.Frequency(\"C3\") // 261\n\t * Tone.Frequency(38, \"midi\") //\n\t * Tone.Frequency(\"C3\").transpose(4);\n\t */\n\tTone.Frequency = function(val, units){\n\t\tif (this instanceof Tone.Frequency){\n\t\t\t\n\t\t\tTone.TimeBase.call(this, val, units);\n\n\t\t} else {\n\t\t\treturn new Tone.Frequency(val, units);\n\t\t}\n\t};\n\n\tTone.extend(Tone.Frequency, Tone.TimeBase);\n\n\t///////////////////////////////////////////////////////////////////////////\n\t//\tAUGMENT BASE EXPRESSIONS\n\t///////////////////////////////////////////////////////////////////////////\n\n\t//clone the expressions so that \n\t//we can add more without modifying the original\n\tTone.Frequency.prototype._primaryExpressions = Object.create(Tone.TimeBase.prototype._primaryExpressions);\n\n\t/*\n\t * midi type primary expression\n\t * @type {Object}\n\t * @private\n\t */\n\tTone.Frequency.prototype._primaryExpressions.midi = {\n\t\tregexp : /^(\\d+(?:\\.\\d+)?midi)/,\n\t\tmethod : function(value){\n\t\t\treturn this.midiToFrequency(value);\n\t\t}\t\n\t};\n\n\t/*\n\t * note type primary expression\n\t * @type {Object}\n\t * @private\n\t */\n\tTone.Frequency.prototype._primaryExpressions.note = {\n\t\tregexp : /^([a-g]{1}(?:b|#|x|bb)?)(-?[0-9]+)/i,\n\t\tmethod : function(pitch, octave){\n\t\t\tvar index = noteToScaleIndex[pitch.toLowerCase()];\n\t\t\tvar noteNumber = index + (parseInt(octave) + 1) * 12;\n\t\t\treturn this.midiToFrequency(noteNumber);\n\t\t}\t\n\t};\n\n\t/*\n\t * BeatsBarsSixteenths type primary expression\n\t * @type {Object}\n\t * @private\n\t */\n\tTone.Frequency.prototype._primaryExpressions.tr = {\n\t\t\tregexp : /^(\\d+(?:\\.\\d+)?):(\\d+(?:\\.\\d+)?):?(\\d+(?:\\.\\d+)?)?/,\n\t\t\tmethod : function(m, q, s){\n\t\t\tvar total = 1;\n\t\t\tif (m && m !== \"0\"){\n\t\t\t\ttotal *= this._beatsToUnits(this._timeSignature() * parseFloat(m));\n\t\t\t}\n\t\t\tif (q && q !== \"0\"){\n\t\t\t\ttotal *= this._beatsToUnits(parseFloat(q));\n\t\t\t}\n\t\t\tif (s && s !== \"0\"){\n\t\t\t\ttotal *= this._beatsToUnits(parseFloat(s) / 4);\n\t\t\t}\n\t\t\treturn total;\n\t\t}\n\t};\n\n\t///////////////////////////////////////////////////////////////////////////\n\t//\tEXPRESSIONS\n\t///////////////////////////////////////////////////////////////////////////\n\n\t/**\n\t * Transposes the frequency by the given number of semitones.\n\t * @param {Interval} interval\n\t * @return {Tone.Frequency} this\n\t * @example\n\t * Tone.Frequency(\"A4\").transpose(3); //\"C5\"\n\t */\n\tTone.Frequency.prototype.transpose = function(interval){\n\t\tthis._expr = function(expr, interval){\n\t\t\tvar val = expr();\n\t\t\treturn val * this.intervalToFrequencyRatio(interval);\n\t\t}.bind(this, this._expr, interval);\n\t\treturn this;\n\t};\n\n\t/**\n\t * Takes an array of semitone intervals and returns\n\t * an array of frequencies transposed by those intervals.\n\t * @param {Array} intervals\n\t * @return {Tone.Frequency} this\n\t * @example\n\t * Tone.Frequency(\"A4\").harmonize([0, 3, 7]); //[\"A4\", \"C5\", \"E5\"]\n\t */\n\tTone.Frequency.prototype.harmonize = function(intervals){\n\t\tthis._expr = function(expr, intervals){\n\t\t\tvar val = expr();\n\t\t\tvar ret = [];\n\t\t\tfor (var i = 0; i < intervals.length; i++){\n\t\t\t\tret[i] = val * this.intervalToFrequencyRatio(intervals[i]);\n\t\t\t}\n\t\t\treturn ret;\n\t\t}.bind(this, this._expr, intervals);\n\t\treturn this;\n\t};\n\n\t///////////////////////////////////////////////////////////////////////////\n\t//\tUNIT CONVERSIONS\n\t///////////////////////////////////////////////////////////////////////////\n\n\t/**\n\t * Return the value of the frequency as a MIDI note\n\t * @return {MIDI}\n\t * @example\n\t * Tone.Frequency(\"C4\").toMidi(); //60\n\t */\n\tTone.Frequency.prototype.toMidi = function(){\n\t\treturn this.frequencyToMidi(this.valueOf());\n\t};\n\n\t/**\n\t * Return the value of the frequency in Scientific Pitch Notation\n\t * @return {Note}\n\t * @example\n\t * Tone.Frequency(69, \"midi\").toNote(); //\"A4\"\n\t */\n\tTone.Frequency.prototype.toNote = function(){\n\t\tvar freq = this.valueOf();\n\t\tvar log = Math.log(freq / Tone.Frequency.A4) / Math.LN2;\n\t\tvar noteNumber = Math.round(12 * log) + 57;\n\t\tvar octave = Math.floor(noteNumber/12);\n\t\tif(octave < 0){\n\t\t\tnoteNumber += -12 * octave;\n\t\t}\n\t\tvar noteName = scaleIndexToNote[noteNumber % 12];\n\t\treturn noteName + octave.toString();\n\t};\n\n\t/**\n\t * Return the duration of one cycle in seconds.\n\t * @return {Seconds}\n\t */\n\tTone.Frequency.prototype.toSeconds = function(){\n\t\treturn 1 / this.valueOf();\n\t};\n\n\t/**\n\t * Return the value in Hertz\n\t * @return {Frequency}\n\t */\n\tTone.Frequency.prototype.toFrequency = function(){\n\t\treturn this.valueOf();\n\t};\n\n\t/**\n\t * Return the duration of one cycle in ticks\n\t * @return {Ticks}\n\t */\n\tTone.Frequency.prototype.toTicks = function(){\n\t\tvar quarterTime = this._beatsToUnits(1);\n\t\tvar quarters = this.valueOf() / quarterTime;\n\t\treturn Math.floor(quarters * Tone.Transport.PPQ);\n\t};\n\n\t///////////////////////////////////////////////////////////////////////////\n\t//\tUNIT CONVERSIONS HELPERS\n\t///////////////////////////////////////////////////////////////////////////\n\n\t/**\n\t * Returns the value of a frequency in the current units\n\t * @param {Frequency} freq\n\t * @return {Number}\n\t * @private\n\t */\n\tTone.Frequency.prototype._frequencyToUnits = function(freq){\n\t\treturn freq;\n\t};\n\n\t/**\n\t * Returns the value of a tick in the current time units\n\t * @param {Ticks} ticks\n\t * @return {Number}\n\t * @private\n\t */\n\tTone.Frequency.prototype._ticksToUnits = function(ticks){\n\t\treturn 1 / ((ticks * 60) / (Tone.Transport.bpm.value * Tone.Transport.PPQ));\n\t};\n\n\t/**\n\t * Return the value of the beats in the current units\n\t * @param {Number} beats\n\t * @return {Number}\n\t * @private\n\t */\n\tTone.Frequency.prototype._beatsToUnits = function(beats){\n\t\treturn 1 / Tone.TimeBase.prototype._beatsToUnits.call(this, beats);\n\t};\n\n\t/**\n\t * Returns the value of a second in the current units\n\t * @param {Seconds} seconds\n\t * @return {Number}\n\t * @private\n\t */\n\tTone.Frequency.prototype._secondsToUnits = function(seconds){\n\t\treturn 1 / seconds;\n\t};\n\n\t/**\n\t * The default units if none are given.\n\t * @private\n\t */\n\tTone.Frequency.prototype._defaultUnits = \"hz\";\n\n\t///////////////////////////////////////////////////////////////////////////\n\t//\tFREQUENCY CONVERSIONS\n\t///////////////////////////////////////////////////////////////////////////\n\n\t/**\n\t * Note to scale index\n\t * @type {Object}\n\t */\n\tvar noteToScaleIndex = {\n\t\t\"cbb\" : -2, \"cb\" : -1, \"c\" : 0, \"c#\" : 1, \"cx\" : 2, \n\t\t\"dbb\" : 0, \"db\" : 1, \"d\" : 2, \"d#\" : 3, \"dx\" : 4,\n\t\t\"ebb\" : 2, \"eb\" : 3, \"e\" : 4, \"e#\" : 5, \"ex\" : 6, \n\t\t\"fbb\" : 3, \"fb\" : 4, \"f\" : 5, \"f#\" : 6, \"fx\" : 7,\n\t\t\"gbb\" : 5, \"gb\" : 6, \"g\" : 7, \"g#\" : 8, \"gx\" : 9,\n\t\t\"abb\" : 7, \"ab\" : 8, \"a\" : 9, \"a#\" : 10, \"ax\" : 11,\n\t\t\"bbb\" : 9, \"bb\" : 10, \"b\" : 11, \"b#\" : 12, \"bx\" : 13,\n\t};\n\n\t/**\n\t * scale index to note (sharps)\n\t * @type {Array}\n\t */\n\tvar scaleIndexToNote = [\"C\", \"C#\", \"D\", \"D#\", \"E\", \"F\", \"F#\", \"G\", \"G#\", \"A\", \"A#\", \"B\"];\n\n\t/**\n\t * The [concert pitch](https://en.wikipedia.org/wiki/Concert_pitch)\n\t * A4's values in Hertz. \n\t * @type {Frequency}\n\t * @static\n\t */\n\tTone.Frequency.A4 = 440;\n\n\t/**\n\t * Convert a MIDI note to frequency value. \n\t * @param {MIDI} midi The midi number to convert.\n\t * @return {Frequency} the corresponding frequency value\n\t * @example\n\t * tone.midiToFrequency(69); // returns 440\n\t */\n\tTone.Frequency.prototype.midiToFrequency = function(midi){\n\t\treturn Tone.Frequency.A4 * Math.pow(2, (midi - 69) / 12);\n\t};\n\n\t/**\n\t * Convert a frequency value to a MIDI note.\n\t * @param {Frequency} frequency The value to frequency value to convert.\n\t * @returns {MIDI}\n\t * @example\n\t * tone.midiToFrequency(440); // returns 69\n\t */\n\tTone.Frequency.prototype.frequencyToMidi = function(frequency){\n\t\treturn 69 + 12 * Math.log(frequency / Tone.Frequency.A4) / Math.LN2;\n\t};\n\n\treturn Tone.Frequency;\n});","define([\"Tone/core/Tone\", \"Tone/type/Time\"], function (Tone) {\n\n\t/**\n\t * @class Tone.TransportTime is a the time along the Transport's\n\t * timeline. It is similar to Tone.Time, but instead of evaluating\n\t * against the AudioContext's clock, it is evaluated against\n\t * the Transport's position. See [TransportTime wiki](https://github.com/Tonejs/Tone.js/wiki/TransportTime).\n\t * @constructor\n\t * @param {Time} val The time value as a number or string\n\t * @param {String=} units Unit values\n\t * @extends {Tone.Time}\n\t */\n\tTone.TransportTime = function(val, units){\n\t\tif (this instanceof Tone.TransportTime){\n\t\t\t\n\t\t\tTone.Time.call(this, val, units);\n\n\t\t} else {\n\t\t\treturn new Tone.TransportTime(val, units);\n\t\t}\n\t};\n\n\tTone.extend(Tone.TransportTime, Tone.Time);\n\n\t//clone the expressions so that \n\t//we can add more without modifying the original\n\tTone.TransportTime.prototype._unaryExpressions = Object.create(Tone.Time.prototype._unaryExpressions);\n\n\t/**\n\t * Adds an additional unary expression\n\t * which quantizes values to the next subdivision\n\t * @type {Object}\n\t * @private\n\t */\n\tTone.TransportTime.prototype._unaryExpressions.quantize = {\n\t\tregexp : /^@/,\n\t\tmethod : function(rh){\n\t\t\tvar subdivision = this._secondsToTicks(rh());\n\t\t\tvar multiple = Math.ceil(Tone.Transport.ticks / subdivision);\n\t\t\treturn this._ticksToUnits(multiple * subdivision);\n\t\t}\n\t};\n\n\t/**\n\t * Convert seconds into ticks\n\t * @param {Seconds} seconds\n\t * @return {Ticks}\n\t * @private\n\t */\n\tTone.TransportTime.prototype._secondsToTicks = function(seconds){\n\t\tvar quarterTime = this._beatsToUnits(1);\n\t\tvar quarters = seconds / quarterTime;\n\t\treturn Math.round(quarters * Tone.Transport.PPQ);\n\t};\n\n\t/**\n\t * Evaluate the time expression. Returns values in ticks\n\t * @return {Ticks}\n\t */\n\tTone.TransportTime.prototype.valueOf = function(){\n\t\tvar val = this._secondsToTicks(this._expr());\n\t\treturn val + (this._plusNow ? Tone.Transport.ticks : 0);\n\t};\n\n\t/**\n\t * Return the time in ticks.\n\t * @return {Ticks}\n\t */\n\tTone.TransportTime.prototype.toTicks = function(){\n\t\treturn this.valueOf();\n\t};\n\n\t/**\n\t * Return the time in seconds.\n\t * @return {Seconds}\n\t */\n\tTone.TransportTime.prototype.toSeconds = function(){\n\t\tvar val = this._expr();\n\t\treturn val + (this._plusNow ? Tone.Transport.seconds : 0);\n\t};\n\n\t/**\n\t * Return the time as a frequency value\n\t * @return {Frequency} \n\t */\n\tTone.TransportTime.prototype.toFrequency = function(){\n\t\treturn 1/this.toSeconds();\n\t};\n\n\treturn Tone.TransportTime;\n});","'use strict';\n\ndefine(function (require) {\n\n var p5sound = require('master');\n var Add = require('Tone/signal/Add');\n var Mult = require('Tone/signal/Multiply');\n var Scale = require('Tone/signal/Scale');\n var TimelineSignal = require('Tone/signal/TimelineSignal');\n\n /**\n *
Envelopes are pre-defined amplitude distribution over time.\n * Typically, envelopes are used to control the output volume\n * of an object, a series of fades referred to as Attack, Decay,\n * Sustain and Release (\n * ADSR\n * ). Envelopes can also control other Web Audio Parameters—for example, a p5.Envelope can\n * control an Oscillator's frequency like this: osc.freq(env).
\n *
Use setRange to change the attack/release level.\n * Use setADSR to change attackTime, decayTime, sustainPercent and releaseTime.
\n *
Use the play method to play the entire envelope,\n * the ramp method for a pingable trigger,\n * or triggerAttack/\n * triggerRelease to trigger noteOn/noteOff.
\n * var attackLevel = 1.0;\n * var releaseLevel = 0;\n *\n * var attackTime = 0.001;\n * var decayTime = 0.2;\n * var susPercent = 0.2;\n * var releaseTime = 0.5;\n *\n * var env, triOsc;\n *\n * function setup() {\n * var cnv = createCanvas(100, 100);\n *\n * textAlign(CENTER);\n * text('click to play', width/2, height/2);\n *\n * env = new p5.Envelope();\n * env.setADSR(attackTime, decayTime, susPercent, releaseTime);\n * env.setRange(attackLevel, releaseLevel);\n *\n * triOsc = new p5.Oscillator('triangle');\n * triOsc.amp(env);\n * triOsc.start();\n * triOsc.freq(220);\n *\n * cnv.mousePressed(playEnv);\n * }\n *\n * function playEnv() {\n * env.play();\n * }\n *
\n */\n p5.Envelope = function(t1, l1, t2, l2, t3, l3) {\n /**\n * Time until envelope reaches attackLevel\n * @property attackTime\n */\n this.aTime = t1 || 0.1;\n /**\n * Level once attack is complete.\n * @property attackLevel\n */\n this.aLevel = l1 || 1;\n /**\n * Time until envelope reaches decayLevel.\n * @property decayTime\n */\n this.dTime = t2 || 0.5;\n /**\n * Level after decay. The envelope will sustain here until it is released.\n * @property decayLevel\n */\n this.dLevel = l2 || 0;\n /**\n * Duration of the release portion of the envelope.\n * @property releaseTime\n */\n this.rTime = t3 || 0;\n /**\n * Level at the end of the release.\n * @property releaseLevel\n */\n this.rLevel = l3 || 0;\n\n this._rampHighPercentage = 0.98;\n\n this._rampLowPercentage = 0.02;\n\n\n this.output = p5sound.audiocontext.createGain();\n\n this.control = new TimelineSignal();\n\n this._init(); // this makes sure the envelope starts at zero\n\n this.control.connect(this.output); // connect to the output\n\n this.connection = null; // store connection\n\n //array of math operation signal chaining\n this.mathOps = [this.control];\n\n //whether envelope should be linear or exponential curve\n this.isExponential = false;\n\n // oscillator or buffer source to clear on env complete\n // to save resources if/when it is retriggered\n this.sourceToClear = null;\n\n // set to true if attack is set, then false on release\n this.wasTriggered = false;\n\n\n // add to the soundArray so we can dispose of the env later\n p5sound.soundArray.push(this);\n };\n\n // this init function just smooths the starting value to zero and gives a start point for the timeline\n // - it was necessary to remove glitches at the beginning.\n p5.Envelope.prototype._init = function () {\n var now = p5sound.audiocontext.currentTime;\n var t = now;\n this.control.setTargetAtTime(0.00001, t, .001);\n //also, compute the correct time constants\n this._setRampAD(this.aTime, this.dTime);\n };\n\n /**\n * Reset the envelope with a series of time/value pairs.\n *\n * @method set\n * @for p5.Envelope\n * @param {Number} attackTime Time (in seconds) before level\n * reaches attackLevel\n * @param {Number} attackLevel Typically an amplitude between\n * 0.0 and 1.0\n * @param {Number} decayTime Time\n * @param {Number} decayLevel Amplitude (In a standard ADSR envelope,\n * decayLevel = sustainLevel)\n * @param {Number} releaseTime Release Time (in seconds)\n * @param {Number} releaseLevel Amplitude\n * @example\n *
\n * var t1 = 0.1; // attack time in seconds\n * var l1 = 0.7; // attack level 0.0 to 1.0\n * var t2 = 0.3; // decay time in seconds\n * var l2 = 0.1; // decay level 0.0 to 1.0\n * var t3 = 0.2; // sustain time in seconds\n * var l3 = 0.5; // sustain level 0.0 to 1.0\n * // release level defaults to zero\n *\n * var env;\n * var triOsc;\n *\n * function setup() {\n * background(0);\n * noStroke();\n * fill(255);\n * textAlign(CENTER);\n * text('click to play', width/2, height/2);\n *\n * env = new p5.Envelope(t1, l1, t2, l2, t3, l3);\n * triOsc = new p5.Oscillator('triangle');\n * triOsc.amp(env); // give the env control of the triOsc's amp\n * triOsc.start();\n * }\n *\n * // mouseClick triggers envelope if over canvas\n * function mouseClicked() {\n * // is mouse over canvas?\n * if (mouseX > 0 && mouseX < width && mouseY > 0 && mouseY < height) {\n * env.play(triOsc);\n * }\n * }\n *
\n *\n */\n p5.Envelope.prototype.set = function(t1, l1, t2, l2, t3, l3) {\n this.aTime = t1;\n this.aLevel = l1;\n this.dTime = t2 || 0;\n this.dLevel = l2 || 0;\n this.rTime = t3 || 0;\n this.rLevel = l3 || 0;\n\n // set time constants for ramp\n this._setRampAD(t1, t2);\n };\n\n /**\n * Set values like a traditional\n * \n * ADSR envelope\n * .\n *\n * @method setADSR\n * @for p5.Envelope\n * @param {Number} attackTime Time (in seconds before envelope\n * reaches Attack Level\n * @param {Number} [decayTime] Time (in seconds) before envelope\n * reaches Decay/Sustain Level\n * @param {Number} [susRatio] Ratio between attackLevel and releaseLevel, on a scale from 0 to 1,\n * where 1.0 = attackLevel, 0.0 = releaseLevel.\n * The susRatio determines the decayLevel and the level at which the\n * sustain portion of the envelope will sustain.\n * For example, if attackLevel is 0.4, releaseLevel is 0,\n * and susAmt is 0.5, the decayLevel would be 0.2. If attackLevel is\n * increased to 1.0 (using setRange),\n * then decayLevel would increase proportionally, to become 0.5.\n * @param {Number} [releaseTime] Time in seconds from now (defaults to 0)\n * @example\n *
\n * var attackLevel = 1.0;\n * var releaseLevel = 0;\n *\n * var attackTime = 0.001;\n * var decayTime = 0.2;\n * var susPercent = 0.2;\n * var releaseTime = 0.5;\n *\n * var env, triOsc;\n *\n * function setup() {\n * var cnv = createCanvas(100, 100);\n *\n * textAlign(CENTER);\n * text('click to play', width/2, height/2);\n *\n * env = new p5.Envelope();\n * env.setADSR(attackTime, decayTime, susPercent, releaseTime);\n * env.setRange(attackLevel, releaseLevel);\n *\n * triOsc = new p5.Oscillator('triangle');\n * triOsc.amp(env);\n * triOsc.start();\n * triOsc.freq(220);\n *\n * cnv.mousePressed(playEnv);\n * }\n *\n * function playEnv() {\n * env.play();\n * }\n *
\n */\n p5.Envelope.prototype.setADSR = function(aTime, dTime, sPercent, rTime) {\n this.aTime = aTime;\n this.dTime = dTime || 0;\n\n // lerp\n this.sPercent = sPercent || 0;\n this.dLevel = typeof sPercent !== 'undefined' ? sPercent * (this.aLevel - this.rLevel) + this.rLevel : 0;\n\n this.rTime = rTime || 0;\n\n // also set time constants for ramp\n this._setRampAD(aTime, dTime);\n };\n\n /**\n * Set max (attackLevel) and min (releaseLevel) of envelope.\n *\n * @method setRange\n * @for p5.Envelope\n * @param {Number} aLevel attack level (defaults to 1)\n * @param {Number} rLevel release level (defaults to 0)\n * @example\n *
\n * var attackLevel = 1.0;\n * var releaseLevel = 0;\n *\n * var attackTime = 0.001;\n * var decayTime = 0.2;\n * var susPercent = 0.2;\n * var releaseTime = 0.5;\n *\n * var env, triOsc;\n *\n * function setup() {\n * var cnv = createCanvas(100, 100);\n *\n * textAlign(CENTER);\n * text('click to play', width/2, height/2);\n *\n * env = new p5.Envelope();\n * env.setADSR(attackTime, decayTime, susPercent, releaseTime);\n * env.setRange(attackLevel, releaseLevel);\n *\n * triOsc = new p5.Oscillator('triangle');\n * triOsc.amp(env);\n * triOsc.start();\n * triOsc.freq(220);\n *\n * cnv.mousePressed(playEnv);\n * }\n *\n * function playEnv() {\n * env.play();\n * }\n *
\n */\n p5.Envelope.prototype.setRange = function(aLevel, rLevel) {\n this.aLevel = aLevel || 1;\n this.rLevel = rLevel || 0;\n\n // not sure if this belongs here:\n\n // {Number} [dLevel] decay/sustain level (optional)\n // if (typeof(dLevel) !== 'undefined') {\n // this.dLevel = dLevel\n // } else if (this.sPercent) {\n // this.dLevel = this.sPercent ? this.sPercent * (this.aLevel - this.rLevel) + this.rLevel : 0;\n // }\n };\n\n // private (undocumented) method called when ADSR is set to set time constants for ramp\n //\n // Set the \n // time constants for simple exponential ramps.\n // The larger the time constant value, the slower the\n // transition will be.\n //\n // method _setRampAD\n // param {Number} attackTimeConstant attack time constant\n // param {Number} decayTimeConstant decay time constant\n //\n p5.Envelope.prototype._setRampAD = function(t1, t2) {\n this._rampAttackTime = this.checkExpInput(t1);\n this._rampDecayTime = this.checkExpInput(t2);\n\n var TCDenominator = 1.0;\n /// Aatish Bhatia's calculation for time constant for rise(to adjust 1/1-e calculation to any percentage)\n TCDenominator = Math.log(1.0 / this.checkExpInput(1.0 - this._rampHighPercentage));\n this._rampAttackTC = t1 / this.checkExpInput(TCDenominator);\n TCDenominator = Math.log(1.0 / this._rampLowPercentage);\n this._rampDecayTC = t2 / this.checkExpInput(TCDenominator);\n };\n\n // private method\n p5.Envelope.prototype.setRampPercentages = function(p1, p2) {\n //set the percentages that the simple exponential ramps go to\n this._rampHighPercentage = this.checkExpInput(p1);\n this._rampLowPercentage = this.checkExpInput(p2);\n var TCDenominator = 1.0;\n //now re-compute the time constants based on those percentages\n /// Aatish Bhatia's calculation for time constant for rise(to adjust 1/1-e calculation to any percentage)\n TCDenominator = Math.log(1.0 / this.checkExpInput(1.0 - this._rampHighPercentage));\n this._rampAttackTC = this._rampAttackTime / this.checkExpInput(TCDenominator);\n TCDenominator = Math.log(1.0 / this._rampLowPercentage);\n this._rampDecayTC = this._rampDecayTime / this.checkExpInput(TCDenominator);\n };\n\n\n /**\n * Assign a parameter to be controlled by this envelope.\n * If a p5.Sound object is given, then the p5.Envelope will control its\n * output gain. If multiple inputs are provided, the env will\n * control all of them.\n *\n * @method setInput\n * @for p5.Envelope\n * @param {Object} [...inputs] A p5.sound object or\n * Web Audio Param.\n */\n p5.Envelope.prototype.setInput = function() {\n for (var i = 0; i\n * Web Audio Audio Param.\n *\n * @method play\n * @for p5.Envelope\n * @param {Object} unit A p5.sound object or\n * Web Audio Param.\n * @param {Number} [startTime] time from now (in seconds) at which to play\n * @param {Number} [sustainTime] time to sustain before releasing the envelope\n * @example\n *
\n * var attackLevel = 1.0;\n * var releaseLevel = 0;\n *\n * var attackTime = 0.001;\n * var decayTime = 0.2;\n * var susPercent = 0.2;\n * var releaseTime = 0.5;\n *\n * var env, triOsc;\n *\n * function setup() {\n * var cnv = createCanvas(100, 100);\n *\n * textAlign(CENTER);\n * text('click to play', width/2, height/2);\n *\n * env = new p5.Envelope();\n * env.setADSR(attackTime, decayTime, susPercent, releaseTime);\n * env.setRange(attackLevel, releaseLevel);\n *\n * triOsc = new p5.Oscillator('triangle');\n * triOsc.amp(env);\n * triOsc.start();\n * triOsc.freq(220);\n *\n * cnv.mousePressed(playEnv);\n * }\n *\n * function playEnv() {\n * // trigger env on triOsc, 0 seconds from now\n * // After decay, sustain for 0.2 seconds before release\n * env.play(triOsc, 0, 0.2);\n * }\n *
\n */\n p5.Envelope.prototype.play = function(unit, secondsFromNow, susTime) {\n var tFromNow = secondsFromNow || 0;\n var susTime = susTime || 0;\n\n if (unit) {\n if (this.connection !== unit) {\n this.connect(unit);\n }\n }\n\n this.triggerAttack(unit, tFromNow);\n\n this.triggerRelease(unit, tFromNow + this.aTime + this.dTime + susTime);\n\n };\n\n /**\n * Trigger the Attack, and Decay portion of the Envelope.\n * Similar to holding down a key on a piano, but it will\n * hold the sustain level until you let go. Input can be\n * any p5.sound object, or a \n * Web Audio Param.\n *\n * @method triggerAttack\n * @for p5.Envelope\n * @param {Object} unit p5.sound Object or Web Audio Param\n * @param {Number} secondsFromNow time from now (in seconds)\n * @example\n *
\n *\n * var attackLevel = 1.0;\n * var releaseLevel = 0;\n *\n * var attackTime = 0.001;\n * var decayTime = 0.3;\n * var susPercent = 0.4;\n * var releaseTime = 0.5;\n *\n * var env, triOsc;\n *\n * function setup() {\n * var cnv = createCanvas(100, 100);\n * background(200);\n * textAlign(CENTER);\n * text('click to play', width/2, height/2);\n *\n * env = new p5.Envelope();\n * env.setADSR(attackTime, decayTime, susPercent, releaseTime);\n * env.setRange(attackLevel, releaseLevel);\n *\n * triOsc = new p5.Oscillator('triangle');\n * triOsc.amp(env);\n * triOsc.start();\n * triOsc.freq(220);\n *\n * cnv.mousePressed(envAttack);\n * }\n *\n * function envAttack() {\n * console.log('trigger attack');\n * env.triggerAttack();\n *\n * background(0,255,0);\n * text('attack!', width/2, height/2);\n * }\n *\n * function mouseReleased() {\n * env.triggerRelease();\n *\n * background(200);\n * text('click to play', width/2, height/2);\n * }\n *
\n */\n p5.Envelope.prototype.triggerAttack = function(unit, secondsFromNow) {\n var now = p5sound.audiocontext.currentTime;\n var tFromNow = secondsFromNow || 0;\n var t = now + tFromNow;\n this.lastAttack = t;\n this.wasTriggered = true;\n\n if (unit) {\n if (this.connection !== unit) {\n this.connect(unit);\n }\n }\n\n // get and set value (with linear ramp) to anchor automation\n var valToSet = this.control.getValueAtTime(t);\n\n if (this.isExponential === true)\n {\n this.control.exponentialRampToValueAtTime(this.checkExpInput(valToSet), t);\n }\n else\n {\n this.control.linearRampToValueAtTime(valToSet, t);\n }\n\n // after each ramp completes, cancel scheduled values\n // (so they can be overridden in case env has been re-triggered)\n // then, set current value (with linearRamp to avoid click)\n // then, schedule the next automation...\n\n // attack\n t += this.aTime;\n if (this.isExponential === true)\n {\n this.control.exponentialRampToValueAtTime(this.checkExpInput(this.aLevel), t);\n valToSet = this.checkExpInput(this.control.getValueAtTime(t));\n this.control.cancelScheduledValues(t);\n this.control.exponentialRampToValueAtTime(valToSet, t);\n }\n else\n {\n this.control.linearRampToValueAtTime(this.aLevel, t);\n valToSet = this.control.getValueAtTime(t);\n this.control.cancelScheduledValues(t);\n this.control.linearRampToValueAtTime(valToSet, t);\n\n }\n\n // decay to decay level (if using ADSR, then decay level == sustain level)\n t += this.dTime;\n if (this.isExponential === true)\n {\n this.control.exponentialRampToValueAtTime(this.checkExpInput(this.dLevel), t);\n valToSet = this.checkExpInput(this.control.getValueAtTime(t));\n this.control.cancelScheduledValues(t);\n this.control.exponentialRampToValueAtTime(valToSet, t);\n }\n else\n {\n this.control.linearRampToValueAtTime(this.dLevel, t);\n valToSet = this.control.getValueAtTime(t);\n this.control.cancelScheduledValues(t);\n this.control.linearRampToValueAtTime(valToSet, t);\n }\n };\n\n /**\n * Trigger the Release of the Envelope. This is similar to releasing\n * the key on a piano and letting the sound fade according to the\n * release level and release time.\n *\n * @method triggerRelease\n * @for p5.Envelope\n * @param {Object} unit p5.sound Object or Web Audio Param\n * @param {Number} secondsFromNow time to trigger the release\n * @example\n *
\n *\n * var attackLevel = 1.0;\n * var releaseLevel = 0;\n *\n * var attackTime = 0.001;\n * var decayTime = 0.3;\n * var susPercent = 0.4;\n * var releaseTime = 0.5;\n *\n * var env, triOsc;\n *\n * function setup() {\n * var cnv = createCanvas(100, 100);\n * background(200);\n * textAlign(CENTER);\n * text('click to play', width/2, height/2);\n *\n * env = new p5.Envelope();\n * env.setADSR(attackTime, decayTime, susPercent, releaseTime);\n * env.setRange(attackLevel, releaseLevel);\n *\n * triOsc = new p5.Oscillator('triangle');\n * triOsc.amp(env);\n * triOsc.start();\n * triOsc.freq(220);\n *\n * cnv.mousePressed(envAttack);\n * }\n *\n * function envAttack() {\n * console.log('trigger attack');\n * env.triggerAttack();\n *\n * background(0,255,0);\n * text('attack!', width/2, height/2);\n * }\n *\n * function mouseReleased() {\n * env.triggerRelease();\n *\n * background(200);\n * text('click to play', width/2, height/2);\n * }\n *
\n */\n p5.Envelope.prototype.triggerRelease = function(unit, secondsFromNow) {\n\n // only trigger a release if an attack was triggered\n if (!this.wasTriggered) {\n // this currently causes a bit of trouble:\n // if a later release has been scheduled (via the play function)\n // a new earlier release won't interrupt it, because\n // this.wasTriggered has already been set to false.\n // If we want new earlier releases to override, then we need to\n // keep track of the last release time, and if the new release time is\n // earlier, then use it.\n return;\n }\n\n var now = p5sound.audiocontext.currentTime;\n var tFromNow = secondsFromNow || 0;\n var t = now + tFromNow;\n\n if (unit) {\n if (this.connection !== unit) {\n this.connect(unit);\n }\n }\n\n // get and set value (with linear or exponential ramp) to anchor automation\n var valToSet = this.control.getValueAtTime(t);\n if (this.isExponential === true)\n {\n this.control.exponentialRampToValueAtTime(this.checkExpInput(valToSet), t);\n }\n else\n {\n this.control.linearRampToValueAtTime(valToSet, t);\n }\n\n // release\n t += this.rTime;\n\n if (this.isExponential === true)\n {\n this.control.exponentialRampToValueAtTime(this.checkExpInput(this.rLevel), t);\n valToSet = this.checkExpInput(this.control.getValueAtTime(t));\n this.control.cancelScheduledValues(t);\n this.control.exponentialRampToValueAtTime(valToSet, t);\n }\n else\n {\n this.control.linearRampToValueAtTime(this.rLevel, t);\n valToSet = this.control.getValueAtTime(t);\n this.control.cancelScheduledValues(t);\n this.control.linearRampToValueAtTime(valToSet, t);\n }\n\n this.wasTriggered = false;\n };\n\n /**\n * Exponentially ramp to a value using the first two\n * values from setADSR(attackTime, decayTime)\n * as \n * time constants for simple exponential ramps.\n * If the value is higher than current value, it uses attackTime,\n * while a decrease uses decayTime.\n *\n * @method ramp\n * @for p5.Envelope\n * @param {Object} unit p5.sound Object or Web Audio Param\n * @param {Number} secondsFromNow When to trigger the ramp\n * @param {Number} v Target value\n * @param {Number} [v2] Second target value (optional)\n * @example\n *
\n * var env, osc, amp, cnv;\n *\n * var attackTime = 0.001;\n * var decayTime = 0.2;\n * var attackLevel = 1;\n * var decayLevel = 0;\n *\n * function setup() {\n * cnv = createCanvas(100, 100);\n * fill(0,255,0);\n * noStroke();\n *\n * env = new p5.Envelope();\n * env.setADSR(attackTime, decayTime);\n *\n * osc = new p5.Oscillator();\n * osc.amp(env);\n * osc.start();\n *\n * amp = new p5.Amplitude();\n *\n * cnv.mousePressed(triggerRamp);\n * }\n *\n * function triggerRamp() {\n * env.ramp(osc, 0, attackLevel, decayLevel);\n * }\n *\n * function draw() {\n * background(20,20,20);\n * text('click me', 10, 20);\n * var h = map(amp.getLevel(), 0, 0.4, 0, height);;\n *\n * rect(0, height, width, -h);\n * }\n *
\n */\n p5.Envelope.prototype.ramp = function(unit, secondsFromNow, v1, v2) {\n\n var now = p5sound.audiocontext.currentTime;\n var tFromNow = secondsFromNow || 0;\n var t = now + tFromNow;\n var destination1 = this.checkExpInput(v1);\n var destination2 = typeof v2 !== 'undefined' ? this.checkExpInput(v2) : undefined;\n\n // connect env to unit if not already connected\n if (unit) {\n if (this.connection !== unit) {\n this.connect(unit);\n }\n }\n\n //get current value\n var currentVal = this.checkExpInput(this.control.getValueAtTime(t));\n // this.control.cancelScheduledValues(t);\n\n //if it's going up\n if (destination1 > currentVal) {\n this.control.setTargetAtTime(destination1, t, this._rampAttackTC);\n t += this._rampAttackTime;\n }\n\n //if it's going down\n else if (destination1 < currentVal) {\n this.control.setTargetAtTime(destination1, t, this._rampDecayTC);\n t += this._rampDecayTime;\n }\n\n // Now the second part of envelope begins\n if (destination2 === undefined) return;\n\n //if it's going up\n if (destination2 > destination1) {\n this.control.setTargetAtTime(destination2, t, this._rampAttackTC);\n }\n\n //if it's going down\n else if (destination2 < destination1) {\n this.control.setTargetAtTime(destination2, t, this._rampDecayTC);\n }\n };\n\n\n p5.Envelope.prototype.connect = function(unit) {\n this.connection = unit;\n\n // assume we're talking about output gain\n // unless given a different audio param\n if (unit instanceof p5.Oscillator ||\n unit instanceof p5.SoundFile ||\n unit instanceof p5.AudioIn ||\n unit instanceof p5.Reverb ||\n unit instanceof p5.Noise ||\n unit instanceof p5.Filter ||\n unit instanceof p5.Delay\n ) {\n unit = unit.output.gain;\n }\n if (unit instanceof AudioParam) {\n //set the initial value\n unit.setValueAtTime(0, p5sound.audiocontext.currentTime);\n }\n if (unit instanceof p5.Signal) {\n unit.setValue(0);\n }\n this.output.connect(unit);\n };\n\n p5.Envelope.prototype.disconnect = function() {\n if (this.output) {\n this.output.disconnect();\n }\n };\n\n\n // Signal Math\n\n /**\n * Add a value to the p5.Oscillator's output amplitude,\n * and return the oscillator. Calling this method\n * again will override the initial add() with new values.\n *\n * @method add\n * @for p5.Envelope\n * @param {Number} number Constant number to add\n * @return {p5.Envelope} Envelope Returns this envelope\n * with scaled output\n */\n p5.Envelope.prototype.add = function(num) {\n var add = new Add(num);\n var thisChain = this.mathOps.length;\n var nextChain = this.output;\n return p5.prototype._mathChain(this, add, thisChain, nextChain, Add);\n };\n\n /**\n * Multiply the p5.Envelope's output amplitude\n * by a fixed value. Calling this method\n * again will override the initial mult() with new values.\n *\n * @method mult\n * @for p5.Envelope\n * @param {Number} number Constant number to multiply\n * @return {p5.Envelope} Envelope Returns this envelope\n * with scaled output\n */\n p5.Envelope.prototype.mult = function(num) {\n var mult = new Mult(num);\n var thisChain = this.mathOps.length;\n var nextChain = this.output;\n return p5.prototype._mathChain(this, mult, thisChain, nextChain, Mult);\n };\n\n /**\n * Scale this envelope's amplitude values to a given\n * range, and return the envelope. Calling this method\n * again will override the initial scale() with new values.\n *\n * @method scale\n * @for p5.Envelope\n * @param {Number} inMin input range minumum\n * @param {Number} inMax input range maximum\n * @param {Number} outMin input range minumum\n * @param {Number} outMax input range maximum\n * @return {p5.Envelope} Envelope Returns this envelope\n * with scaled output\n */\n p5.Envelope.prototype.scale = function(inMin, inMax, outMin, outMax) {\n var scale = new Scale(inMin, inMax, outMin, outMax);\n var thisChain = this.mathOps.length;\n var nextChain = this.output;\n return p5.prototype._mathChain(this, scale, thisChain, nextChain, Scale);\n };\n\n\n // get rid of the oscillator\n p5.Envelope.prototype.dispose = function() {\n // remove reference from soundArray\n var index = p5sound.soundArray.indexOf(this);\n p5sound.soundArray.splice(index, 1);\n\n this.disconnect();\n if (this.control) {\n this.control.dispose();\n this.control = null;\n }\n for (var i = 1; i < this.mathOps.length; i++) {\n this.mathOps[i].dispose();\n }\n };\n\n // Different name for backwards compatibility, replicates p5.Envelope class\n p5.Env = function(t1, l1, t2, l2, t3, l3) {\n console.warn('WARNING: p5.Env is now deprecated and may be removed in future versions. ' +\n 'Please use the new p5.Envelope instead.');\n p5.Envelope.call(this, t1, l1, t2, l2, t3, l3);\n };\n p5.Env.prototype = Object.create(p5.Envelope.prototype);\n\n});\n","'use strict';\n\ndefine(function (require) {\n\n var p5sound = require('master');\n require('oscillator');\n\n /**\n * Creates a Pulse object, an oscillator that implements\n * Pulse Width Modulation.\n * The pulse is created with two oscillators.\n * Accepts a parameter for frequency, and to set the\n * width between the pulses. See \n * p5.Oscillator for a full list of methods.\n *\n * @class p5.Pulse\n * @extends p5.Oscillator\n * @constructor\n * @param {Number} [freq] Frequency in oscillations per second (Hz)\n * @param {Number} [w] Width between the pulses (0 to 1.0,\n * defaults to 0)\n * @example\n *
Note: This uses the getUserMedia/\n * Stream API, which is not supported by certain browsers. Access in Chrome browser\n * is limited to localhost and https, but access over http may be limited.
\n *\n * @class p5.AudioIn\n * @constructor\n * @param {Function} [errorCallback] A function to call if there is an error\n * accessing the AudioIn. For example,\n * Safari and iOS devices do not\n * currently allow microphone access.\n * @example\n *
\n * var mic;\n * function setup(){\n * mic = new p5.AudioIn()\n * mic.start();\n * }\n * function draw(){\n * background(0);\n * micLevel = mic.getLevel();\n * ellipse(width/2, constrain(height-micLevel*height*5, 0, height), 10, 10);\n * }\n *
\n */\n p5.AudioIn = function(errorCallback) {\n // set up audio input\n /**\n * @property {GainNode} input\n */\n this.input = p5sound.audiocontext.createGain();\n /**\n * @property {GainNode} output\n */\n this.output = p5sound.audiocontext.createGain();\n\n /**\n * @property {MediaStream|null} stream\n */\n this.stream = null;\n /**\n * @property {MediaStreamAudioSourceNode|null} mediaStream\n */\n this.mediaStream = null;\n /**\n * @property {Number|null} currentSource\n */\n this.currentSource = null;\n\n /**\n * Client must allow browser to access their microphone / audioin source.\n * Default: false. Will become true when the client enables acces.\n *\n * @property {Boolean} enabled\n */\n this.enabled = false;\n\n /**\n * Input amplitude, connect to it by default but not to master out\n *\n * @property {p5.Amplitude} amplitude\n */\n this.amplitude = new p5.Amplitude();\n this.output.connect(this.amplitude.input);\n\n if (!window.MediaStreamTrack || !window.navigator.mediaDevices || !window.navigator.mediaDevices.getUserMedia) {\n errorCallback ? errorCallback() : window.alert('This browser does not support MediaStreamTrack and mediaDevices');\n }\n\n // add to soundArray so we can dispose on close\n p5sound.soundArray.push(this);\n };\n\n /**\n * Start processing audio input. This enables the use of other\n * AudioIn methods like getLevel(). Note that by default, AudioIn\n * is not connected to p5.sound's output. So you won't hear\n * anything unless you use the connect() method. \n *\n * Certain browsers limit access to the user's microphone. For example,\n * Chrome only allows access from localhost and over https. For this reason,\n * you may want to include an errorCallback—a function that is called in case\n * the browser won't provide mic access.\n *\n * @method start\n * @for p5.AudioIn\n * @param {Function} [successCallback] Name of a function to call on\n * success.\n * @param {Function} [errorCallback] Name of a function to call if\n * there was an error. For example,\n * some browsers do not support\n * getUserMedia.\n */\n p5.AudioIn.prototype.start = function(successCallback, errorCallback) {\n var self = this;\n\n if (this.stream) {\n this.stop();\n }\n\n // set the audio source\n var audioSource = p5sound.inputSources[self.currentSource];\n var constraints = {\n audio: {\n sampleRate: p5sound.audiocontext.sampleRate,\n echoCancellation: false\n }\n };\n\n // if developers determine which source to use\n if (p5sound.inputSources[this.currentSource]) {\n constraints.audio.deviceId = audioSource.deviceId;\n }\n\n window.navigator.mediaDevices.getUserMedia( constraints )\n .then( function(stream) {\n self.stream = stream;\n self.enabled = true;\n // Wrap a MediaStreamSourceNode around the live input\n self.mediaStream = p5sound.audiocontext.createMediaStreamSource(stream);\n self.mediaStream.connect(self.output);\n // only send to the Amplitude reader, so we can see it but not hear it.\n self.amplitude.setInput(self.output);\n if (successCallback) successCallback();\n })\n .catch( function(err) {\n if (errorCallback) errorCallback(err);\n else console.error(err);\n });\n };\n\n /**\n * Turn the AudioIn off. If the AudioIn is stopped, it cannot getLevel().\n * If re-starting, the user may be prompted for permission access.\n *\n * @method stop\n * @for p5.AudioIn\n */\n p5.AudioIn.prototype.stop = function() {\n if (this.stream) {\n this.stream.getTracks().forEach(function(track) {\n track.stop();\n });\n\n this.mediaStream.disconnect();\n\n delete this.mediaStream;\n delete this.stream;\n }\n };\n\n /**\n * Connect to an audio unit. If no parameter is provided, will\n * connect to the master output (i.e. your speakers). \n *\n * @method connect\n * @for p5.AudioIn\n * @param {Object} [unit] An object that accepts audio input,\n * such as an FFT\n */\n p5.AudioIn.prototype.connect = function(unit) {\n if (unit) {\n if (unit.hasOwnProperty('input')) {\n this.output.connect(unit.input);\n }\n else if (unit.hasOwnProperty('analyser')) {\n this.output.connect(unit.analyser);\n }\n else {\n this.output.connect(unit);\n }\n }\n else {\n this.output.connect(p5sound.input);\n }\n };\n\n /**\n * Disconnect the AudioIn from all audio units. For example, if\n * connect() had been called, disconnect() will stop sending\n * signal to your speakers. \n *\n * @method disconnect\n * @for p5.AudioIn\n */\n p5.AudioIn.prototype.disconnect = function() {\n if (this.output) {\n this.output.disconnect();\n // stay connected to amplitude even if not outputting to p5\n this.output.connect(this.amplitude.input);\n }\n };\n\n /**\n * Read the Amplitude (volume level) of an AudioIn. The AudioIn\n * class contains its own instance of the Amplitude class to help\n * make it easy to get a microphone's volume level. Accepts an\n * optional smoothing value (0.0 < 1.0). NOTE: AudioIn must\n * .start() before using .getLevel(). \n *\n * @method getLevel\n * @for p5.AudioIn\n * @param {Number} [smoothing] Smoothing is 0.0 by default.\n * Smooths values based on previous values.\n * @return {Number} Volume level (between 0.0 and 1.0)\n */\n p5.AudioIn.prototype.getLevel = function(smoothing) {\n if (smoothing) {\n this.amplitude.smoothing = smoothing;\n }\n return this.amplitude.getLevel();\n };\n\n /**\n * Set amplitude (volume) of a mic input between 0 and 1.0. \n *\n * @method amp\n * @for p5.AudioIn\n * @param {Number} vol between 0 and 1.0\n * @param {Number} [time] ramp time (optional)\n */\n p5.AudioIn.prototype.amp = function(vol, t) {\n if (t) {\n var rampTime = t || 0;\n var currentVol = this.output.gain.value;\n this.output.gain.cancelScheduledValues(p5sound.audiocontext.currentTime);\n this.output.gain.setValueAtTime(currentVol, p5sound.audiocontext.currentTime);\n this.output.gain.linearRampToValueAtTime(vol, rampTime + p5sound.audiocontext.currentTime);\n } else {\n this.output.gain.cancelScheduledValues(p5sound.audiocontext.currentTime);\n this.output.gain.setValueAtTime(vol, p5sound.audiocontext.currentTime);\n }\n };\n\n /**\n * Returns a list of available input sources. This is a wrapper\n * for and it returns a Promise.\n *\n * @method getSources\n * @for p5.AudioIn\n * @param {Function} [successCallback] This callback function handles the sources when they\n * have been enumerated. The callback function\n * receives the deviceList array as its only argument\n * @param {Function} [errorCallback] This optional callback receives the error\n * message as its argument.\n * @returns {Promise} Returns a Promise that can be used in place of the callbacks, similar\n * to the enumerateDevices() method\n * @example\n *
\n */\n p5.AudioIn.prototype.getSources = function (onSuccess, onError) {\n return new Promise( function(resolve, reject) {\n window.navigator.mediaDevices.enumerateDevices()\n .then( function(devices) {\n p5sound.inputSources = devices.filter(function(device) {\n return device.kind === 'audioinput';\n });\n resolve(p5sound.inputSources);\n if (onSuccess) {\n onSuccess(p5sound.inputSources);\n }\n })\n .catch( function(error) {\n reject(error);\n if (onError) {\n onError(error);\n } else {\n console.error('This browser does not support MediaStreamTrack.getSources()');\n }\n });\n });\n };\n\n /**\n * Set the input source. Accepts a number representing a\n * position in the array returned by getSources().\n * This is only available in browsers that support\n * navigator.mediaDevices.enumerateDevices(). \n *\n * @method setSource\n * @for p5.AudioIn\n * @param {number} num position of input source in the array\n */\n p5.AudioIn.prototype.setSource = function(num) {\n if (p5sound.inputSources.length > 0 && num < p5sound.inputSources.length) {\n // set the current source\n this.currentSource = num;\n console.log('set source to ', p5sound.inputSources[this.currentSource]);\n } else {\n console.log('unable to set input source');\n }\n\n // restart stream if currently active\n if (this.stream && this.stream.active) {\n this.start();\n }\n };\n\n // private method\n p5.AudioIn.prototype.dispose = function() {\n // remove reference from soundArray\n var index = p5sound.soundArray.indexOf(this);\n p5sound.soundArray.splice(index, 1);\n\n this.stop();\n\n if (this.output) {\n this.output.disconnect();\n }\n if (this.amplitude) {\n this.amplitude.disconnect();\n }\n delete this.amplitude;\n delete this.output;\n };\n\n});\n","define([\"Tone/core/Tone\", \"Tone/signal/Signal\", \"Tone/signal/Expr\", \n\t\"Tone/signal/EqualPowerGain\", \"Tone/core/Gain\"], function(Tone){\n\n\t\"use strict\";\n\n\t/**\n\t * @class Tone.Crossfade provides equal power fading between two inputs. \n\t * More on crossfading technique [here](https://en.wikipedia.org/wiki/Fade_(audio_engineering)#Crossfading).\n\t *\n\t * @constructor\n\t * @extends {Tone}\n\t * @param {NormalRange} [initialFade=0.5]\n\t * @example\n\t * var crossFade = new Tone.CrossFade(0.5);\n\t * //connect effect A to crossfade from\n\t * //effect output 0 to crossfade input 0\n\t * effectA.connect(crossFade, 0, 0);\n\t * //connect effect B to crossfade from\n\t * //effect output 0 to crossfade input 1\n\t * effectB.connect(crossFade, 0, 1);\n\t * crossFade.fade.value = 0;\n\t * // ^ only effectA is output\n\t * crossFade.fade.value = 1;\n\t * // ^ only effectB is output\n\t * crossFade.fade.value = 0.5;\n\t * // ^ the two signals are mixed equally. \n\t */\t\t\n\tTone.CrossFade = function(initialFade){\n\n\t\tthis.createInsOuts(2, 1);\n\n\t\t/**\n\t\t * Alias for input[0]. \n\t\t * @type {Tone.Gain}\n\t\t */\n\t\tthis.a = this.input[0] = new Tone.Gain();\n\n\t\t/**\n\t\t * Alias for input[1]. \n\t\t * @type {Tone.Gain}\n\t\t */\n\t\tthis.b = this.input[1] = new Tone.Gain();\n\n\t\t/**\n\t\t * \tThe mix between the two inputs. A fade value of 0\n\t\t * \twill output 100% input[0] and \n\t\t * \ta value of 1 will output 100% input[1]. \n\t\t * @type {NormalRange}\n\t\t * @signal\n\t\t */\n\t\tthis.fade = new Tone.Signal(this.defaultArg(initialFade, 0.5), Tone.Type.NormalRange);\n\n\t\t/**\n\t\t * equal power gain cross fade\n\t\t * @private\n\t\t * @type {Tone.EqualPowerGain}\n\t\t */\n\t\tthis._equalPowerA = new Tone.EqualPowerGain();\n\n\t\t/**\n\t\t * equal power gain cross fade\n\t\t * @private\n\t\t * @type {Tone.EqualPowerGain}\n\t\t */\n\t\tthis._equalPowerB = new Tone.EqualPowerGain();\n\t\t\n\t\t/**\n\t\t * invert the incoming signal\n\t\t * @private\n\t\t * @type {Tone}\n\t\t */\n\t\tthis._invert = new Tone.Expr(\"1 - $0\");\n\n\t\t//connections\n\t\tthis.a.connect(this.output);\n\t\tthis.b.connect(this.output);\n\t\tthis.fade.chain(this._equalPowerB, this.b.gain);\n\t\tthis.fade.chain(this._invert, this._equalPowerA, this.a.gain);\n\t\tthis._readOnly(\"fade\");\n\t};\n\n\tTone.extend(Tone.CrossFade);\n\n\t/**\n\t * clean up\n\t * @returns {Tone.CrossFade} this\n\t */\n\tTone.CrossFade.prototype.dispose = function(){\n\t\tTone.prototype.dispose.call(this);\n\t\tthis._writable(\"fade\");\n\t\tthis._equalPowerA.dispose();\n\t\tthis._equalPowerA = null;\n\t\tthis._equalPowerB.dispose();\n\t\tthis._equalPowerB = null;\n\t\tthis.fade.dispose();\n\t\tthis.fade = null;\n\t\tthis._invert.dispose();\n\t\tthis._invert = null;\n\t\tthis.a.dispose();\n\t\tthis.a = null;\n\t\tthis.b.dispose();\n\t\tthis.b = null;\n\t\treturn this;\n\t};\n\n\treturn Tone.CrossFade;\n});\n","define([\"Tone/core/Tone\", \"Tone/signal/Add\", \"Tone/signal/Subtract\", \"Tone/signal/Multiply\", \n\t\"Tone/signal/GreaterThan\", \"Tone/signal/GreaterThanZero\", \"Tone/signal/Abs\", \"Tone/signal/Negate\", \n\t\"Tone/signal/Modulo\", \"Tone/signal/Pow\", \"Tone/signal/AudioToGain\"], \n\tfunction(Tone){\n\n\t\"use strict\";\n\n\t/**\n\t * @class Evaluate an expression at audio rate.
\n\t * Parsing code modified from https://code.google.com/p/tapdigit/\n\t * Copyright 2011 2012 Ariya Hidayat, New BSD License\n\t *\n\t * @extends {Tone.SignalBase}\n\t * @constructor\n\t * @param {string} expr the expression to generate\n\t * @example\n\t * //adds the signals from input[0] and input[1].\n\t * var expr = new Tone.Expr(\"$0 + $1\");\n\t */\n\tTone.Expr = function(){\n\n\t\tvar expr = this._replacements(Array.prototype.slice.call(arguments));\n\t\tvar inputCount = this._parseInputs(expr);\n\n\t\t/**\n\t\t * hold onto all of the nodes for disposal\n\t\t * @type {Array}\n\t\t * @private\n\t\t */\n\t\tthis._nodes = [];\n\n\t\t/**\n\t\t * The inputs. The length is determined by the expression. \n\t\t * @type {Array}\n\t\t */\n\t\tthis.input = new Array(inputCount);\n\n\t\t//create a gain for each input\n\t\tfor (var i = 0; i < inputCount; i++){\n\t\t\tthis.input[i] = this.context.createGain();\n\t\t}\n\n\t\t//parse the syntax tree\n\t\tvar tree = this._parseTree(expr);\n\t\t//evaluate the results\n\t\tvar result;\n\t\ttry {\n\t\t\tresult = this._eval(tree);\n\t\t} catch (e){\n\t\t\tthis._disposeNodes();\n\t\t\tthrow new Error(\"Tone.Expr: Could evaluate expression: \"+expr);\n\t\t}\n\n\t\t/**\n\t\t * The output node is the result of the expression\n\t\t * @type {Tone}\n\t\t */\n\t\tthis.output = result;\n\t};\n\n\tTone.extend(Tone.Expr, Tone.SignalBase);\n\n\t//some helpers to cut down the amount of code\n\tfunction applyBinary(Constructor, args, self){\n\t\tvar op = new Constructor();\n\t\tself._eval(args[0]).connect(op, 0, 0);\n\t\tself._eval(args[1]).connect(op, 0, 1);\n\t\treturn op;\n\t}\n\tfunction applyUnary(Constructor, args, self){\n\t\tvar op = new Constructor();\n\t\tself._eval(args[0]).connect(op, 0, 0);\n\t\treturn op;\n\t}\n\tfunction getNumber(arg){\n\t\treturn arg ? parseFloat(arg) : undefined;\n\t}\n\tfunction literalNumber(arg){\n\t\treturn arg && arg.args ? parseFloat(arg.args) : undefined;\n\t}\n\n\t/*\n\t * the Expressions that Tone.Expr can parse.\n\t *\n\t * each expression belongs to a group and contains a regexp \n\t * for selecting the operator as well as that operators method\n\t * \n\t * @type {Object}\n\t * @private\n\t */\n\tTone.Expr._Expressions = {\n\t\t//values\n\t\t\"value\" : {\n\t\t\t\"signal\" : {\n\t\t\t\tregexp : /^\\d+\\.\\d+|^\\d+/,\n\t\t\t\tmethod : function(arg){\n\t\t\t\t\tvar sig = new Tone.Signal(getNumber(arg));\n\t\t\t\t\treturn sig;\n\t\t\t\t}\n\t\t\t},\n\t\t\t\"input\" : {\n\t\t\t\tregexp : /^\\$\\d/,\n\t\t\t\tmethod : function(arg, self){\n\t\t\t\t\treturn self.input[getNumber(arg.substr(1))];\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\t\t//syntactic glue\n\t\t\"glue\" : {\n\t\t\t\"(\" : {\n\t\t\t\tregexp : /^\\(/,\n\t\t\t},\n\t\t\t\")\" : {\n\t\t\t\tregexp : /^\\)/,\n\t\t\t},\n\t\t\t\",\" : {\n\t\t\t\tregexp : /^,/,\n\t\t\t}\n\t\t},\n\t\t//functions\n\t\t\"func\" : {\n\t\t\t\"abs\" : {\n\t\t\t\tregexp : /^abs/,\n\t\t\t\tmethod : applyUnary.bind(this, Tone.Abs)\n\t\t\t},\n\t\t\t\"mod\" : {\n\t\t\t\tregexp : /^mod/,\n\t\t\t\tmethod : function(args, self){\n\t\t\t\t\tvar modulus = literalNumber(args[1]);\n\t\t\t\t\tvar op = new Tone.Modulo(modulus);\n\t\t\t\t\tself._eval(args[0]).connect(op);\n\t\t\t\t\treturn op;\n\t\t\t\t}\n\t\t\t},\n\t\t\t\"pow\" : {\n\t\t\t\tregexp : /^pow/,\n\t\t\t\tmethod : function(args, self){\n\t\t\t\t\tvar exp = literalNumber(args[1]);\n\t\t\t\t\tvar op = new Tone.Pow(exp);\n\t\t\t\t\tself._eval(args[0]).connect(op);\n\t\t\t\t\treturn op;\n\t\t\t\t}\n\t\t\t},\n\t\t\t\"a2g\" : {\n\t\t\t\tregexp : /^a2g/,\n\t\t\t\tmethod : function(args, self){\n\t\t\t\t\tvar op = new Tone.AudioToGain();\n\t\t\t\t\tself._eval(args[0]).connect(op);\n\t\t\t\t\treturn op;\n\t\t\t\t}\n\t\t\t},\n\t\t},\n\t\t//binary expressions\n\t\t\"binary\" : {\n\t\t\t\"+\" : {\n\t\t\t\tregexp : /^\\+/,\n\t\t\t\tprecedence : 1,\n\t\t\t\tmethod : applyBinary.bind(this, Tone.Add)\n\t\t\t},\n\t\t\t\"-\" : {\n\t\t\t\tregexp : /^\\-/,\n\t\t\t\tprecedence : 1,\n\t\t\t\tmethod : function(args, self){\n\t\t\t\t\t//both unary and binary op\n\t\t\t\t\tif (args.length === 1){\n\t\t\t\t\t\treturn applyUnary(Tone.Negate, args, self);\n\t\t\t\t\t} else {\n\t\t\t\t\t\treturn applyBinary(Tone.Subtract, args, self);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t},\n\t\t\t\"*\" : {\n\t\t\t\tregexp : /^\\*/,\n\t\t\t\tprecedence : 0,\n\t\t\t\tmethod : applyBinary.bind(this, Tone.Multiply)\n\t\t\t}\n\t\t},\n\t\t//unary expressions\n\t\t\"unary\" : {\n\t\t\t\"-\" : {\n\t\t\t\tregexp : /^\\-/,\n\t\t\t\tmethod : applyUnary.bind(this, Tone.Negate)\n\t\t\t},\n\t\t\t\"!\" : {\n\t\t\t\tregexp : /^\\!/,\n\t\t\t\tmethod : applyUnary.bind(this, Tone.NOT)\n\t\t\t},\n\t\t},\n\t};\n\t\t\n\t/**\n\t * @param {string} expr the expression string\n\t * @return {number} the input count\n\t * @private\n\t */\n\tTone.Expr.prototype._parseInputs = function(expr){\n\t\tvar inputArray = expr.match(/\\$\\d/g);\n\t\tvar inputMax = 0;\n\t\tif (inputArray !== null){\n\t\t\tfor (var i = 0; i < inputArray.length; i++){\n\t\t\t\tvar inputNum = parseInt(inputArray[i].substr(1)) + 1;\n\t\t\t\tinputMax = Math.max(inputMax, inputNum);\n\t\t\t}\n\t\t}\n\t\treturn inputMax;\n\t};\n\n\t/**\n\t * @param {Array} args \tan array of arguments\n\t * @return {string} the results of the replacements being replaced\n\t * @private\n\t */\n\tTone.Expr.prototype._replacements = function(args){\n\t\tvar expr = args.shift();\n\t\tfor (var i = 0; i < args.length; i++){\n\t\t\texpr = expr.replace(/\\%/i, args[i]);\n\t\t}\n\t\treturn expr;\n\t};\n\n\t/**\n\t * tokenize the expression based on the Expressions object\n\t * @param {string} expr \n\t * @return {Object} returns two methods on the tokenized list, next and peek\n\t * @private\n\t */\n\tTone.Expr.prototype._tokenize = function(expr){\n\t\tvar position = -1;\n\t\tvar tokens = [];\n\n\t\twhile(expr.length > 0){\n\t\t\texpr = expr.trim();\n\t\t\tvar token = getNextToken(expr);\n\t\t\ttokens.push(token);\n\t\t\texpr = expr.substr(token.value.length);\n\t\t}\n\n\t\tfunction getNextToken(expr){\n\t\t\tfor (var type in Tone.Expr._Expressions){\n\t\t\t\tvar group = Tone.Expr._Expressions[type];\n\t\t\t\tfor (var opName in group){\n\t\t\t\t\tvar op = group[opName];\n\t\t\t\t\tvar reg = op.regexp;\n\t\t\t\t\tvar match = expr.match(reg);\n\t\t\t\t\tif (match !== null){\n\t\t\t\t\t\treturn {\n\t\t\t\t\t\t\ttype : type,\n\t\t\t\t\t\t\tvalue : match[0],\n\t\t\t\t\t\t\tmethod : op.method\n\t\t\t\t\t\t};\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\tthrow new SyntaxError(\"Tone.Expr: Unexpected token \"+expr);\n\t\t}\n\n\t\treturn {\n\t\t\tnext : function(){\n\t\t\t\treturn tokens[++position];\n\t\t\t},\n\t\t\tpeek : function(){\n\t\t\t\treturn tokens[position + 1];\n\t\t\t}\n\t\t};\n\t};\n\n\t/**\n\t * recursively parse the string expression into a syntax tree\n\t * \n\t * @param {string} expr \n\t * @return {Object}\n\t * @private\n\t */\n\tTone.Expr.prototype._parseTree = function(expr){\n\t\tvar lexer = this._tokenize(expr);\n\t\tvar isUndef = this.isUndef.bind(this);\n\n\t\tfunction matchSyntax(token, syn) {\n\t\t\treturn !isUndef(token) && \n\t\t\t\ttoken.type === \"glue\" &&\n\t\t\t\ttoken.value === syn;\n\t\t}\n\n\t\tfunction matchGroup(token, groupName, prec) {\n\t\t\tvar ret = false;\n\t\t\tvar group = Tone.Expr._Expressions[groupName];\n\t\t\tif (!isUndef(token)){\n\t\t\t\tfor (var opName in group){\n\t\t\t\t\tvar op = group[opName];\n\t\t\t\t\tif (op.regexp.test(token.value)){\n\t\t\t\t\t\tif (!isUndef(prec)){\n\t\t\t\t\t\t\tif(op.precedence === prec){\t\n\t\t\t\t\t\t\t\treturn true;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\treturn true;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn ret;\n\t\t}\n\n\t\tfunction parseExpression(precedence) {\n\t\t\tif (isUndef(precedence)){\n\t\t\t\tprecedence = 5;\n\t\t\t}\n\t\t\tvar expr;\n\t\t\tif (precedence < 0){\n\t\t\t\texpr = parseUnary();\n\t\t\t} else {\n\t\t\t\texpr = parseExpression(precedence-1);\n\t\t\t}\n\t\t\tvar token = lexer.peek();\n\t\t\twhile (matchGroup(token, \"binary\", precedence)) {\n\t\t\t\ttoken = lexer.next();\n\t\t\t\texpr = {\n\t\t\t\t\toperator: token.value,\n\t\t\t\t\tmethod : token.method,\n\t\t\t\t\targs : [\n\t\t\t\t\t\texpr,\n\t\t\t\t\t\tparseExpression(precedence-1)\n\t\t\t\t\t]\n\t\t\t\t};\n\t\t\t\ttoken = lexer.peek();\n\t\t\t}\n\t\t\treturn expr;\n\t\t}\n\n\t\tfunction parseUnary() {\n\t\t\tvar token, expr;\n\t\t\ttoken = lexer.peek();\n\t\t\tif (matchGroup(token, \"unary\")) {\n\t\t\t\ttoken = lexer.next();\n\t\t\t\texpr = parseUnary();\n\t\t\t\treturn {\n\t\t\t\t\toperator: token.value,\n\t\t\t\t\tmethod : token.method,\n\t\t\t\t\targs : [expr]\n\t\t\t\t};\n\t\t\t}\n\t\t\treturn parsePrimary();\n\t\t}\n\n\t\tfunction parsePrimary() {\n\t\t\tvar token, expr;\n\t\t\ttoken = lexer.peek();\n\t\t\tif (isUndef(token)) {\n\t\t\t\tthrow new SyntaxError(\"Tone.Expr: Unexpected termination of expression\");\n\t\t\t}\n\t\t\tif (token.type === \"func\") {\n\t\t\t\ttoken = lexer.next();\n\t\t\t\treturn parseFunctionCall(token);\n\t\t\t}\n\t\t\tif (token.type === \"value\") {\n\t\t\t\ttoken = lexer.next();\n\t\t\t\treturn {\n\t\t\t\t\tmethod : token.method,\n\t\t\t\t\targs : token.value\n\t\t\t\t};\n\t\t\t}\n\t\t\tif (matchSyntax(token, \"(\")) {\n\t\t\t\tlexer.next();\n\t\t\t\texpr = parseExpression();\n\t\t\t\ttoken = lexer.next();\n\t\t\t\tif (!matchSyntax(token, \")\")) {\n\t\t\t\t\tthrow new SyntaxError(\"Expected )\");\n\t\t\t\t}\n\t\t\t\treturn expr;\n\t\t\t}\n\t\t\tthrow new SyntaxError(\"Tone.Expr: Parse error, cannot process token \" + token.value);\n\t\t}\n\n\t\tfunction parseFunctionCall(func) {\n\t\t\tvar token, args = [];\n\t\t\ttoken = lexer.next();\n\t\t\tif (!matchSyntax(token, \"(\")) {\n\t\t\t\tthrow new SyntaxError(\"Tone.Expr: Expected ( in a function call \\\"\" + func.value + \"\\\"\");\n\t\t\t}\n\t\t\ttoken = lexer.peek();\n\t\t\tif (!matchSyntax(token, \")\")) {\n\t\t\t\targs = parseArgumentList();\n\t\t\t}\n\t\t\ttoken = lexer.next();\n\t\t\tif (!matchSyntax(token, \")\")) {\n\t\t\t\tthrow new SyntaxError(\"Tone.Expr: Expected ) in a function call \\\"\" + func.value + \"\\\"\");\n\t\t\t}\n\t\t\treturn {\n\t\t\t\tmethod : func.method,\n\t\t\t\targs : args,\n\t\t\t\tname : name\n\t\t\t};\n\t\t}\n\n\t\tfunction parseArgumentList() {\n\t\t\tvar token, expr, args = [];\n\t\t\twhile (true) {\n\t\t\t\texpr = parseExpression();\n\t\t\t\tif (isUndef(expr)) {\n\t\t\t\t\t// TODO maybe throw exception?\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\targs.push(expr);\n\t\t\t\ttoken = lexer.peek();\n\t\t\t\tif (!matchSyntax(token, \",\")) {\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tlexer.next();\n\t\t\t}\n\t\t\treturn args;\n\t\t}\n\n\t\treturn parseExpression();\n\t};\n\n\t/**\n\t * recursively evaluate the expression tree\n\t * @param {Object} tree \n\t * @return {AudioNode} the resulting audio node from the expression\n\t * @private\n\t */\n\tTone.Expr.prototype._eval = function(tree){\n\t\tif (!this.isUndef(tree)){\n\t\t\tvar node = tree.method(tree.args, this);\n\t\t\tthis._nodes.push(node);\n\t\t\treturn node;\n\t\t} \n\t};\n\n\t/**\n\t * dispose all the nodes\n\t * @private\n\t */\n\tTone.Expr.prototype._disposeNodes = function(){\n\t\tfor (var i = 0; i < this._nodes.length; i++){\n\t\t\tvar node = this._nodes[i];\n\t\t\tif (this.isFunction(node.dispose)) {\n\t\t\t\tnode.dispose();\n\t\t\t} else if (this.isFunction(node.disconnect)) {\n\t\t\t\tnode.disconnect();\n\t\t\t}\n\t\t\tnode = null;\n\t\t\tthis._nodes[i] = null;\n\t\t}\n\t\tthis._nodes = null;\n\t};\n\n\t/**\n\t * clean up\n\t */\n\tTone.Expr.prototype.dispose = function(){\n\t\tTone.prototype.dispose.call(this);\n\t\tthis._disposeNodes();\n\t};\n\n\treturn Tone.Expr;\n});","define([\"Tone/core/Tone\", \"Tone/signal/GreaterThanZero\", \"Tone/signal/Subtract\", \"Tone/signal/Signal\"], \n\tfunction(Tone){\n\n\t\"use strict\";\n\n\t/**\n\t * @class Output 1 if the signal is greater than the value, otherwise outputs 0.\n\t * can compare two signals or a signal and a number. \n\t * \n\t * @constructor\n\t * @extends {Tone.Signal}\n\t * @param {number} [value=0] the value to compare to the incoming signal\n\t * @example\n\t * var gt = new Tone.GreaterThan(2);\n\t * var sig = new Tone.Signal(4).connect(gt);\n\t * //output of gt is equal 1. \n\t */\n\tTone.GreaterThan = function(value){\n\n\t\tthis.createInsOuts(2, 0);\n\t\t\n\t\t/**\n\t\t * subtract the amount from the incoming signal\n\t\t * @type {Tone.Subtract}\n\t\t * @private\n\t\t */\n\t\tthis._param = this.input[0] = new Tone.Subtract(value);\n\t\tthis.input[1] = this._param.input[1];\n\n\t\t/**\n\t\t * compare that amount to zero\n\t\t * @type {Tone.GreaterThanZero}\n\t\t * @private\n\t\t */\n\t\tthis._gtz = this.output = new Tone.GreaterThanZero();\n\n\t\t//connect\n\t\tthis._param.connect(this._gtz);\n\t};\n\n\tTone.extend(Tone.GreaterThan, Tone.Signal);\n\n\t/**\n\t * dispose method\n\t * @returns {Tone.GreaterThan} this\n\t */\n\tTone.GreaterThan.prototype.dispose = function(){\n\t\tTone.prototype.dispose.call(this);\n\t\tthis._param.dispose();\n\t\tthis._param = null;\n\t\tthis._gtz.dispose();\n\t\tthis._gtz = null;\n\t\treturn this;\n\t};\n\n\treturn Tone.GreaterThan;\n});","define([\"Tone/core/Tone\", \"Tone/signal/WaveShaper\", \"Tone/signal/SignalBase\"], \nfunction(Tone){\n\n\t\"use strict\";\n\n\t/**\n\t * @class Return the absolute value of an incoming signal. \n\t * \n\t * @constructor\n\t * @extends {Tone.SignalBase}\n\t * @example\n\t * var signal = new Tone.Signal(-1);\n\t * var abs = new Tone.Abs();\n\t * signal.connect(abs);\n\t * //the output of abs is 1. \n\t */\n\tTone.Abs = function(){\n\t\t/**\n\t\t * @type {Tone.LessThan}\n\t\t * @private\n\t\t */\n\t\tthis._abs = this.input = this.output = new Tone.WaveShaper(function(val){\n\t\t\tif (val === 0){\n\t\t\t\treturn 0;\n\t\t\t} else {\n\t\t\t\treturn Math.abs(val);\n\t\t\t}\n\t\t}, 127);\n\t};\n\n\tTone.extend(Tone.Abs, Tone.SignalBase);\n\n\t/**\n\t * dispose method\n\t * @returns {Tone.Abs} this\n\t */\n\tTone.Abs.prototype.dispose = function(){\n\t\tTone.prototype.dispose.call(this);\n\t\tthis._abs.dispose();\n\t\tthis._abs = null;\n\t\treturn this;\n\t}; \n\n\treturn Tone.Abs;\n});","define([\"Tone/core/Tone\", \"Tone/signal/WaveShaper\", \"Tone/signal/Multiply\", \"Tone/signal/Subtract\"], \nfunction(Tone){\n\n\t\"use strict\";\n\n\t/**\n\t * @class Signal-rate modulo operator. Only works in AudioRange [-1, 1] and for modulus\n\t * values in the NormalRange. \n\t *\n\t * @constructor\n\t * @extends {Tone.SignalBase}\n\t * @param {NormalRange} modulus The modulus to apply.\n\t * @example\n\t * var mod = new Tone.Modulo(0.2)\n\t * var sig = new Tone.Signal(0.5).connect(mod);\n\t * //mod outputs 0.1\n\t */\n\tTone.Modulo = function(modulus){\n\n\t\tthis.createInsOuts(1, 0);\n\n\t\t/**\n\t\t * A waveshaper gets the integer multiple of \n\t\t * the input signal and the modulus.\n\t\t * @private\n\t\t * @type {Tone.WaveShaper}\n\t\t */\n\t\tthis._shaper = new Tone.WaveShaper(Math.pow(2, 16));\n\n\t\t/**\n\t\t * the integer multiple is multiplied by the modulus\n\t\t * @type {Tone.Multiply}\n\t\t * @private\n\t\t */\n\t\tthis._multiply = new Tone.Multiply();\n\n\t\t/**\n\t\t * and subtracted from the input signal\n\t\t * @type {Tone.Subtract}\n\t\t * @private\n\t\t */\n\t\tthis._subtract = this.output = new Tone.Subtract();\n\n\t\t/**\n\t\t * the modulus signal\n\t\t * @type {Tone.Signal}\n\t\t * @private\n\t\t */\n\t\tthis._modSignal = new Tone.Signal(modulus);\n\n\t\t//connections\n\t\tthis.input.fan(this._shaper, this._subtract);\n\t\tthis._modSignal.connect(this._multiply, 0, 0);\n\t\tthis._shaper.connect(this._multiply, 0, 1);\n\t\tthis._multiply.connect(this._subtract, 0, 1);\n\t\tthis._setWaveShaper(modulus);\n\t};\n\n\tTone.extend(Tone.Modulo, Tone.SignalBase);\n\n\t/**\n\t * @param {number} mod the modulus to apply\n\t * @private\n\t */\n\tTone.Modulo.prototype._setWaveShaper = function(mod){\n\t\tthis._shaper.setMap(function(val){\n\t\t\tvar multiple = Math.floor((val + 0.0001) / mod);\n\t\t\treturn multiple;\n\t\t});\n\t};\n\n\t/**\n\t * The modulus value.\n\t * @memberOf Tone.Modulo#\n\t * @type {NormalRange}\n\t * @name value\n\t */\n\tObject.defineProperty(Tone.Modulo.prototype, \"value\", {\n\t\tget : function(){\n\t\t\treturn this._modSignal.value;\n\t\t},\n\t\tset : function(mod){\n\t\t\tthis._modSignal.value = mod;\n\t\t\tthis._setWaveShaper(mod);\n\t\t}\n\t});\n\n\t/**\n\t * clean up\n\t * @returns {Tone.Modulo} this\n\t */\n\tTone.Modulo.prototype.dispose = function(){\n\t\tTone.prototype.dispose.call(this);\n\t\tthis._shaper.dispose();\n\t\tthis._shaper = null;\n\t\tthis._multiply.dispose();\n\t\tthis._multiply = null;\n\t\tthis._subtract.dispose();\n\t\tthis._subtract = null;\n\t\tthis._modSignal.dispose();\n\t\tthis._modSignal = null;\n\t\treturn this;\n\t};\n\n\treturn Tone.Modulo;\n});","define([\"Tone/core/Tone\", \"Tone/signal/WaveShaper\"], function(Tone){\n\n\t\"use strict\";\n\n\t/**\n\t * @class Pow applies an exponent to the incoming signal. The incoming signal\n\t * must be AudioRange.\n\t *\n\t * @extends {Tone.SignalBase}\n\t * @constructor\n\t * @param {Positive} exp The exponent to apply to the incoming signal, must be at least 2. \n\t * @example\n\t * var pow = new Tone.Pow(2);\n\t * var sig = new Tone.Signal(0.5).connect(pow);\n\t * //output of pow is 0.25. \n\t */\n\tTone.Pow = function(exp){\n\n\t\t/**\n\t\t * the exponent\n\t\t * @private\n\t\t * @type {number}\n\t\t */\n\t\tthis._exp = this.defaultArg(exp, 1);\n\n\t\t/**\n\t\t * @type {WaveShaperNode}\n\t\t * @private\n\t\t */\n\t\tthis._expScaler = this.input = this.output = new Tone.WaveShaper(this._expFunc(this._exp), 8192);\n\t};\n\n\tTone.extend(Tone.Pow, Tone.SignalBase);\n\n\t/**\n\t * The value of the exponent.\n\t * @memberOf Tone.Pow#\n\t * @type {number}\n\t * @name value\n\t */\n\tObject.defineProperty(Tone.Pow.prototype, \"value\", {\n\t\tget : function(){\n\t\t\treturn this._exp;\n\t\t},\n\t\tset : function(exp){\n\t\t\tthis._exp = exp;\n\t\t\tthis._expScaler.setMap(this._expFunc(this._exp));\n\t\t}\n\t});\n\n\n\t/**\n\t * the function which maps the waveshaper\n\t * @param {number} exp\n\t * @return {function}\n\t * @private\n\t */\n\tTone.Pow.prototype._expFunc = function(exp){\n\t\treturn function(val){\n\t\t\treturn Math.pow(Math.abs(val), exp);\n\t\t};\n\t};\n\n\t/**\n\t * Clean up.\n\t * @returns {Tone.Pow} this\n\t */\n\tTone.Pow.prototype.dispose = function(){\n\t\tTone.prototype.dispose.call(this);\n\t\tthis._expScaler.dispose();\n\t\tthis._expScaler = null;\n\t\treturn this;\n\t};\n\n\treturn Tone.Pow;\n});","define([\"Tone/core/Tone\", \"Tone/signal/WaveShaper\", \"Tone/signal/Signal\"], function(Tone){\n\n\t\"use strict\";\n\n\t/**\n\t * @class AudioToGain converts an input in AudioRange [-1,1] to NormalRange [0,1]. \n\t * See Tone.GainToAudio.\n\t *\n\t * @extends {Tone.SignalBase}\n\t * @constructor\n\t * @example\n\t * var a2g = new Tone.AudioToGain();\n\t */\n\tTone.AudioToGain = function(){\n\n\t\t/**\n\t\t * @type {WaveShaperNode}\n\t\t * @private\n\t\t */\n\t\tthis._norm = this.input = this.output = new Tone.WaveShaper(function(x){\n\t\t\treturn (x + 1) / 2;\n\t\t});\n\t};\n\n\tTone.extend(Tone.AudioToGain, Tone.SignalBase);\n\n\t/**\n\t * clean up\n\t * @returns {Tone.AudioToGain} this\n\t */\n\tTone.AudioToGain.prototype.dispose = function(){\n\t\tTone.prototype.dispose.call(this);\n\t\tthis._norm.dispose();\n\t\tthis._norm = null;\n\t\treturn this;\n\t};\n\n\treturn Tone.AudioToGain;\n});","define([\"Tone/core/Tone\", \"Tone/signal/WaveShaper\"], function(Tone){\n\n\t\"use strict\";\n\n\t/**\n\t * @class Convert an incoming signal between 0, 1 to an equal power gain scale.\n\t *\n\t * @extends {Tone.SignalBase}\n\t * @constructor\n\t * @example\n\t * var eqPowGain = new Tone.EqualPowerGain();\n\t */\n\tTone.EqualPowerGain = function(){\n\n\t\t/**\n\t\t * @type {Tone.WaveShaper}\n\t\t * @private\n\t\t */\n\t\tthis._eqPower = this.input = this.output = new Tone.WaveShaper(function(val){\n\t\t\tif (Math.abs(val) < 0.001){\n\t\t\t\t//should output 0 when input is 0\n\t\t\t\treturn 0;\n\t\t\t} else {\n\t\t\t\treturn this.equalPowerScale(val);\n\t\t\t}\n\t\t}.bind(this), 4096);\n\t};\n\n\tTone.extend(Tone.EqualPowerGain, Tone.SignalBase);\n\n\t/**\n\t * clean up\n\t * @returns {Tone.EqualPowerGain} this\n\t */\n\tTone.EqualPowerGain.prototype.dispose = function(){\n\t\tTone.prototype.dispose.call(this);\n\t\tthis._eqPower.dispose();\n\t\tthis._eqPower = null;\n\t\treturn this;\n\t};\n\n\treturn Tone.EqualPowerGain;\n});","'use strict';\n\ndefine(function (require) {\n\n var Effect = require('effect');\n var EQFilter = require('eqFilter');\n\n /**\n * p5.EQ is an audio effect that performs the function of a multiband\n * audio equalizer. Equalization is used to adjust the balance of\n * frequency compoenents of an audio signal. This process is commonly used\n * in sound production and recording to change the waveform before it reaches\n * a sound output device. EQ can also be used as an audio effect to create\n * interesting distortions by filtering out parts of the spectrum. p5.EQ is\n * built using a chain of Web Audio Biquad Filter Nodes and can be\n * instantiated with 3 or 8 bands. Bands can be added or removed from\n * the EQ by directly modifying p5.EQ.bands (the array that stores filters).\n *\n * This class extends p5.Effect.\n * Methods amp(), chain(),\n * drywet(), connect(), and\n * disconnect() are available.\n *\n * @class p5.EQ\n * @constructor\n * @extends p5.Effect\n * @param {Number} [_eqsize] Constructor will accept 3 or 8, defaults to 3\n * @return {Object} p5.EQ object\n *\n * @example\n *
\n * var eq;\n * var band_names;\n * var band_index;\n *\n * var soundFile, play;\n *\n * function preload() {\n * soundFormats('mp3', 'ogg');\n * soundFile = loadSound('assets/beat');\n * }\n *\n * function setup() {\n * eq = new p5.EQ(3);\n * soundFile.disconnect();\n * eq.process(soundFile);\n *\n * band_names = ['lows','mids','highs'];\n * band_index = 0;\n * play = false;\n * textAlign(CENTER);\n * }\n *\n * function draw() {\n * background(30);\n * noStroke();\n * fill(255);\n * text('click to kill',50,25);\n *\n * fill(255, 40, 255);\n * textSize(26);\n * text(band_names[band_index],50,55);\n *\n * fill(255);\n * textSize(9);\n * text('space = play/pause',50,80);\n * }\n *\n * //If mouse is over canvas, cycle to the next band and kill the frequency\n * function mouseClicked() {\n * for (var i = 0; i < eq.bands.length; i++) {\n * eq.bands[i].gain(0);\n * }\n * eq.bands[band_index].gain(-40);\n * if (mouseX > 0 && mouseX < width && mouseY < height && mouseY > 0) {\n * band_index === 2 ? band_index = 0 : band_index++;\n * }\n * }\n *\n * //use space bar to trigger play / pause\n * function keyPressed() {\n * if (key===' ') {\n * play = !play\n * play ? soundFile.loop() : soundFile.pause();\n * }\n * }\n *
\n */\n p5.EQ = function(_eqsize) {\n Effect.call(this);\n\n //p5.EQ can be of size (3) or (8), defaults to 3\n _eqsize = _eqsize === 3 || _eqsize === 8 ? _eqsize : 3;\n\n var factor;\n _eqsize === 3 ? factor = Math.pow(2,3) : factor = 2;\n\n /**\n * The p5.EQ is built with abstracted p5.Filter objects.\n * To modify any bands, use methods of the \n * p5.Filter API, especially `gain` and `freq`.\n * Bands are stored in an array, with indices 0 - 3, or 0 - 7\n * @property {Array} bands\n *\n */\n this.bands = [];\n\n\n var freq, res;\n for (var i = 0; i < _eqsize; i++) {\n if (i === _eqsize - 1) {\n freq = 21000;\n res = .01;\n } else if (i === 0) {\n freq = 100;\n res = .1;\n }\n else if (i===1) {\n freq = _eqsize === 3 ? 360 * factor : 360;\n res = 1;\n }else {\n freq = this.bands[i-1].freq() * factor;\n res = 1;\n }\n this.bands[i] = this._newBand(freq, res);\n\n if (i>0) {\n this.bands[i-1].connect(this.bands[i].biquad);\n } else {\n this.input.connect(this.bands[i].biquad);\n }\n }\n this.bands[_eqsize-1].connect(this.output);\n };\n p5.EQ.prototype = Object.create(Effect.prototype);\n\n /**\n * Process an input by connecting it to the EQ\n * @method process\n * @param {Object} src Audio source\n */\n p5.EQ.prototype.process = function (src) {\n src.connect(this.input);\n };\n\n // /**\n // * Set the frequency and gain of each band in the EQ. This method should be\n // * called with 3 or 8 frequency and gain pairs, depending on the size of the EQ.\n // * ex. eq.set(freq0, gain0, freq1, gain1, freq2, gain2);\n // *\n // * @method set\n // * @for p5.EQ\n // * @param {Number} [freq0] Frequency value for band with index 0\n // * @param {Number} [gain0] Gain value for band with index 0\n // * @param {Number} [freq1] Frequency value for band with index 1\n // * @param {Number} [gain1] Gain value for band with index 1\n // * @param {Number} [freq2] Frequency value for band with index 2\n // * @param {Number} [gain2] Gain value for band with index 2\n // * @param {Number} [freq3] Frequency value for band with index 3\n // * @param {Number} [gain3] Gain value for band with index 3\n // * @param {Number} [freq4] Frequency value for band with index 4\n // * @param {Number} [gain4] Gain value for band with index 4\n // * @param {Number} [freq5] Frequency value for band with index 5\n // * @param {Number} [gain5] Gain value for band with index 5\n // * @param {Number} [freq6] Frequency value for band with index 6\n // * @param {Number} [gain6] Gain value for band with index 6\n // * @param {Number} [freq7] Frequency value for band with index 7\n // * @param {Number} [gain7] Gain value for band with index 7\n // */\n p5.EQ.prototype.set = function() {\n if (arguments.length === this.bands.length * 2) {\n for (var i = 0; i < arguments.length; i+=2) {\n this.bands[i/2].freq(arguments[i]);\n this.bands[i/2].gain(arguments[i+1]);\n }\n }\n else {\n console.error('Argument mismatch. .set() should be called with ' + this.bands.length*2 +\n ' arguments. (one frequency and gain value pair for each band of the eq)');\n }\n };\n\n /**\n * Add a new band. Creates a p5.Filter and strips away everything but\n * the raw biquad filter. This method returns an abstracted p5.Filter,\n * which can be added to p5.EQ.bands, in order to create new EQ bands.\n * @private\n * @for p5.EQ\n * @method _newBand\n * @param {Number} freq\n * @param {Number} res\n * @return {Object} Abstracted Filter\n */\n p5.EQ.prototype._newBand = function(freq, res) {\n return new EQFilter(freq, res);\n };\n\n p5.EQ.prototype.dispose = function () {\n Effect.prototype.dispose.apply(this);\n\n if (this.bands) {\n while (this.bands.length > 0) {\n delete this.bands.pop().dispose();\n }\n delete this.bands;\n }\n };\n\n return p5.EQ;\n});\n","'use strict';\n\ndefine(function (require) {\n var Filter = require('filter');\n var p5sound = require('master');\n\n /**\n * EQFilter extends p5.Filter with constraints\n * necessary for the p5.EQ\n *\n * @private\n */\n var EQFilter = function(freq, res) {\n Filter.call(this, 'peaking');\n this.disconnect();\n this.set(freq, res);\n this.biquad.gain.value = 0;\n delete this.input;\n delete this.output;\n delete this._drywet;\n delete this.wet;\n\n };\n EQFilter.prototype = Object.create(Filter.prototype);\n\n EQFilter.prototype.amp = function() {\n console.warn('`amp()` is not available for p5.EQ bands. Use `.gain()`');\n };\n EQFilter.prototype.drywet = function() {\n console.warn('`drywet()` is not available for p5.EQ bands.');\n };\n EQFilter.prototype.connect = function(unit) {\n var u = unit || p5.soundOut.input;\n if (this.biquad) {\n this.biquad.connect(u.input ? u.input : u);\n } else {\n this.output.connect(u.input ? u.input : u);\n }\n };\n\n EQFilter.prototype.disconnect = function() {\n if (this.biquad) {\n this.biquad.disconnect();\n }\n };\n EQFilter.prototype.dispose = function() {\n // remove reference form soundArray\n var index = p5sound.soundArray.indexOf(this);\n p5sound.soundArray.splice(index, 1);\n this.disconnect();\n delete this.biquad;\n };\n\n return EQFilter;\n});\n","'use strict'\n\ndefine(function (require) {\n var p5sound = require('master');\n var Effect = require('effect');\n\n /**\n * Panner3D is based on the \n * Web Audio Spatial Panner Node.\n * This panner is a spatial processing node that allows audio to be positioned\n * and oriented in 3D space.\n *\n * The position is relative to an \n * Audio Context Listener, which can be accessed\n * by p5.soundOut.audiocontext.listener\n *\n *\n * @class p5.Panner3D\n * @constructor\n */\n\tp5.Panner3D = function() {\n Effect.call(this);\n\n /**\n * \n * Web Audio Spatial Panner Node\n *\n * Properties include\n * - panningModel: \"equal power\" or \"HRTF\"\n * - distanceModel: \"linear\", \"inverse\", or \"exponential\"\n *\n * @property {AudioNode} panner\n *\n */\n this.panner = this.ac.createPanner();\n this.panner.panningModel = 'HRTF';\n this.panner.distanceModel = 'linear';\n this.panner.connect(this.output);\n this.input.connect(this.panner);\n\t};\n\n p5.Panner3D.prototype = Object.create(Effect.prototype);\n\n\n /**\n * Connect an audio sorce\n *\n * @method process\n * @for p5.Panner3D\n * @param {Object} src Input source\n */\n p5.Panner3D.prototype.process = function(src) {\n src.connect(this.input);\n }\n /**\n * Set the X,Y,Z position of the Panner\n * @method set\n * @for p5.Panner3D\n * @param {Number} xVal\n * @param {Number} yVal\n * @param {Number} zVal\n * @param {Number} time\n * @return {Array} Updated x, y, z values as an array\n */\n p5.Panner3D.prototype.set = function(xVal, yVal, zVal, time) {\n this.positionX(xVal,time);\n this.positionY(yVal,time);\n this.positionZ(zVal,time);\n return [this.panner.positionX.value,\n this.panner.positionY.value,\n this.panner.positionZ.value];\n };\n\n /**\n * Getter and setter methods for position coordinates\n * @method positionX\n * @for p5.Panner3D\n * @return {Number} updated coordinate value\n */\n /**\n * Getter and setter methods for position coordinates\n * @method positionY\n * @for p5.Panner3D\n * @return {Number} updated coordinate value\n */\n /**\n * Getter and setter methods for position coordinates\n * @method positionZ\n * @for p5.Panner3D\n * @return {Number} updated coordinate value\n */\n p5.Panner3D.prototype.positionX = function(xVal, time) {\n var t = time || 0;\n if (typeof xVal === 'number') {\n this.panner.positionX.value = xVal;\n this.panner.positionX.cancelScheduledValues(this.ac.currentTime + 0.01 + t);\n this.panner.positionX.linearRampToValueAtTime(xVal, this.ac.currentTime + 0.02 + t);\n } else if (xVal) {\n xVal.connect(this.panner.positionX);\n }\n return this.panner.positionX.value;\n };\n p5.Panner3D.prototype.positionY = function(yVal, time) {\n var t = time || 0;\n if (typeof yVal === 'number') {\n this.panner.positionY.value = yVal;\n this.panner.positionY.cancelScheduledValues(this.ac.currentTime + 0.01 + t);\n this.panner.positionY.linearRampToValueAtTime(yVal, this.ac.currentTime + 0.02 + t);\n } else if (yVal) {\n yVal.connect(this.panner.positionY);\n }\n return this.panner.positionY.value;\n };\n p5.Panner3D.prototype.positionZ = function(zVal, time) {\n var t = time || 0;\n if (typeof zVal === 'number') {\n this.panner.positionZ.value = zVal;\n this.panner.positionZ.cancelScheduledValues(this.ac.currentTime + 0.01 + t);\n this.panner.positionZ.linearRampToValueAtTime(zVal, this.ac.currentTime + 0.02 + t);\n } else if (zVal) {\n zVal.connect(this.panner.positionZ);\n }\n return this.panner.positionZ.value;\n };\n\n /**\n * Set the X,Y,Z position of the Panner\n * @method orient\n * @for p5.Panner3D\n * @param {Number} xVal\n * @param {Number} yVal\n * @param {Number} zVal\n * @param {Number} time\n * @return {Array} Updated x, y, z values as an array\n */\n p5.Panner3D.prototype.orient = function(xVal, yVal, zVal, time) {\n this.orientX(xVal,time);\n this.orientY(yVal,time);\n this.orientZ(zVal,time);\n return [this.panner.orientationX.value,\n this.panner.orientationY.value,\n this.panner.orientationZ.value];\n };\n\n /**\n * Getter and setter methods for orient coordinates\n * @method orientX\n * @for p5.Panner3D\n * @return {Number} updated coordinate value\n */\n /**\n * Getter and setter methods for orient coordinates\n * @method orientY\n * @for p5.Panner3D\n * @return {Number} updated coordinate value\n */\n /**\n * Getter and setter methods for orient coordinates\n * @method orientZ\n * @for p5.Panner3D\n * @return {Number} updated coordinate value\n */\n p5.Panner3D.prototype.orientX = function(xVal, time) {\n var t = time || 0;\n if (typeof xVal === 'number') {\n this.panner.orientationX.value = xVal;\n this.panner.orientationX.cancelScheduledValues(this.ac.currentTime + 0.01 + t);\n this.panner.orientationX.linearRampToValueAtTime(xVal, this.ac.currentTime + 0.02 + t);\n } else if (xVal) {\n xVal.connect(this.panner.orientationX);\n }\n return this.panner.orientationX.value;\n };\n p5.Panner3D.prototype.orientY = function(yVal, time) {\n var t = time || 0;\n if (typeof yVal === 'number') {\n this.panner.orientationY.value = yVal;\n this.panner.orientationY.cancelScheduledValues(this.ac.currentTime + 0.01 + t);\n this.panner.orientationY.linearRampToValueAtTime(yVal, this.ac.currentTime + 0.02 + t);\n } else if (yVal) {\n yVal.connect(this.panner.orientationY);\n }\n return this.panner.orientationY.value;\n };\n p5.Panner3D.prototype.orientZ = function(zVal, time) {\n var t = time || 0;\n if (typeof zVal === 'number') {\n this.panner.orientationZ.value = zVal;\n this.panner.orientationZ.cancelScheduledValues(this.ac.currentTime + 0.01 + t);\n this.panner.orientationZ.linearRampToValueAtTime(zVal, this.ac.currentTime + 0.02 + t);\n } else if (zVal) {\n zVal.connect(this.panner.orientationZ);\n }\n return this.panner.orientationZ.value;\n };\n\n /**\n * Set the rolloff factor and max distance\n * @method setFalloff\n * @for p5.Panner3D\n * @param {Number} [maxDistance]\n * @param {Number} [rolloffFactor]\n */\n p5.Panner3D.prototype.setFalloff = function(maxDistance, rolloffFactor) {\n this.maxDist(maxDistance);\n this.rolloff(rolloffFactor);\n };\n /**\n * Maxium distance between the source and the listener\n * @method maxDist\n * @for p5.Panner3D\n * @param {Number} maxDistance\n * @return {Number} updated value\n */\n p5.Panner3D.prototype.maxDist = function(maxDistance){\n if (typeof maxDistance === 'number') {\n this.panner.maxDistance = maxDistance;\n }\n return this.panner.maxDistance;\n };\n\n /**\n * How quickly the volume is reduced as the source moves away from the listener\n * @method rollof\n * @for p5.Panner3D\n * @param {Number} rolloffFactor\n * @return {Number} updated value\n */\n p5.Panner3D.prototype.rolloff = function(rolloffFactor){\n if (typeof rolloffFactor === 'number') {\n this.panner.rolloffFactor = rolloffFactor;\n }\n return this.panner.rolloffFactor;\n };\n\n p5.Panner3D.dispose = function() {\n Effect.prototype.dispose.apply(this);\n if (this.panner) {\n this.panner.disconnect();\n delete this.panner;\n }\n };\n\n return p5.Panner3D;\n\n});\n","'use strict'\n\ndefine(function (require) {\n var p5sound = require('master');\n var Effect = require('effect');\n\n// /**\n// * listener is a class that can construct both a Spatial Panner\n// * and a Spatial Listener. The panner is based on the \n// * Web Audio Spatial Panner Node\n// * https://www.w3.org/TR/webaudio/#the-listenernode-interface\n// * This panner is a spatial processing node that allows audio to be positioned\n// * and oriented in 3D space. \n// *\n// * The Listener modifies the properties of the Audio Context Listener. \n// * Both objects types use the same methods. The default is a spatial panner.\n// *\n// * p5.Panner3D - Constructs a Spatial Panner \n// * p5.Listener3D - Constructs a Spatial Listener \n// *\n// * @class listener\n// * @constructor\n// * @return {Object} p5.Listener3D Object\n// *\n// * @param {Web Audio Node} listener Web Audio Spatial Panning Node\n// * @param {AudioParam} listener.panningModel \"equal power\" or \"HRTF\"\n// * @param {AudioParam} listener.distanceModel \"linear\", \"inverse\", or \"exponential\"\n// * @param {String} [type] [Specify construction of a spatial panner or listener]\n// */\n \n\tp5.Listener3D = function(type) {\n this.ac = p5sound.audiocontext;\n this.listener = this.ac.listener;\n\t}; \n\n// /**\n// * Connect an audio sorce\n// * @param {Object} src Input source\n// */\n p5.Listener3D.prototype.process = function(src) {\n src.connect(this.input);\n }\n// /**\n// * Set the X,Y,Z position of the Panner\n// * @param {[Number]} xVal\n// * @param {[Number]} yVal\n// * @param {[Number]} zVal\n// * @param {[Number]} time\n// * @return {[Array]} [Updated x, y, z values as an array]\n// */\n p5.Listener3D.prototype.position = function(xVal, yVal, zVal, time) {\n this.positionX(xVal,time);\n this.positionY(yVal,time);\n this.positionZ(zVal,time);\n return [this.listener.positionX.value, \n this.listener.positionY.value,\n this.listener.positionZ.value];\n };\n\n// /**\n// * Getter and setter methods for position coordinates\n// * @return {Number} [updated coordinate value]\n// */\n p5.Listener3D.prototype.positionX = function(xVal, time) {\n var t = time || 0;\n if (typeof xVal === 'number') {\n this.listener.positionX.value = xVal;\n this.listener.positionX.cancelScheduledValues(this.ac.currentTime + 0.01 + t);\n this.listener.positionX.linearRampToValueAtTime(xVal, this.ac.currentTime + 0.02 + t);\n } else if (xVal) {\n xVal.connect(this.listener.positionX);\n }\n return this.listener.positionX.value;\n };\n p5.Listener3D.prototype.positionY = function(yVal, time) {\n var t = time || 0;\n if (typeof yVal === 'number') {\n this.listener.positionY.value = yVal;\n this.listener.positionY.cancelScheduledValues(this.ac.currentTime + 0.01 + t);\n this.listener.positionY.linearRampToValueAtTime(yVal, this.ac.currentTime + 0.02 + t);\n } else if (yVal) {\n yVal.connect(this.listener.positionY);\n }\n return this.listener.positionY.value;\n };\n p5.Listener3D.prototype.positionZ = function(zVal, time) {\n var t = time || 0;\n if (typeof zVal === 'number') {\n this.listener.positionZ.value = zVal;\n this.listener.positionZ.cancelScheduledValues(this.ac.currentTime + 0.01 + t);\n this.listener.positionZ.linearRampToValueAtTime(zVal, this.ac.currentTime + 0.02 + t);\n } else if (zVal) {\n zVal.connect(this.listener.positionZ);\n }\n return this.listener.positionZ.value;\n };\n\n// cannot define method when class definition is commented\n// /**\n// * Overrides the listener orient() method because Listener has slightly\n// * different params. In human terms, Forward vectors are the direction the \n// * nose is pointing. Up vectors are the direction of the top of the head.\n// *\n// * @method orient\n// * @param {Number} xValF Forward vector X direction\n// * @param {Number} yValF Forward vector Y direction\n// * @param {Number} zValF Forward vector Z direction\n// * @param {Number} xValU Up vector X direction\n// * @param {Number} yValU Up vector Y direction\n// * @param {Number} zValU Up vector Z direction\n// * @param {Number} time \n// * @return {Array} All orienation params\n// */\n p5.Listener3D.prototype.orient = function(xValF, yValF, zValF, \n xValU, yValU, zValU, time) {\n\n if (arguments.length === 3 || arguments.length === 4) {\n time = arguments[3];\n this.orientForward(xValF, yValF, zValF, time);\n } else if (arguments.length === 6 || arguments === 7) {\n this.orientForward(xValF, yValF, zValF);\n this.orientUp(xValU, yValU, zValU, time);\n }\n \n return [this.listener.forwardX.value, \n this.listener.forwardY.value,\n this.listener.forwardZ.value,\n this.listener.upX.value,\n this.listener.upY.value,\n this.listener.upZ.value];\n };\n\n\n p5.Listener3D.prototype.orientForward = function(xValF, yValF, zValF, time) {\n this.forwardX(xValF,time);\n this.forwardY(yValF,time);\n this.forwardZ(zValF,time);\n\n return [this.listener.forwardX, \n this.listener.forwardY,\n this.listener.forwardZ];\n };\n\n p5.Listener3D.prototype.orientUp = function(xValU, yValU, zValU, time) {\n this.upX(xValU,time);\n this.upY(yValU,time);\n this.upZ(zValU,time);\n\n return [this.listener.upX, \n this.listener.upY,\n this.listener.upZ];\n };\n// /**\n// * Getter and setter methods for orient coordinates\n// * @return {Number} [updated coordinate value]\n// */\n p5.Listener3D.prototype.forwardX = function(xVal, time) {\n var t = time || 0;\n if (typeof xVal === 'number') {\n this.listener.forwardX.value = xVal;\n this.listener.forwardX.cancelScheduledValues(this.ac.currentTime + 0.01 + t);\n this.listener.forwardX.linearRampToValueAtTime(xVal, this.ac.currentTime + 0.02 + t);\n } else if (xVal) {\n xVal.connect(this.listener.forwardX);\n }\n return this.listener.forwardX.value;\n };\n p5.Listener3D.prototype.forwardY = function(yVal, time) {\n var t = time || 0;\n if (typeof yVal === 'number') {\n this.listener.forwardY.value = yVal;\n this.listener.forwardY.cancelScheduledValues(this.ac.currentTime + 0.01 + t);\n this.listener.forwardY.linearRampToValueAtTime(yVal, this.ac.currentTime + 0.02 + t);\n } else if (yVal) {\n yVal.connect(this.listener.forwardY);\n }\n return this.listener.forwardY.value;\n };\n p5.Listener3D.prototype.forwardZ = function(zVal, time) {\n var t = time || 0;\n if (typeof zVal === 'number') {\n this.listener.forwardZ.value = zVal;\n this.listener.forwardZ.cancelScheduledValues(this.ac.currentTime + 0.01 + t);\n this.listener.forwardZ.linearRampToValueAtTime(zVal, this.ac.currentTime + 0.02 + t);\n } else if (zVal) {\n zVal.connect(this.listener.forwardZ);\n }\n return this.listener.forwardZ.value;\n };\n p5.Listener3D.prototype.upX = function(xVal, time) {\n var t = time || 0;\n if (typeof xVal === 'number') {\n this.listener.upX.value = xVal;\n this.listener.upX.cancelScheduledValues(this.ac.currentTime + 0.01 + t);\n this.listener.upX.linearRampToValueAtTime(xVal, this.ac.currentTime + 0.02 + t);\n } else if (xVal) {\n xVal.connect(this.listener.upX);\n }\n return this.listener.upX.value;\n };\n p5.Listener3D.prototype.upY = function(yVal, time) {\n var t = time || 0;\n if (typeof yVal === 'number') {\n this.listener.upY.value = yVal;\n this.listener.upY.cancelScheduledValues(this.ac.currentTime + 0.01 + t);\n this.listener.upY.linearRampToValueAtTime(yVal, this.ac.currentTime + 0.02 + t);\n } else if (yVal) {\n yVal.connect(this.listener.upY);\n }\n return this.listener.upY.value;\n };\n p5.Listener3D.prototype.upZ = function(zVal, time) {\n var t = time || 0;\n if (typeof zVal === 'number') {\n this.listener.upZ.value = zVal;\n this.listener.upZ.cancelScheduledValues(this.ac.currentTime + 0.01 + t);\n this.listener.upZ.linearRampToValueAtTime(zVal, this.ac.currentTime + 0.02 + t);\n } else if (zVal) {\n zVal.connect(this.listener.upZ);\n }\n return this.listener.upZ.value;\n };\n \n return p5.Listener3D;\n\n});","'use strict';\n\ndefine(function (require) {\n var Filter = require('filter');\n var Effect = require('effect');\n\n /**\n * Delay is an echo effect. It processes an existing sound source,\n * and outputs a delayed version of that sound. The p5.Delay can\n * produce different effects depending on the delayTime, feedback,\n * filter, and type. In the example below, a feedback of 0.5 (the\n * defaul value) will produce a looping delay that decreases in\n * volume by 50% each repeat. A filter will cut out the high\n * frequencies so that the delay does not sound as piercing as the\n * original source.\n *\n *\n * This class extends p5.Effect.\n * Methods amp(), chain(),\n * drywet(), connect(), and\n * disconnect() are available.\n * @class p5.Delay\n * @extends p5.Effect\n * @constructor\n * @example\n *
\n * var noise, env, delay;\n *\n * function setup() {\n * background(0);\n * noStroke();\n * fill(255);\n * textAlign(CENTER);\n * text('click to play', width/2, height/2);\n *\n * noise = new p5.Noise('brown');\n * noise.amp(0);\n * noise.start();\n *\n * delay = new p5.Delay();\n *\n * // delay.process() accepts 4 parameters:\n * // source, delayTime, feedback, filter frequency\n * // play with these numbers!!\n * delay.process(noise, .12, .7, 2300);\n *\n * // play the noise with an envelope,\n * // a series of fades ( time / value pairs )\n * env = new p5.Envelope(.01, 0.2, .2, .1);\n * }\n *\n * // mouseClick triggers envelope\n * function mouseClicked() {\n * // is mouse over canvas?\n * if (mouseX > 0 && mouseX < width && mouseY > 0 && mouseY < height) {\n * env.play(noise);\n * }\n * }\n *
\n */\n p5.Delay = function() {\n \tEffect.call(this);\n\n this._split = this.ac.createChannelSplitter(2);\n this._merge = this.ac.createChannelMerger(2);\n\n this._leftGain = this.ac.createGain();\n this._rightGain = this.ac.createGain();\n\n /**\n * The p5.Delay is built with two\n * \n * Web Audio Delay Nodes, one for each stereo channel.\n *\n * @property {DelayNode} leftDelay\n */\n this.leftDelay = this.ac.createDelay();\n /**\n * The p5.Delay is built with two\n * \n * Web Audio Delay Nodes, one for each stereo channel.\n *\n * @property {DelayNode} rightDelay\n */\n this.rightDelay = this.ac.createDelay();\n\n this._leftFilter = new Filter();\n this._rightFilter = new Filter();\n this._leftFilter.disconnect();\n this._rightFilter.disconnect();\n\n this._leftFilter.biquad.frequency.setValueAtTime(1200, this.ac.currentTime);\n this._rightFilter.biquad.frequency.setValueAtTime(1200, this.ac.currentTime);\n this._leftFilter.biquad.Q.setValueAtTime(0.3, this.ac.currentTime);\n this._rightFilter.biquad.Q.setValueAtTime(0.3, this.ac.currentTime);\n\n // graph routing\n this.input.connect(this._split);\n this.leftDelay.connect(this._leftGain);\n this.rightDelay.connect(this._rightGain);\n this._leftGain.connect(this._leftFilter.input);\n this._rightGain.connect(this._rightFilter.input);\n this._merge.connect(this.wet);\n\n\n this._leftFilter.biquad.gain.setValueAtTime(1, this.ac.currentTime);\n this._rightFilter.biquad.gain.setValueAtTime(1, this.ac.currentTime);\n\n // default routing\n this.setType(0);\n\n this._maxDelay = this.leftDelay.delayTime.maxValue;\n\n // set initial feedback to 0.5\n this.feedback(0.5);\n\n\n };\n\n p5.Delay.prototype = Object.create(Effect.prototype);\n /**\n * Add delay to an audio signal according to a set\n * of delay parameters.\n *\n * @method process\n * @for p5.Delay\n * @param {Object} Signal An object that outputs audio\n * @param {Number} [delayTime] Time (in seconds) of the delay/echo.\n * Some browsers limit delayTime to\n * 1 second.\n * @param {Number} [feedback] sends the delay back through itself\n * in a loop that decreases in volume\n * each time.\n * @param {Number} [lowPass] Cutoff frequency. Only frequencies\n * below the lowPass will be part of the\n * delay.\n */\n p5.Delay.prototype.process = function(src, _delayTime, _feedback, _filter) {\n var feedback = _feedback || 0;\n var delayTime = _delayTime || 0;\n if (feedback >= 1.0) {\n throw new Error('Feedback value will force a positive feedback loop.');\n }\n if (delayTime >= this._maxDelay) {\n throw new Error('Delay Time exceeds maximum delay time of ' + this._maxDelay + ' second.');\n }\n\n src.connect(this.input);\n this.leftDelay.delayTime.setValueAtTime(delayTime, this.ac.currentTime);\n this.rightDelay.delayTime.setValueAtTime(delayTime, this.ac.currentTime);\n this._leftGain.gain.value = feedback;\n this._rightGain.gain.value = feedback;\n\n if (_filter) {\n this._leftFilter.freq(_filter);\n this._rightFilter.freq(_filter);\n }\n };\n\n /**\n * Set the delay (echo) time, in seconds. Usually this value will be\n * a floating point number between 0.0 and 1.0.\n *\n * @method delayTime\n * @for p5.Delay\n * @param {Number} delayTime Time (in seconds) of the delay\n */\n p5.Delay.prototype.delayTime = function(t) {\n // if t is an audio node...\n if (typeof t !== 'number') {\n t.connect(this.leftDelay.delayTime);\n t.connect(this.rightDelay.delayTime);\n }\n\n else {\n this.leftDelay.delayTime.cancelScheduledValues(this.ac.currentTime);\n this.rightDelay.delayTime.cancelScheduledValues(this.ac.currentTime);\n this.leftDelay.delayTime.linearRampToValueAtTime(t, this.ac.currentTime);\n this.rightDelay.delayTime.linearRampToValueAtTime(t, this.ac.currentTime);\n }\n };\n\n /**\n * Feedback occurs when Delay sends its signal back through its input\n * in a loop. The feedback amount determines how much signal to send each\n * time through the loop. A feedback greater than 1.0 is not desirable because\n * it will increase the overall output each time through the loop,\n * creating an infinite feedback loop. The default value is 0.5\n *\n * @method feedback\n * @for p5.Delay\n * @param {Number|Object} feedback 0.0 to 1.0, or an object such as an\n * Oscillator that can be used to\n * modulate this param\n * @returns {Number} Feedback value\n *\n */\n p5.Delay.prototype.feedback = function(f) {\n // if f is an audio node...\n if (f && typeof f !== 'number') {\n f.connect(this._leftGain.gain);\n f.connect(this._rightGain.gain);\n }\n else if (f >= 1.0) {\n throw new Error('Feedback value will force a positive feedback loop.');\n }\n else if (typeof f === 'number') {\n this._leftGain.gain.value = f;\n this._rightGain.gain.value = f;\n }\n\n // return value of feedback\n return this._leftGain.gain.value;\n };\n\n /**\n * Set a lowpass filter frequency for the delay. A lowpass filter\n * will cut off any frequencies higher than the filter frequency.\n *\n * @method filter\n * @for p5.Delay\n * @param {Number|Object} cutoffFreq A lowpass filter will cut off any\n * frequencies higher than the filter frequency.\n * @param {Number|Object} res Resonance of the filter frequency\n * cutoff, or an object (i.e. a p5.Oscillator)\n * that can be used to modulate this parameter.\n * High numbers (i.e. 15) will produce a resonance,\n * low numbers (i.e. .2) will produce a slope.\n */\n p5.Delay.prototype.filter = function(freq, q) {\n this._leftFilter.set(freq, q);\n this._rightFilter.set(freq, q);\n };\n\n\n /**\n * Choose a preset type of delay. 'pingPong' bounces the signal\n * from the left to the right channel to produce a stereo effect.\n * Any other parameter will revert to the default delay setting.\n *\n * @method setType\n * @for p5.Delay\n * @param {String|Number} type 'pingPong' (1) or 'default' (0)\n */\n p5.Delay.prototype.setType = function(t) {\n if (t === 1) {\n t = 'pingPong';\n }\n this._split.disconnect();\n this._leftFilter.disconnect();\n this._rightFilter.disconnect();\n this._split.connect(this.leftDelay, 0);\n this._split.connect(this.rightDelay, 1);\n switch(t) {\n case 'pingPong':\n this._rightFilter.setType( this._leftFilter.biquad.type );\n this._leftFilter.output.connect(this._merge, 0, 0);\n this._rightFilter.output.connect(this._merge, 0, 1);\n this._leftFilter.output.connect(this.rightDelay);\n this._rightFilter.output.connect(this.leftDelay);\n break;\n default:\n this._leftFilter.output.connect(this._merge, 0, 0);\n this._rightFilter.output.connect(this._merge, 0, 1);\n this._leftFilter.output.connect(this.leftDelay);\n this._rightFilter.output.connect(this.rightDelay);\n }\n };\n\n // DocBlocks for methods inherited from p5.Effect\n /**\n * Set the output level of the delay effect.\n *\n * @method amp\n * @for p5.Delay\n * @param {Number} volume amplitude between 0 and 1.0\n * @param {Number} [rampTime] create a fade that lasts rampTime\n * @param {Number} [timeFromNow] schedule this event to happen\n * seconds from now\n */\n /**\n * Send output to a p5.sound or web audio object\n *\n * @method connect\n * @for p5.Delay\n * @param {Object} unit\n */\n /**\n * Disconnect all output.\n *\n * @method disconnect\n * @for p5.Delay\n */\n\n p5.Delay.prototype.dispose = function() {\n\n Effect.prototype.dispose.apply(this);\n\n this._split.disconnect();\n this._leftFilter.dispose();\n this._rightFilter.dispose();\n this._merge.disconnect();\n this._leftGain.disconnect();\n this._rightGain.disconnect();\n this.leftDelay.disconnect();\n this.rightDelay.disconnect();\n\n this._split = undefined;\n this._leftFilter = undefined;\n this._rightFilter = undefined;\n this._merge = undefined;\n this._leftGain = undefined;\n this._rightGain = undefined;\n this.leftDelay = undefined;\n this.rightDelay = undefined;\n };\n\n});\n","'use strict';\n\ndefine(function (require) {\n var CustomError = require('errorHandler');\n var Effect = require('effect');\n\n /**\n * Reverb adds depth to a sound through a large number of decaying\n * echoes. It creates the perception that sound is occurring in a\n * physical space. The p5.Reverb has paramters for Time (how long does the\n * reverb last) and decayRate (how much the sound decays with each echo)\n * that can be set with the .set() or .process() methods. The p5.Convolver\n * extends p5.Reverb allowing you to recreate the sound of actual physical\n * spaces through convolution.\n *\n * This class extends p5.Effect.\n * Methods amp(), chain(),\n * drywet(), connect(), and\n * disconnect() are available.\n *\n * @class p5.Reverb\n * @extends p5.Effect\n * @constructor\n * @example\n *
\n * var soundFile, reverb;\n * function preload() {\n * soundFile = loadSound('assets/Damscray_DancingTiger.mp3');\n * }\n *\n * function setup() {\n * reverb = new p5.Reverb();\n * soundFile.disconnect(); // so we'll only hear reverb...\n *\n * // connect soundFile to reverb, process w/\n * // 3 second reverbTime, decayRate of 2%\n * reverb.process(soundFile, 3, 2);\n * soundFile.play();\n * }\n *
\n */\n\n\n p5.Reverb = function() {\n Effect.call(this);\n\n this._initConvolverNode();\n\n // otherwise, Safari distorts\n this.input.gain.value = 0.5;\n\n // default params\n this._seconds = 3;\n this._decay = 2;\n this._reverse = false;\n\n this._buildImpulse();\n\n };\n\n p5.Reverb.prototype = Object.create(Effect.prototype);\n\n p5.Reverb.prototype._initConvolverNode = function() {\n this.convolverNode = this.ac.createConvolver();\n this.input.connect(this.convolverNode);\n this.convolverNode.connect(this.wet);\n };\n\n p5.Reverb.prototype._teardownConvolverNode = function() {\n if (this.convolverNode) {\n this.convolverNode.disconnect();\n delete this.convolverNode;\n }\n };\n\n p5.Reverb.prototype._setBuffer = function(audioBuffer) {\n this._teardownConvolverNode();\n this._initConvolverNode();\n this.convolverNode.buffer = audioBuffer;\n };\n /**\n * Connect a source to the reverb, and assign reverb parameters.\n *\n * @method process\n * @for p5.Reverb\n * @param {Object} src p5.sound / Web Audio object with a sound\n * output.\n * @param {Number} [seconds] Duration of the reverb, in seconds.\n * Min: 0, Max: 10. Defaults to 3.\n * @param {Number} [decayRate] Percentage of decay with each echo.\n * Min: 0, Max: 100. Defaults to 2.\n * @param {Boolean} [reverse] Play the reverb backwards or forwards.\n */\n p5.Reverb.prototype.process = function(src, seconds, decayRate, reverse) {\n src.connect(this.input);\n var rebuild = false;\n if (seconds) {\n this._seconds = seconds;\n rebuild = true;\n }\n if (decayRate) {\n this._decay = decayRate;\n }\n if (reverse) {\n this._reverse = reverse;\n }\n if (rebuild) {\n this._buildImpulse();\n }\n };\n\n /**\n * Set the reverb settings. Similar to .process(), but without\n * assigning a new input.\n *\n * @method set\n * @for p5.Reverb\n * @param {Number} [seconds] Duration of the reverb, in seconds.\n * Min: 0, Max: 10. Defaults to 3.\n * @param {Number} [decayRate] Percentage of decay with each echo.\n * Min: 0, Max: 100. Defaults to 2.\n * @param {Boolean} [reverse] Play the reverb backwards or forwards.\n */\n p5.Reverb.prototype.set = function(seconds, decayRate, reverse) {\n var rebuild = false;\n if (seconds) {\n this._seconds = seconds;\n rebuild = true;\n }\n if (decayRate) {\n this._decay = decayRate;\n }\n if (reverse) {\n this._reverse = reverse;\n }\n if (rebuild) {\n this._buildImpulse();\n }\n };\n\n // DocBlocks for methods inherited from p5.Effect\n /**\n * Set the output level of the reverb effect.\n *\n * @method amp\n * @for p5.Reverb\n * @param {Number} volume amplitude between 0 and 1.0\n * @param {Number} [rampTime] create a fade that lasts rampTime\n * @param {Number} [timeFromNow] schedule this event to happen\n * seconds from now\n */\n /**\n * Send output to a p5.sound or web audio object\n *\n * @method connect\n * @for p5.Reverb\n * @param {Object} unit\n */\n /**\n * Disconnect all output.\n *\n * @method disconnect\n * @for p5.Reverb\n */\n\n /**\n * Inspired by Simple Reverb by Jordan Santell\n * https://github.com/web-audio-components/simple-reverb/blob/master/index.js\n *\n * Utility function for building an impulse response\n * based on the module parameters.\n *\n * @private\n */\n p5.Reverb.prototype._buildImpulse = function() {\n var rate = this.ac.sampleRate;\n var length = rate*this._seconds;\n var decay = this._decay;\n var impulse = this.ac.createBuffer(2, length, rate);\n var impulseL = impulse.getChannelData(0);\n var impulseR = impulse.getChannelData(1);\n var n, i;\n for (i = 0; i < length; i++) {\n n = this._reverse ? length - i : i;\n impulseL[i] = (Math.random() * 2 - 1) * Math.pow(1 - n / length, decay);\n impulseR[i] = (Math.random() * 2 - 1) * Math.pow(1 - n / length, decay);\n }\n this._setBuffer(impulse);\n };\n\n p5.Reverb.prototype.dispose = function() {\n Effect.prototype.dispose.apply(this);\n this._teardownConvolverNode();\n };\n\n // =======================================================================\n // *** p5.Convolver ***\n // =======================================================================\n\n /**\n *
p5.Convolver extends p5.Reverb. It can emulate the sound of real\n * physical spaces through a process called \n * convolution.
\n *\n *
Convolution multiplies any audio input by an \"impulse response\"\n * to simulate the dispersion of sound over time. The impulse response is\n * generated from an audio file that you provide. One way to\n * generate an impulse response is to pop a balloon in a reverberant space\n * and record the echo. Convolution can also be used to experiment with\n * sound.
\n *\n *
Use the method createConvolution(path) to instantiate a\n * p5.Convolver with a path to your impulse response audio file.
\n *\n * @class p5.Convolver\n * @extends p5.Effect\n * @constructor\n * @param {String} path path to a sound file\n * @param {Function} [callback] function to call when loading succeeds\n * @param {Function} [errorCallback] function to call if loading fails.\n * This function will receive an error or\n * XMLHttpRequest object with information\n * about what went wrong.\n * @example\n *
\n * var cVerb, sound;\n * function preload() {\n * // We have both MP3 and OGG versions of all sound assets\n * soundFormats('ogg', 'mp3');\n *\n * // Try replacing 'bx-spring' with other soundfiles like\n * // 'concrete-tunnel' 'small-plate' 'drum' 'beatbox'\n * cVerb = createConvolver('assets/bx-spring.mp3');\n *\n * // Try replacing 'Damscray_DancingTiger' with\n * // 'beat', 'doorbell', lucky_dragons_-_power_melody'\n * sound = loadSound('assets/Damscray_DancingTiger.mp3');\n * }\n *\n * function setup() {\n * // disconnect from master output...\n * sound.disconnect();\n *\n * // ...and process with cVerb\n * // so that we only hear the convolution\n * cVerb.process(sound);\n *\n * sound.play();\n * }\n *
\n */\n p5.Convolver = function(path, callback, errorCallback) {\n \t p5.Reverb.call(this);\n\n /**\n * Internally, the p5.Convolver uses the a\n * \n * Web Audio Convolver Node.\n *\n * @property {ConvolverNode} convolverNode\n */\n this._initConvolverNode();\n\n // otherwise, Safari distorts\n this.input.gain.value = 0.5;\n\n if (path) {\n this.impulses = [];\n this._loadBuffer(path, callback, errorCallback);\n }\n else {\n // parameters\n this._seconds = 3;\n this._decay = 2;\n this._reverse = false;\n\n this._buildImpulse();\n }\n\n };\n\n p5.Convolver.prototype = Object.create(p5.Reverb.prototype);\n\n p5.prototype.registerPreloadMethod('createConvolver', p5.prototype);\n\n /**\n * Create a p5.Convolver. Accepts a path to a soundfile\n * that will be used to generate an impulse response.\n *\n * @method createConvolver\n * @for p5\n * @param {String} path path to a sound file\n * @param {Function} [callback] function to call if loading is successful.\n * The object will be passed in as the argument\n * to the callback function.\n * @param {Function} [errorCallback] function to call if loading is not successful.\n * A custom error will be passed in as the argument\n * to the callback function.\n * @return {p5.Convolver}\n * @example\n *
\n * var cVerb, sound;\n * function preload() {\n * // We have both MP3 and OGG versions of all sound assets\n * soundFormats('ogg', 'mp3');\n *\n * // Try replacing 'bx-spring' with other soundfiles like\n * // 'concrete-tunnel' 'small-plate' 'drum' 'beatbox'\n * cVerb = createConvolver('assets/bx-spring.mp3');\n *\n * // Try replacing 'Damscray_DancingTiger' with\n * // 'beat', 'doorbell', lucky_dragons_-_power_melody'\n * sound = loadSound('assets/Damscray_DancingTiger.mp3');\n * }\n *\n * function setup() {\n * // disconnect from master output...\n * sound.disconnect();\n *\n * // ...and process with cVerb\n * // so that we only hear the convolution\n * cVerb.process(sound);\n *\n * sound.play();\n * }\n *
\n */\n p5.prototype.createConvolver = function(path, callback, errorCallback) {\n // if loading locally without a server\n if (window.location.origin.indexOf('file://') > -1 && window.cordova === 'undefined') {\n alert('This sketch may require a server to load external files. Please see http://bit.ly/1qcInwS');\n }\n var self = this;\n var cReverb = new p5.Convolver(path, function(buffer) {\n if (typeof callback === 'function') {\n callback(buffer);\n }\n\n if (typeof self._decrementPreload === 'function') {\n self._decrementPreload();\n }\n }, errorCallback);\n cReverb.impulses = [];\n return cReverb;\n };\n\n /**\n * Private method to load a buffer as an Impulse Response,\n * assign it to the convolverNode, and add to the Array of .impulses.\n *\n * @param {String} path\n * @param {Function} callback\n * @param {Function} errorCallback\n * @private\n */\n p5.Convolver.prototype._loadBuffer = function(path, callback, errorCallback) {\n var path = p5.prototype._checkFileFormats(path);\n var self = this;\n var errorTrace = new Error().stack;\n var ac = p5.prototype.getAudioContext();\n\n var request = new XMLHttpRequest();\n request.open('GET', path, true);\n request.responseType = 'arraybuffer';\n\n request.onload = function() {\n if (request.status === 200) {\n // on success loading file:\n ac.decodeAudioData(request.response,\n function(buff) {\n var buffer = {};\n var chunks = path.split('/');\n buffer.name = chunks[chunks.length - 1];\n buffer.audioBuffer = buff;\n self.impulses.push(buffer);\n self._setBuffer(buffer.audioBuffer);\n if (callback) {\n callback(buffer);\n }\n },\n // error decoding buffer. \"e\" is undefined in Chrome 11/22/2015\n function() {\n var err = new CustomError('decodeAudioData', errorTrace, self.url);\n var msg = 'AudioContext error at decodeAudioData for ' + self.url;\n if (errorCallback) {\n err.msg = msg;\n errorCallback(err);\n } else {\n console.error(msg +'\\n The error stack trace includes: \\n' + err.stack);\n }\n }\n );\n }\n // if request status != 200, it failed\n else {\n var err = new CustomError('loadConvolver', errorTrace, self.url);\n var msg = 'Unable to load ' + self.url +\n '. The request status was: ' + request.status + ' (' + request.statusText + ')';\n\n if (errorCallback) {\n err.message = msg;\n errorCallback(err);\n } else {\n console.error(msg +'\\n The error stack trace includes: \\n' + err.stack);\n }\n }\n };\n\n // if there is another error, aside from 404...\n request.onerror = function() {\n var err = new CustomError('loadConvolver', errorTrace, self.url);\n var msg = 'There was no response from the server at ' + self.url + '. Check the url and internet connectivity.';\n\n if (errorCallback) {\n err.message = msg;\n errorCallback(err);\n } else {\n console.error(msg +'\\n The error stack trace includes: \\n' + err.stack);\n }\n };\n request.send();\n };\n\n p5.Convolver.prototype.set = null;\n\n /**\n * Connect a source to the reverb, and assign reverb parameters.\n *\n * @method process\n * @for p5.Convolver\n * @param {Object} src p5.sound / Web Audio object with a sound\n * output.\n * @example\n *
\n * var cVerb, sound;\n * function preload() {\n * soundFormats('ogg', 'mp3');\n *\n * cVerb = createConvolver('assets/concrete-tunnel.mp3');\n *\n * sound = loadSound('assets/beat.mp3');\n * }\n *\n * function setup() {\n * // disconnect from master output...\n * sound.disconnect();\n *\n * // ...and process with (i.e. connect to) cVerb\n * // so that we only hear the convolution\n * cVerb.process(sound);\n *\n * sound.play();\n * }\n *
\n */\n p5.Convolver.prototype.process = function(src) {\n src.connect(this.input);\n };\n\n /**\n * If you load multiple impulse files using the .addImpulse method,\n * they will be stored as Objects in this Array. Toggle between them\n * with the toggleImpulse(id) method.\n *\n * @property {Array} impulses\n * @for p5.Convolver\n */\n p5.Convolver.prototype.impulses = [];\n\n /**\n * Load and assign a new Impulse Response to the p5.Convolver.\n * The impulse is added to the .impulses array. Previous\n * impulses can be accessed with the .toggleImpulse(id)\n * method.\n *\n * @method addImpulse\n * @for p5.Convolver\n * @param {String} path path to a sound file\n * @param {Function} callback function (optional)\n * @param {Function} errorCallback function (optional)\n */\n p5.Convolver.prototype.addImpulse = function(path, callback, errorCallback) {\n // if loading locally without a server\n if (window.location.origin.indexOf('file://') > -1 && window.cordova === 'undefined') {\n alert('This sketch may require a server to load external files. Please see http://bit.ly/1qcInwS');\n }\n this._loadBuffer(path, callback, errorCallback);\n };\n\n /**\n * Similar to .addImpulse, except that the .impulses\n * Array is reset to save memory. A new .impulses\n * array is created with this impulse as the only item.\n *\n * @method resetImpulse\n * @for p5.Convolver\n * @param {String} path path to a sound file\n * @param {Function} callback function (optional)\n * @param {Function} errorCallback function (optional)\n */\n p5.Convolver.prototype.resetImpulse = function(path, callback, errorCallback) {\n // if loading locally without a server\n if (window.location.origin.indexOf('file://') > -1 && window.cordova === 'undefined') {\n alert('This sketch may require a server to load external files. Please see http://bit.ly/1qcInwS');\n }\n this.impulses = [];\n this._loadBuffer(path, callback, errorCallback);\n };\n\n /**\n * If you have used .addImpulse() to add multiple impulses\n * to a p5.Convolver, then you can use this method to toggle between\n * the items in the .impulses Array. Accepts a parameter\n * to identify which impulse you wish to use, identified either by its\n * original filename (String) or by its position in the .impulses\n * Array (Number). \n * You can access the objects in the .impulses Array directly. Each\n * Object has two attributes: an .audioBuffer (type:\n * Web Audio \n * AudioBuffer) and a .name, a String that corresponds\n * with the original filename.\n *\n * @method toggleImpulse\n * @for p5.Convolver\n * @param {String|Number} id Identify the impulse by its original filename\n * (String), or by its position in the\n * .impulses Array (Number).\n */\n p5.Convolver.prototype.toggleImpulse = function(id) {\n if (typeof id === 'number' && id < this.impulses.length) {\n this._setBuffer(this.impulses[id].audioBuffer);\n }\n if (typeof id === 'string') {\n for (var i = 0; i < this.impulses.length; i++) {\n if (this.impulses[i].name === id) {\n this._setBuffer(this.impulses[i].audioBuffer);\n break;\n }\n }\n }\n };\n\n p5.Convolver.prototype.dispose = function() {\n p5.Reverb.prototype.dispose.apply(this);\n\n // remove all the Impulse Response buffers\n for (var i in this.impulses) {\n if (this.impulses[i]) {\n this.impulses[i] = null;\n }\n }\n };\n\n});\n","'use strict';\n\ndefine(function (require) {\n var p5sound = require('master');\n\n // requires the Tone.js library's Clock (MIT license, Yotam Mann)\n // https://github.com/TONEnoTONE/Tone.js/\n var Clock = require('Tone/core/Clock');\n\n p5.Metro = function() {\n this.clock = new Clock({\n 'callback': this.ontick.bind(this)\n });\n this.syncedParts = [];\n this.bpm = 120; // gets overridden by p5.Part\n this._init();\n\n this.prevTick = 0;\n this.tatumTime = 0;\n\n this.tickCallback = function() {};\n };\n\n p5.Metro.prototype.ontick = function(tickTime) {\n var elapsedTime = tickTime - this.prevTick;\n var secondsFromNow = tickTime - p5sound.audiocontext.currentTime;\n if (elapsedTime - this.tatumTime <= -0.02) {\n return;\n } else {\n // console.log('ok', this.syncedParts[0].phrases[0].name);\n this.prevTick = tickTime;\n\n // for all of the active things on the metro:\n var self = this;\n this.syncedParts.forEach(function(thisPart) {\n if (!thisPart.isPlaying) return;\n thisPart.incrementStep(secondsFromNow);\n // each synced source keeps track of its own beat number\n thisPart.phrases.forEach(function(thisPhrase) {\n var phraseArray = thisPhrase.sequence;\n var bNum = self.metroTicks % phraseArray.length;\n if (phraseArray[bNum] !== 0 && (self.metroTicks < phraseArray.length || !thisPhrase.looping) ) {\n thisPhrase.callback(secondsFromNow, phraseArray[bNum]);\n }\n });\n });\n this.metroTicks += 1;\n this.tickCallback(secondsFromNow);\n }\n };\n\n p5.Metro.prototype.setBPM = function(bpm, rampTime) {\n var beatTime = 60 / (bpm*this.tatums);\n var now = p5sound.audiocontext.currentTime;\n this.tatumTime = beatTime;\n\n var rampTime = rampTime || 0;\n this.clock.frequency.setValueAtTime(this.clock.frequency.value, now);\n this.clock.frequency.linearRampToValueAtTime(bpm, now + rampTime);\n this.bpm = bpm;\n };\n\n p5.Metro.prototype.getBPM = function() {\n return this.clock.getRate() / this.tatums * 60;\n };\n\n p5.Metro.prototype._init = function() {\n this.metroTicks = 0;\n // this.setBPM(120);\n };\n\n // clear existing synced parts, add only this one\n p5.Metro.prototype.resetSync = function(part) {\n this.syncedParts = [part];\n };\n\n // push a new synced part to the array\n p5.Metro.prototype.pushSync = function(part) {\n this.syncedParts.push(part);\n };\n\n p5.Metro.prototype.start = function(timeFromNow) {\n var t = timeFromNow || 0;\n var now = p5sound.audiocontext.currentTime;\n this.clock.start(now + t);\n this.setBPM(this.bpm);\n };\n\n p5.Metro.prototype.stop = function(timeFromNow) {\n var t = timeFromNow || 0;\n var now = p5sound.audiocontext.currentTime;\n this.clock.stop(now + t);\n };\n\n p5.Metro.prototype.beatLength = function(tatums) {\n this.tatums = 1/tatums / 4; // lowest possible division of a beat\n };\n\n});\n","define([\"Tone/core/Tone\", \"Tone/core/Timeline\", \"Tone/type/Type\"], function (Tone) {\n\n\t\"use strict\";\n\n\t/**\n\t * @class A Timeline State. Provides the methods: setStateAtTime(\"state\", time)\n\t * and getValueAtTime(time).\n\t *\n\t * @extends {Tone.Timeline}\n\t * @param {String} initial The initial state of the TimelineState. \n\t * Defaults to undefined\n\t */\n\tTone.TimelineState = function(initial){\n\n\t\tTone.Timeline.call(this);\n\n\t\t/**\n\t\t * The initial state\n\t\t * @private\n\t\t * @type {String}\n\t\t */\n\t\tthis._initial = initial;\n\t};\n\n\tTone.extend(Tone.TimelineState, Tone.Timeline);\n\n\t/**\n\t * Returns the scheduled state scheduled before or at\n\t * the given time.\n\t * @param {Number} time The time to query.\n\t * @return {String} The name of the state input in setStateAtTime.\n\t */\n\tTone.TimelineState.prototype.getValueAtTime = function(time){\n\t\tvar event = this.get(time);\n\t\tif (event !== null){\n\t\t\treturn event.state;\n\t\t} else {\n\t\t\treturn this._initial;\n\t\t}\n\t};\n\n\t/**\n\t * Returns the scheduled state scheduled before or at\n\t * the given time.\n\t * @param {String} state The name of the state to set.\n\t * @param {Number} time The time to query.\n\t */\n\tTone.TimelineState.prototype.setStateAtTime = function(state, time){\n\t\tthis.add({\n\t\t\t\"state\" : state,\n\t\t\t\"time\" : time\n\t\t});\n\t};\n\n\treturn Tone.TimelineState;\n});","'use strict';\n\ndefine(function(require) {\n var p5sound = require('master');\n\n var BPM = 120;\n\n /**\n * Set the global tempo, in beats per minute, for all\n * p5.Parts. This method will impact all active p5.Parts.\n *\n * @method setBPM\n * @for p5\n * @param {Number} BPM Beats Per Minute\n * @param {Number} rampTime Seconds from now\n */\n p5.prototype.setBPM = function(bpm, rampTime) {\n BPM = bpm;\n for (var i in p5sound.parts) {\n if (p5sound.parts[i]) {\n p5sound.parts[i].setBPM(bpm, rampTime);\n }\n }\n };\n\n /**\n *
A phrase is a pattern of musical events over time, i.e.\n * a series of notes and rests.
\n *\n *
Phrases must be added to a p5.Part for playback, and\n * each part can play multiple phrases at the same time.\n * For example, one Phrase might be a kick drum, another\n * could be a snare, and another could be the bassline.
\n *\n *
The first parameter is a name so that the phrase can be\n * modified or deleted later. The callback is a a function that\n * this phrase will call at every step—for example it might be\n * called playNote(value){}. The array determines\n * which value is passed into the callback at each step of the\n * phrase. It can be numbers, an object with multiple numbers,\n * or a zero (0) indicates a rest so the callback won't be called).
\n *\n * @class p5.Phrase\n * @constructor\n * @param {String} name Name so that you can access the Phrase.\n * @param {Function} callback The name of a function that this phrase\n * will call. Typically it will play a sound,\n * and accept two parameters: a time at which\n * to play the sound (in seconds from now),\n * and a value from the sequence array. The\n * time should be passed into the play() or\n * start() method to ensure precision.\n * @param {Array} sequence Array of values to pass into the callback\n * at each step of the phrase.\n * @example\n *
\n */\n p5.Phrase = function(name, callback, sequence) {\n this.phraseStep = 0;\n this.name = name;\n this.callback = callback;\n /**\n * Array of values to pass into the callback\n * at each step of the phrase. Depending on the callback\n * function's requirements, these values may be numbers,\n * strings, or an object with multiple parameters.\n * Zero (0) indicates a rest.\n *\n * @property {Array} sequence\n */\n this.sequence = sequence;\n };\n\n /**\n *
A p5.Part plays back one or more p5.Phrases. Instantiate a part\n * with steps and tatums. By default, each step represents a 1/16th note.
\n *\n *
See p5.Phrase for more about musical timing.
\n *\n * @class p5.Part\n * @constructor\n * @param {Number} [steps] Steps in the part\n * @param {Number} [tatums] Divisions of a beat, e.g. use 1/4, or 0.25 for a quater note (default is 1/16, a sixteenth note)\n * @example\n *
\n * var box, drum, myPart;\n * var boxPat = [1,0,0,2,0,2,0,0];\n * var drumPat = [0,1,1,0,2,0,1,0];\n * var msg = 'click to play';\n *\n * function preload() {\n * box = loadSound('assets/beatbox.mp3');\n * drum = loadSound('assets/drum.mp3');\n * }\n *\n * function setup() {\n * noStroke();\n * fill(255);\n * textAlign(CENTER);\n * masterVolume(0.1);\n *\n * var boxPhrase = new p5.Phrase('box', playBox, boxPat);\n * var drumPhrase = new p5.Phrase('drum', playDrum, drumPat);\n * myPart = new p5.Part();\n * myPart.addPhrase(boxPhrase);\n * myPart.addPhrase(drumPhrase);\n * myPart.setBPM(60);\n * masterVolume(0.1);\n * }\n *\n * function draw() {\n * background(0);\n * text(msg, width/2, height/2);\n * }\n *\n * function playBox(time, playbackRate) {\n * box.rate(playbackRate);\n * box.play(time);\n * }\n *\n * function playDrum(time, playbackRate) {\n * drum.rate(playbackRate);\n * drum.play(time);\n * }\n *\n * function mouseClicked() {\n * if (mouseX > 0 && mouseX < width && mouseY > 0 && mouseY < height) {\n * myPart.start();\n * msg = 'playing part';\n * }\n * }\n *
\n */\n p5.Part = function(steps, bLength) {\n this.length = steps || 0; // how many beats\n this.partStep = 0;\n this.phrases = [];\n this.isPlaying = false;\n this.noLoop();\n this.tatums = bLength || 0.0625; // defaults to quarter note\n\n this.metro = new p5.Metro();\n this.metro._init();\n this.metro.beatLength(this.tatums);\n this.metro.setBPM(BPM);\n p5sound.parts.push(this);\n this.callback = function() {};\n };\n\n /**\n * Set the tempo of this part, in Beats Per Minute.\n *\n * @method setBPM\n * @for p5.Part\n * @param {Number} BPM Beats Per Minute\n * @param {Number} [rampTime] Seconds from now\n */\n p5.Part.prototype.setBPM = function(tempo, rampTime) {\n this.metro.setBPM(tempo, rampTime);\n };\n\n /**\n * Returns the tempo, in Beats Per Minute, of this part.\n *\n * @method getBPM\n * @for p5.Part\n * @return {Number}\n */\n p5.Part.prototype.getBPM = function() {\n return this.metro.getBPM();\n };\n\n /**\n * Start playback of this part. It will play\n * through all of its phrases at a speed\n * determined by setBPM.\n *\n * @method start\n * @for p5.Part\n * @param {Number} [time] seconds from now\n */\n p5.Part.prototype.start = function(time) {\n if (!this.isPlaying) {\n this.isPlaying = true;\n this.metro.resetSync(this);\n var t = time || 0;\n this.metro.start(t);\n }\n };\n\n /**\n * Loop playback of this part. It will begin\n * looping through all of its phrases at a speed\n * determined by setBPM.\n *\n * @method loop\n * @for p5.Part\n * @param {Number} [time] seconds from now\n */\n p5.Part.prototype.loop = function(time) {\n this.looping = true;\n // rest onended function\n this.onended = function() {\n this.partStep = 0;\n };\n var t = time || 0;\n this.start(t);\n };\n\n /**\n * Tell the part to stop looping.\n *\n * @method noLoop\n * @for p5.Part\n */\n p5.Part.prototype.noLoop = function() {\n this.looping = false;\n // rest onended function\n this.onended = function() {\n this.stop();\n };\n };\n\n /**\n * Stop the part and cue it to step 0. Playback will resume from the begining of the Part when it is played again.\n *\n * @method stop\n * @for p5.Part\n * @param {Number} [time] seconds from now\n */\n p5.Part.prototype.stop = function(time) {\n this.partStep = 0;\n this.pause(time);\n };\n\n /**\n * Pause the part. Playback will resume\n * from the current step.\n *\n * @method pause\n * @for p5.Part\n * @param {Number} time seconds from now\n */\n p5.Part.prototype.pause = function(time) {\n this.isPlaying = false;\n var t = time || 0;\n this.metro.stop(t);\n };\n\n /**\n * Add a p5.Phrase to this Part.\n *\n * @method addPhrase\n * @for p5.Part\n * @param {p5.Phrase} phrase reference to a p5.Phrase\n */\n p5.Part.prototype.addPhrase = function(name, callback, array) {\n var p;\n if (arguments.length === 3) {\n p = new p5.Phrase(name, callback, array);\n } else if (arguments[0] instanceof p5.Phrase) {\n p = arguments[0];\n } else {\n throw 'invalid input. addPhrase accepts name, callback, array or a p5.Phrase';\n }\n this.phrases.push(p);\n // reset the length if phrase is longer than part's existing length\n if (p.sequence.length > this.length) {\n this.length = p.sequence.length;\n }\n };\n\n /**\n * Remove a phrase from this part, based on the name it was\n * given when it was created.\n *\n * @method removePhrase\n * @for p5.Part\n * @param {String} phraseName\n */\n p5.Part.prototype.removePhrase = function(name) {\n for (var i in this.phrases) {\n if (this.phrases[i].name === name) {\n this.phrases.splice(i, 1);\n }\n }\n };\n\n /**\n * Get a phrase from this part, based on the name it was\n * given when it was created. Now you can modify its array.\n *\n * @method getPhrase\n * @for p5.Part\n * @param {String} phraseName\n */\n p5.Part.prototype.getPhrase = function(name) {\n for (var i in this.phrases) {\n if (this.phrases[i].name === name) {\n return this.phrases[i];\n }\n }\n };\n\n /**\n * Find all sequences with the specified name, and replace their patterns with the specified array.\n *\n * @method replaceSequence\n * @for p5.Part\n * @param {String} phraseName\n * @param {Array} sequence Array of values to pass into the callback\n * at each step of the phrase.\n */\n p5.Part.prototype.replaceSequence = function(name, array) {\n for (var i in this.phrases) {\n if (this.phrases[i].name === name) {\n this.phrases[i].sequence = array;\n }\n }\n };\n\n p5.Part.prototype.incrementStep = function(time) {\n if (this.partStep < this.length - 1) {\n this.callback(time);\n this.partStep += 1;\n } else {\n if (!this.looping && this.partStep === this.length - 1) {\n console.log('done');\n // this.callback(time);\n this.onended();\n }\n }\n };\n\n /**\n * Set the function that will be called at every step. This will clear the previous function.\n *\n * @method onStep\n * @for p5.Part\n * @param {Function} callback The name of the callback\n * you want to fire\n * on every beat/tatum.\n */\n p5.Part.prototype.onStep = function(callback) {\n this.callback = callback;\n };\n\n\n // ===============\n // p5.Score\n // ===============\n\n /**\n * A Score consists of a series of Parts. The parts will\n * be played back in order. For example, you could have an\n * A part, a B part, and a C part, and play them back in this order\n * new p5.Score(a, a, b, a, c)\n *\n * @class p5.Score\n * @constructor\n * @param {p5.Part} [...parts] One or multiple parts, to be played in sequence.\n */\n p5.Score = function() {\n // for all of the arguments\n this.parts = [];\n this.currentPart = 0;\n\n var thisScore = this;\n for (var i in arguments) {\n if (arguments[i] && this.parts[i]) {\n this.parts[i] = arguments[i];\n this.parts[i].nextPart = this.parts[i + 1];\n this.parts[i].onended = function() {\n thisScore.resetPart(i);\n playNextPart(thisScore);\n };\n }\n }\n this.looping = false;\n };\n\n p5.Score.prototype.onended = function() {\n if (this.looping) {\n // this.resetParts();\n this.parts[0].start();\n } else {\n this.parts[this.parts.length - 1].onended = function() {\n this.stop();\n this.resetParts();\n };\n }\n this.currentPart = 0;\n };\n\n /**\n * Start playback of the score.\n *\n * @method start\n * @for p5.Score\n */\n p5.Score.prototype.start = function() {\n this.parts[this.currentPart].start();\n this.scoreStep = 0;\n };\n\n /**\n * Stop playback of the score.\n *\n * @method stop\n * @for p5.Score\n */\n p5.Score.prototype.stop = function() {\n this.parts[this.currentPart].stop();\n this.currentPart = 0;\n this.scoreStep = 0;\n };\n\n /**\n * Pause playback of the score.\n *\n * @method pause\n * @for p5.Score\n */\n p5.Score.prototype.pause = function() {\n this.parts[this.currentPart].stop();\n };\n\n /**\n * Loop playback of the score.\n *\n * @method loop\n * @for p5.Score\n */\n p5.Score.prototype.loop = function() {\n this.looping = true;\n this.start();\n };\n\n /**\n * Stop looping playback of the score. If it\n * is currently playing, this will go into effect\n * after the current round of playback completes.\n *\n * @method noLoop\n * @for p5.Score\n */\n p5.Score.prototype.noLoop = function() {\n this.looping = false;\n };\n\n p5.Score.prototype.resetParts = function() {\n var self = this;\n this.parts.forEach(function(part) {\n self.resetParts[part];\n });\n };\n\n p5.Score.prototype.resetPart = function(i) {\n this.parts[i].stop();\n this.parts[i].partStep = 0;\n for (var p in this.parts[i].phrases) {\n if (this.parts[i]) {\n this.parts[i].phrases[p].phraseStep = 0;\n }\n }\n };\n\n /**\n * Set the tempo for all parts in the score\n *\n * @method setBPM\n * @for p5.Score\n * @param {Number} BPM Beats Per Minute\n * @param {Number} rampTime Seconds from now\n */\n p5.Score.prototype.setBPM = function(bpm, rampTime) {\n for (var i in this.parts) {\n if (this.parts[i]) {\n this.parts[i].setBPM(bpm, rampTime);\n }\n }\n };\n\n function playNextPart(aScore) {\n aScore.currentPart++;\n if (aScore.currentPart >= aScore.parts.length) {\n aScore.scoreStep = 0;\n aScore.onended();\n } else {\n aScore.scoreStep = 0;\n aScore.parts[aScore.currentPart - 1].stop();\n aScore.parts[aScore.currentPart].start();\n }\n }\n\n});\n","'use strict';\n\ndefine(function (require) {\n var p5sound = require('master');\n var Clock = require('Tone/core/Clock');\n\n /**\n * SoundLoop\n *\n * @class p5.SoundLoop\n * @constructor\n *\n * @param {Function} callback this function will be called on each iteration of theloop\n * @param {Number|String} [interval] amount of time or beats for each iteration of the loop\n * defaults to 1\n *\n * @example\n *
\n * var click;\n * var looper1;\n *\n * function preload() {\n * click = loadSound('assets/drum.mp3');\n * }\n *\n * function setup() {\n * //the looper's callback is passed the timeFromNow\n * //this value should be used as a reference point from\n * //which to schedule sounds\n * looper1 = new p5.SoundLoop(function(timeFromNow){\n * click.play(timeFromNow);\n * background(255 * (looper1.iterations % 2));\n * }, 2);\n *\n * //stop after 10 iteratios;\n * looper1.maxIterations = 10;\n * //start the loop\n * looper1.start();\n * }\n *
\n */\n p5.SoundLoop = function(callback, interval) {\n this.callback = callback;\n /**\n * musicalTimeMode uses Tone.Time convention\n\t * true if string, false if number\n * @property {Boolean} musicalTimeMode\n */\n this.musicalTimeMode = typeof this._interval === 'number' ? false : true;\n\n this._interval = interval || 1;\n\n /**\n * musicalTimeMode variables\n * modify these only when the interval is specified in musicalTime format as a string\n */\n this._timeSignature = 4;\n this._bpm = 60;\n\n this.isPlaying = false;\n\n /**\n * Set a limit to the number of loops to play. defaults to Infinity\n * @property {Number} maxIterations\n */\n this.maxIterations = Infinity;\n var self = this;\n\n this.clock = new Clock({\n 'callback' : function(time) {\n var timeFromNow = time - p5sound.audiocontext.currentTime;\n /**\n * Do not initiate the callback if timeFromNow is < 0\n * This ususually occurs for a few milliseconds when the page\n * is not fully loaded\n *\n * The callback should only be called until maxIterations is reached\n */\n if (timeFromNow > 0 && self.iterations <= self.maxIterations) {\n self.callback(timeFromNow);}\n },\n 'frequency' : this._calcFreq()\n });\n };\n\n /**\n * Start the loop\n * @method start\n * @for p5.SoundLoop\n * @param {Number} [timeFromNow] schedule a starting time\n */\n p5.SoundLoop.prototype.start = function(timeFromNow) {\n var t = timeFromNow || 0;\n var now = p5sound.audiocontext.currentTime;\n if (!this.isPlaying) {\n this.clock.start(now + t);\n this.isPlaying = true;\n }\n };\n\n /**\n * Stop the loop\n * @method stop\n * @for p5.SoundLoop\n * @param {Number} [timeFromNow] schedule a stopping time\n */\n p5.SoundLoop.prototype.stop = function(timeFromNow) {\n var t = timeFromNow || 0;\n var now = p5sound.audiocontext.currentTime;\n if (this.isPlaying) {\n this.clock.stop(now + t);\n this.isPlaying = false;\n }\n };\n /**\n * Pause the loop\n * @method pause\n * @for p5.SoundLoop\n * @param {Number} [timeFromNow] schedule a pausing time\n */\n p5.SoundLoop.prototype.pause = function(timeFromNow) {\n var t = timeFromNow || 0;\n var now = p5sound.audiocontext.currentTime;\n if (this.isPlaying) {\n this.clock.pause(now + t);\n this.isPlaying = false;\n }\n };\n\n\n /**\n * Synchronize loops. Use this method to start two more more loops in synchronization\n * or to start a loop in synchronization with a loop that is already playing\n * This method will schedule the implicit loop in sync with the explicit master loop\n * i.e. loopToStart.syncedStart(loopToSyncWith)\n *\n * @method syncedStart\n * @for p5.SoundLoop\n * @param {Object} otherLoop a p5.SoundLoop to sync with\n * @param {Number} [timeFromNow] Start the loops in sync after timeFromNow seconds\n */\n p5.SoundLoop.prototype.syncedStart = function(otherLoop, timeFromNow) {\n var t = timeFromNow || 0;\n var now = p5sound.audiocontext.currentTime;\n\n if (!otherLoop.isPlaying) {\n otherLoop.clock.start(now + t);\n otherLoop.isPlaying = true;\n this.clock.start(now + t);\n this.isPlaying = true;\n } else if (otherLoop.isPlaying) {\n var time = otherLoop.clock._nextTick - p5sound.audiocontext.currentTime;\n this.clock.start(now + time);\n this.isPlaying = true;\n }\n };\n\n\n /**\n * Updates frequency value, reflected in next callback\n * @private\n * @for p5.SoundLoop\n * @method _update\n */\n p5.SoundLoop.prototype._update = function() {\n this.clock.frequency.value = this._calcFreq();\n };\n\n /**\n * Calculate the frequency of the clock's callback based on bpm, interval, and timesignature\n * @private\n * @for p5.SoundLoop\n * @method _calcFreq\n * @return {Number} new clock frequency value\n */\n p5.SoundLoop.prototype._calcFreq = function() {\n //Seconds mode, bpm / timesignature has no effect\n if (typeof this._interval === 'number') {\n this.musicalTimeMode = false;\n return 1 / this._interval;\n }\n //Musical timing mode, calculate interval based bpm, interval,and time signature\n else if (typeof this._interval === 'string') {\n this.musicalTimeMode = true;\n return this._bpm / 60 / this._convertNotation(this._interval) * (this._timeSignature / 4);\n }\n };\n\n /**\n * Convert notation from musical time format to seconds\n * Uses Tone.Time convention\n * @private\n * @for p5.SoundLoop\n * @method _convertNotation\n * @param {String} value value to be converted\n * @return {Number} converted value in seconds\n */\n p5.SoundLoop.prototype._convertNotation = function(value) {\n var type = value.slice(-1);\n value = Number(value.slice(0,-1));\n switch (type) {\n case 'm':\n return this._measure(value);\n case 'n':\n return this._note(value);\n default:\n console.warn('Specified interval is not formatted correctly. See Tone.js '+\n 'timing reference for more info: https://github.com/Tonejs/Tone.js/wiki/Time');\n }\n };\n\n /**\n * Helper conversion methods of measure and note\n * @private\n * @for p5.SoundLoop\n * @method _measure\n */\n p5.SoundLoop.prototype._measure = function(value) {\n return value * this._timeSignature;\n };\n\n /**\n * @private\n * @method _note\n * @for p5.SoundLoop\n */\n p5.SoundLoop.prototype._note = function(value) {\n return this._timeSignature / value ;\n };\n\n\n /**\n * Getters and Setters, setting any paramter will result in a change in the clock's\n * frequency, that will be reflected after the next callback\n * beats per minute (defaults to 60)\n * @property {Number} bpm\n * @for p5.SoundLoop\n */\n Object.defineProperty(p5.SoundLoop.prototype, 'bpm', {\n get : function() {\n return this._bpm;\n },\n set : function(bpm) {\n if (!this.musicalTimeMode) {\n console.warn('Changing the BPM in \"seconds\" mode has no effect. '+\n 'BPM is only relevant in musicalTimeMode '+\n 'when the interval is specified as a string '+\n '(\"2n\", \"4n\", \"1m\"...etc)');\n }\n this._bpm = bpm;\n this._update();\n }\n });\n\n /**\n * number of quarter notes in a measure (defaults to 4)\n * @property {Number} timeSignature\n * @for p5.SoundLoop\n */\n Object.defineProperty(p5.SoundLoop.prototype, 'timeSignature', {\n get : function() {\n return this._timeSignature;\n },\n set : function(timeSig) {\n if (!this.musicalTimeMode) {\n console.warn('Changing the timeSignature in \"seconds\" mode has no effect. '+\n 'BPM is only relevant in musicalTimeMode '+\n 'when the interval is specified as a string '+\n '(\"2n\", \"4n\", \"1m\"...etc)');\n }\n this._timeSignature = timeSig;\n this._update();\n }\n });\n\n /**\n * length of the loops interval\n * @property {Number|String} interval\n * @for p5.SoundLoop\n */\n Object.defineProperty(p5.SoundLoop.prototype, 'interval', {\n get : function() {\n return this._interval;\n },\n set : function(interval) {\n this.musicalTimeMode = typeof interval === 'Number'? false : true;\n this._interval = interval;\n this._update();\n }\n });\n\n /**\n * how many times the callback has been called so far\n * @property {Number} iterations\n * @for p5.SoundLoop\n * @readonly\n */\n Object.defineProperty(p5.SoundLoop.prototype, 'iterations', {\n get : function() {\n return this.clock.ticks;\n }\n });\n\n return p5.SoundLoop;\n});\n","define(function (require) {\n\t'use strict';\n\n\tvar p5sound = require('master');\n\tvar Effect = require('effect');\n var CustomError = require('errorHandler');\n\n /**\n * Compressor is an audio effect class that performs dynamics compression\n * on an audio input source. This is a very commonly used technique in music\n * and sound production. Compression creates an overall louder, richer,\n * and fuller sound by lowering the volume of louds and raising that of softs.\n * Compression can be used to avoid clipping (sound distortion due to\n * peaks in volume) and is especially useful when many sounds are played\n * at once. Compression can be used on indivudal sound sources in addition\n * to the master output.\n *\n * This class extends p5.Effect.\n * Methods amp(), chain(),\n * drywet(), connect(), and\n * disconnect() are available.\n *\n * @class p5.Compressor\n * @constructor\n * @extends p5.Effect\n *\n *\n */\n\tp5.Compressor = function() {\n\t\tEffect.call(this);\n\n /**\n * The p5.Compressor is built with a Web Audio Dynamics Compressor Node\n * \n * @property {AudioNode} compressor\n */\n\n\n\t\tthis.compressor = this.ac.createDynamicsCompressor();\n\n this.input.connect(this.compressor);\n this.compressor.connect(this.wet);\n\t};\n\n\tp5.Compressor.prototype = Object.create(Effect.prototype);\n\n /**\n * Performs the same function as .connect, but also accepts\n * optional parameters to set compressor's audioParams\n * @method process\n * @for p5.Compressor\n *\n * @param {Object} src Sound source to be connected\n *\n * @param {Number} [attack] The amount of time (in seconds) to reduce the gain by 10dB,\n * default = .003, range 0 - 1\n * @param {Number} [knee] A decibel value representing the range above the\n * threshold where the curve smoothly transitions to the \"ratio\" portion.\n * default = 30, range 0 - 40\n * @param {Number} [ratio] The amount of dB change in input for a 1 dB change in output\n * default = 12, range 1 - 20\n * @param {Number} [threshold] The decibel value above which the compression will start taking effect\n * default = -24, range -100 - 0\n * @param {Number} [release] The amount of time (in seconds) to increase the gain by 10dB\n * default = .25, range 0 - 1\n */\n\tp5.Compressor.prototype.process = function(src, attack, knee,\n ratio, threshold, release) {\n\t\tsrc.connect(this.input);\n\t\tthis.set(attack, knee, ratio, threshold, release);\n\t};\n\n /**\n * Set the paramters of a compressor.\n * @method set\n * @for p5.Compressor\n * @param {Number} attack The amount of time (in seconds) to reduce the gain by 10dB,\n * default = .003, range 0 - 1\n * @param {Number} knee A decibel value representing the range above the\n * threshold where the curve smoothly transitions to the \"ratio\" portion.\n * default = 30, range 0 - 40\n * @param {Number} ratio The amount of dB change in input for a 1 dB change in output\n * default = 12, range 1 - 20\n * @param {Number} threshold The decibel value above which the compression will start taking effect\n * default = -24, range -100 - 0\n * @param {Number} release The amount of time (in seconds) to increase the gain by 10dB\n * default = .25, range 0 - 1\n */\n p5.Compressor.prototype.set = function (attack, knee,\n ratio, threshold, release) {\n\n if (typeof attack !== 'undefined') {this.attack(attack);}\n if (typeof knee !== 'undefined') {this.knee(knee);}\n if (typeof ratio !== 'undefined') {this.ratio(ratio);}\n if (typeof threshold !== 'undefined') {this.threshold(threshold);}\n if (typeof release !== 'undefined') {this.release(release);}\n };\n\n\n /**\n * Get current attack or set value w/ time ramp\n *\n *\n * @method attack\n * @for p5.Compressor\n * @param {Number} [attack] Attack is the amount of time (in seconds) to reduce the gain by 10dB,\n * default = .003, range 0 - 1\n * @param {Number} [time] Assign time value to schedule the change in value\n */\n p5.Compressor.prototype.attack = function (attack, time){\n var t = time || 0;\n if (typeof attack == 'number'){\n this.compressor.attack.value = attack;\n this.compressor.attack.cancelScheduledValues(this.ac.currentTime + 0.01 + t);\n this.compressor.attack.linearRampToValueAtTime(attack, this.ac.currentTime + 0.02 + t);\n } else if (typeof attack !== 'undefined') {\n attack.connect(this.compressor.attack);\n }\n return this.compressor.attack.value;\n };\n\n\n /**\n * Get current knee or set value w/ time ramp\n *\n * @method knee\n * @for p5.Compressor\n * @param {Number} [knee] A decibel value representing the range above the\n * threshold where the curve smoothly transitions to the \"ratio\" portion.\n * default = 30, range 0 - 40\n * @param {Number} [time] Assign time value to schedule the change in value\n */\n p5.Compressor.prototype.knee = function (knee, time){\n var t = time || 0;\n if (typeof knee == 'number'){\n this.compressor.knee.value = knee;\n this.compressor.knee.cancelScheduledValues(this.ac.currentTime + 0.01 + t);\n this.compressor.knee.linearRampToValueAtTime(knee, this.ac.currentTime + 0.02 + t);\n } else if (typeof knee !== 'undefined') {\n knee.connect(this.compressor.knee);\n }\n return this.compressor.knee.value;\n };\n\n\n /**\n * Get current ratio or set value w/ time ramp\n * @method ratio\n * @for p5.Compressor\n * @param {Number} [ratio] The amount of dB change in input for a 1 dB change in output\n * default = 12, range 1 - 20\n * @param {Number} [time] Assign time value to schedule the change in value\n */\n p5.Compressor.prototype.ratio = function (ratio, time){\n var t = time || 0;\n if (typeof ratio == 'number'){\n this.compressor.ratio.value = ratio;\n this.compressor.ratio.cancelScheduledValues(this.ac.currentTime + 0.01 + t);\n this.compressor.ratio.linearRampToValueAtTime(ratio, this.ac.currentTime + 0.02 + t);\n } else if (typeof ratio !== 'undefined') {\n ratio.connect(this.compressor.ratio);\n }\n return this.compressor.ratio.value;\n };\n\n\n /**\n * Get current threshold or set value w/ time ramp\n * @method threshold\n * @for p5.Compressor\n * @param {Number} threshold The decibel value above which the compression will start taking effect\n * default = -24, range -100 - 0\n * @param {Number} [time] Assign time value to schedule the change in value\n */\n p5.Compressor.prototype.threshold = function (threshold, time){\n var t = time || 0;\n if (typeof threshold == 'number'){\n this.compressor.threshold.value = threshold;\n this.compressor.threshold.cancelScheduledValues(this.ac.currentTime + 0.01 + t);\n this.compressor.threshold.linearRampToValueAtTime(threshold, this.ac.currentTime + 0.02 + t);\n } else if (typeof threshold !== 'undefined') {\n threshold.connect(this.compressor.threshold);\n }\n return this.compressor.threshold.value;\n };\n\n\n /**\n * Get current release or set value w/ time ramp\n * @method release\n * @for p5.Compressor\n * @param {Number} release The amount of time (in seconds) to increase the gain by 10dB\n * default = .25, range 0 - 1\n *\n * @param {Number} [time] Assign time value to schedule the change in value\n */\n p5.Compressor.prototype.release = function (release, time){\n var t = time || 0;\n if (typeof release == 'number'){\n this.compressor.release.value = release;\n this.compressor.release.cancelScheduledValues(this.ac.currentTime + 0.01 + t);\n this.compressor.release.linearRampToValueAtTime(release, this.ac.currentTime + 0.02 + t);\n } else if (typeof number !== 'undefined') {\n release.connect(this.compressor.release);\n }\n return this.compressor.release.value;\n };\n\n /**\n * Return the current reduction value\n *\n * @method reduction\n * @for p5.Compressor\n * @return {Number} Value of the amount of gain reduction that is applied to the signal\n */\n p5.Compressor.prototype.reduction =function() {\n return this.compressor.reduction.value;\n };\n\n\n\tp5.Compressor.prototype.dispose = function() {\n Effect.prototype.dispose.apply(this);\n if (this.compressor) {\n this.compressor.disconnect();\n delete this.compressor;\n }\n\t};\n\n return p5.Compressor;\n});\n","'use strict';\n\ndefine(function (require) {\n\n // inspiration: recorder.js, Tone.js & typedarray.org\n\n var p5sound = require('master');\n var convertToWav = require('helpers').convertToWav;\n var processorNames = require('./audioWorklet/processorNames');\n var ac = p5sound.audiocontext;\n\n /**\n *
Record sounds for playback and/or to save as a .wav file.\n * The p5.SoundRecorder records all sound output from your sketch,\n * or can be assigned a specific source with setInput().
\n *
The record() method accepts a p5.SoundFile as a parameter.\n * When playback is stopped (either after the given amount of time,\n * or with the stop() method), the p5.SoundRecorder will send its\n * recording to that p5.SoundFile for playback.
\n * var mic, recorder, soundFile;\n * var state = 0;\n *\n * function setup() {\n * background(200);\n * // create an audio in\n * mic = new p5.AudioIn();\n *\n * // prompts user to enable their browser mic\n * mic.start();\n *\n * // create a sound recorder\n * recorder = new p5.SoundRecorder();\n *\n * // connect the mic to the recorder\n * recorder.setInput(mic);\n *\n * // this sound file will be used to\n * // playback & save the recording\n * soundFile = new p5.SoundFile();\n *\n * text('keyPress to record', 20, 20);\n * }\n *\n * function keyPressed() {\n * // make sure user enabled the mic\n * if (state === 0 && mic.enabled) {\n *\n * // record to our p5.SoundFile\n * recorder.record(soundFile);\n *\n * background(255,0,0);\n * text('Recording!', 20, 20);\n * state++;\n * }\n * else if (state === 1) {\n * background(0,255,0);\n *\n * // stop recorder and\n * // send result to soundFile\n * recorder.stop();\n *\n * text('Stopped', 20, 20);\n * state++;\n * }\n *\n * else if (state === 2) {\n * soundFile.play(); // play the result!\n * save(soundFile, 'mySound.wav');\n * state++;\n * }\n * }\n *
\n */\n p5.SoundRecorder = function() {\n this.input = ac.createGain();\n this.output = ac.createGain();\n\n this._inputChannels = 2;\n this._outputChannels = 2; // stereo output, even if input is mono\n\n this._workletNode = new AudioWorkletNode(ac, processorNames.recorderProcessor, {\n outputChannelCount: [this._outputChannels],\n processorOptions: { numInputChannels: this._inputChannels }\n });\n\n this._workletNode.port.onmessage = function(event) {\n if (event.data.name === 'buffers') {\n const buffers = [\n new Float32Array(event.data.leftBuffer),\n new Float32Array(event.data.rightBuffer)\n ];\n this._callback(buffers);\n }\n }.bind(this);\n\n /**\n * callback invoked when the recording is over\n * @private\n * @type Function(Float32Array)\n */\n this._callback = function() {};\n\n // connections\n this._workletNode.connect(p5.soundOut._silentNode);\n this.setInput();\n\n // add this p5.SoundFile to the soundArray\n p5sound.soundArray.push(this);\n };\n\n /**\n * Connect a specific device to the p5.SoundRecorder.\n * If no parameter is given, p5.SoundRecorer will record\n * all audible p5.sound from your sketch.\n *\n * @method setInput\n * @for p5.SoundRecorder\n * @param {Object} [unit] p5.sound object or a web audio unit\n * that outputs sound\n */\n p5.SoundRecorder.prototype.setInput = function(unit) {\n this.input.disconnect();\n this.input = null;\n this.input = ac.createGain();\n this.input.connect(this._workletNode);\n this.input.connect(this.output);\n if (unit) {\n unit.connect(this.input);\n } else {\n p5.soundOut.output.connect(this.input);\n }\n };\n\n /**\n * Start recording. To access the recording, provide\n * a p5.SoundFile as the first parameter. The p5.SoundRecorder\n * will send its recording to that p5.SoundFile for playback once\n * recording is complete. Optional parameters include duration\n * (in seconds) of the recording, and a callback function that\n * will be called once the complete recording has been\n * transfered to the p5.SoundFile.\n *\n * @method record\n * @for p5.SoundRecorder\n * @param {p5.SoundFile} soundFile p5.SoundFile\n * @param {Number} [duration] Time (in seconds)\n * @param {Function} [callback] The name of a function that will be\n * called once the recording completes\n */\n p5.SoundRecorder.prototype.record = function(sFile, duration, callback) {\n this._workletNode.port.postMessage({ name: 'start', duration: duration });\n\n if (sFile && callback) {\n this._callback = function(buffer) {\n sFile.setBuffer(buffer);\n callback();\n };\n }\n else if (sFile) {\n this._callback = function(buffer) {\n sFile.setBuffer(buffer);\n };\n }\n };\n\n /**\n * Stop the recording. Once the recording is stopped,\n * the results will be sent to the p5.SoundFile that\n * was given on .record(), and if a callback function\n * was provided on record, that function will be called.\n *\n * @method stop\n * @for p5.SoundRecorder\n */\n p5.SoundRecorder.prototype.stop = function() {\n this._workletNode.port.postMessage({ name: 'stop' });\n };\n\n p5.SoundRecorder.prototype.dispose = function() {\n // remove reference from soundArray\n var index = p5sound.soundArray.indexOf(this);\n p5sound.soundArray.splice(index, 1);\n\n this._callback = function() {};\n if (this.input) {\n this.input.disconnect();\n }\n this.input = null;\n this._workletNode = null;\n };\n\n\n /**\n * Save a p5.SoundFile as a .wav file. The browser will prompt the user\n * to download the file to their device.\n * For uploading audio to a server, use\n * `p5.SoundFile.saveBlob`.\n *\n * @for p5\n * @method saveSound\n * @param {p5.SoundFile} soundFile p5.SoundFile that you wish to save\n * @param {String} fileName name of the resulting .wav file.\n */\n // add to p5.prototype as this is used by the p5 `save()` method.\n p5.prototype.saveSound = function (soundFile, fileName) {\n const dataView = convertToWav(soundFile.buffer);\n p5.prototype.writeFile([dataView], fileName, 'wav');\n };\n});\n","'use strict';\n\ndefine(function () {\n /**\n *
PeakDetect works in conjunction with p5.FFT to\n * look for onsets in some or all of the frequency spectrum.\n *
\n *
\n * To use p5.PeakDetect, call update in the draw loop\n * and pass in a p5.FFT object.\n *
\n *
\n * You can listen for a specific part of the frequency spectrum by\n * setting the range between freq1 and freq2.\n *
\n *\n *
threshold is the threshold for detecting a peak,\n * scaled between 0 and 1. It is logarithmic, so 0.1 is half as loud\n * as 1.0.
\n *\n *
\n * The update method is meant to be run in the draw loop, and\n * frames determines how many loops must pass before\n * another peak can be detected.\n * For example, if the frameRate() = 60, you could detect the beat of a\n * 120 beat-per-minute song with this equation:\n * framesPerPeak = 60 / (estimatedBPM / 60 );\n *
\n *\n *
\n * Based on example contribtued by @b2renger, and a simple beat detection\n * explanation by Felix Turner.\n *
\n *\n * @class p5.PeakDetect\n * @constructor\n * @param {Number} [freq1] lowFrequency - defaults to 20Hz\n * @param {Number} [freq2] highFrequency - defaults to 20000 Hz\n * @param {Number} [threshold] Threshold for detecting a beat between 0 and 1\n * scaled logarithmically where 0.1 is 1/2 the loudness\n * of 1.0. Defaults to 0.35.\n * @param {Number} [framesPerPeak] Defaults to 20.\n * @example\n *
\n */\n p5.PeakDetect = function(freq1, freq2, threshold, _framesPerPeak) {\n // framesPerPeak determines how often to look for a beat.\n // If a beat is provided, try to look for a beat based on bpm\n this.framesPerPeak = _framesPerPeak || 20;\n this.framesSinceLastPeak = 0;\n this.decayRate = 0.95;\n\n this.threshold = threshold || 0.35;\n this.cutoff = 0;\n\n // how much to increase the cutoff\n // TO DO: document this / figure out how to make it accessible\n this.cutoffMult = 1.5;\n\n this.energy = 0;\n this.penergy = 0;\n\n // TO DO: document this property / figure out how to make it accessible\n this.currentValue = 0;\n\n /**\n * isDetected is set to true when a peak is detected.\n *\n * @attribute isDetected {Boolean}\n * @default false\n */\n this.isDetected = false;\n\n this.f1 = freq1 || 40;\n this.f2 = freq2 || 20000;\n\n // function to call when a peak is detected\n this._onPeak = function() {};\n };\n\n\n /**\n * The update method is run in the draw loop.\n *\n * Accepts an FFT object. You must call .analyze()\n * on the FFT object prior to updating the peakDetect\n * because it relies on a completed FFT analysis.\n *\n * @method update\n * @param {p5.FFT} fftObject A p5.FFT object\n */\n p5.PeakDetect.prototype.update = function(fftObject) {\n var nrg = this.energy = fftObject.getEnergy(this.f1,this.f2)/255;\n if (nrg > this.cutoff && nrg > this.threshold && nrg-this.penergy > 0) {\n\n // trigger callback\n this._onPeak();\n this.isDetected = true;\n\n // debounce\n this.cutoff = nrg * this.cutoffMult;\n this.framesSinceLastPeak = 0;\n } else {\n this.isDetected = false;\n if (this.framesSinceLastPeak <= this.framesPerPeak) {\n this.framesSinceLastPeak++;\n } else {\n this.cutoff *= this.decayRate;\n this.cutoff = Math.max(this.cutoff, this.threshold);\n }\n }\n\n this.currentValue = nrg;\n this.penergy = nrg;\n };\n\n /**\n * onPeak accepts two arguments: a function to call when\n * a peak is detected. The value of the peak,\n * between 0.0 and 1.0, is passed to the callback.\n *\n * @method onPeak\n * @param {Function} callback Name of a function that will\n * be called when a peak is\n * detected.\n * @param {Object} [val] Optional value to pass\n * into the function when\n * a peak is detected.\n * @example\n *
\n * var cnv, soundFile, fft, peakDetect;\n * var ellipseWidth = 0;\n *\n * function preload() {\n * soundFile = loadSound('assets/beat.mp3');\n * }\n *\n * function setup() {\n * cnv = createCanvas(100,100);\n * textAlign(CENTER);\n *\n * fft = new p5.FFT();\n * peakDetect = new p5.PeakDetect();\n *\n * setupSound();\n *\n * // when a beat is detected, call triggerBeat()\n * peakDetect.onPeak(triggerBeat);\n * }\n *\n * function draw() {\n * background(0);\n * fill(255);\n * text('click to play', width/2, height/2);\n *\n * fft.analyze();\n * peakDetect.update(fft);\n *\n * ellipseWidth *= 0.95;\n * ellipse(width/2, height/2, ellipseWidth, ellipseWidth);\n * }\n *\n * // this function is called by peakDetect.onPeak\n * function triggerBeat() {\n * ellipseWidth = 50;\n * }\n *\n * // mouseclick starts/stops sound\n * function setupSound() {\n * cnv.mouseClicked( function() {\n * if (soundFile.isPlaying() ) {\n * soundFile.stop();\n * } else {\n * soundFile.play();\n * }\n * });\n * }\n *
\n */\n p5.PeakDetect.prototype.onPeak = function(callback, val) {\n var self = this;\n\n self._onPeak = function() {\n callback(self.energy, val);\n };\n };\n\n});\n","'use strict';\n\ndefine(function (require) {\n var p5sound = require('master');\n\n /**\n * A gain node is usefull to set the relative volume of sound.\n * It's typically used to build mixers.\n *\n * @class p5.Gain\n * @constructor\n * @example\n *
\n *\n * // load two soundfile and crossfade beetween them\n * var sound1,sound2;\n * var gain1, gain2, gain3;\n *\n * function preload(){\n * soundFormats('ogg', 'mp3');\n * sound1 = loadSound('assets/Damscray_-_Dancing_Tiger_01');\n * sound2 = loadSound('assets/beat.mp3');\n * }\n *\n * function setup() {\n * createCanvas(400,200);\n *\n * // create a 'master' gain to which we will connect both soundfiles\n * gain3 = new p5.Gain();\n * gain3.connect();\n *\n * // setup first sound for playing\n * sound1.rate(1);\n * sound1.loop();\n * sound1.disconnect(); // diconnect from p5 output\n *\n * gain1 = new p5.Gain(); // setup a gain node\n * gain1.setInput(sound1); // connect the first sound to its input\n * gain1.connect(gain3); // connect its output to the 'master'\n *\n * sound2.rate(1);\n * sound2.disconnect();\n * sound2.loop();\n *\n * gain2 = new p5.Gain();\n * gain2.setInput(sound2);\n * gain2.connect(gain3);\n *\n * }\n *\n * function draw(){\n * background(180);\n *\n * // calculate the horizontal distance beetween the mouse and the right of the screen\n * var d = dist(mouseX,0,width,0);\n *\n * // map the horizontal position of the mouse to values useable for volume control of sound1\n * var vol1 = map(mouseX,0,width,0,1);\n * var vol2 = 1-vol1; // when sound1 is loud, sound2 is quiet and vice versa\n *\n * gain1.amp(vol1,0.5,0);\n * gain2.amp(vol2,0.5,0);\n *\n * // map the vertical position of the mouse to values useable for 'master volume control'\n * var vol3 = map(mouseY,0,height,0,1);\n * gain3.amp(vol3,0.5,0);\n * }\n *
\n *\n */\n\n p5.Gain = function() {\n this.ac = p5sound.audiocontext;\n\n this.input = this.ac.createGain();\n this.output = this.ac.createGain();\n\n // otherwise, Safari distorts\n this.input.gain.value = 0.5;\n this.input.connect(this.output);\n\n // add to the soundArray\n p5sound.soundArray.push(this);\n };\n\n /**\n * Connect a source to the gain node.\n *\n * @method setInput\n * @for p5.Gain\n * @param {Object} src p5.sound / Web Audio object with a sound\n * output.\n */\n\n\n p5.Gain.prototype.setInput = function(src) {\n src.connect(this.input);\n };\n\n /**\n * Send output to a p5.sound or web audio object\n *\n * @method connect\n * @for p5.Gain\n * @param {Object} unit\n */\n p5.Gain.prototype.connect = function(unit) {\n var u = unit || p5.soundOut.input;\n this.output.connect(u.input ? u.input : u);\n };\n\n /**\n * Disconnect all output.\n *\n * @method disconnect\n * @for p5.Gain\n */\n p5.Gain.prototype.disconnect = function() {\n if (this.output) {\n this.output.disconnect();\n }\n };\n\n /**\n * Set the output level of the gain node.\n *\n * @method amp\n * @for p5.Gain\n * @param {Number} volume amplitude between 0 and 1.0\n * @param {Number} [rampTime] create a fade that lasts rampTime\n * @param {Number} [timeFromNow] schedule this event to happen\n * seconds from now\n */\n p5.Gain.prototype.amp = function(vol, rampTime, tFromNow) {\n var rampTime = rampTime || 0;\n var tFromNow = tFromNow || 0;\n var now = p5sound.audiocontext.currentTime;\n var currentVol = this.output.gain.value;\n this.output.gain.cancelScheduledValues(now);\n this.output.gain.linearRampToValueAtTime(currentVol, now + tFromNow);\n this.output.gain.linearRampToValueAtTime(vol, now + tFromNow + rampTime);\n };\n\n p5.Gain.prototype.dispose = function() {\n // remove reference from soundArray\n var index = p5sound.soundArray.indexOf(this);\n p5sound.soundArray.splice(index, 1);\n if (this.output) {\n this.output.disconnect();\n delete this.output;\n }\n if (this.input) {\n this.input.disconnect();\n delete this.input;\n }\n };\n\n});\n","'use strict';\n\ndefine(function (require) {\n\n var Effect = require('effect');\n\n /*\n * Adapted from [Kevin Ennis on StackOverflow](http://stackoverflow.com/questions/22312841/waveshaper-node-in-webaudio-how-to-emulate-distortion)\n */\n function makeDistortionCurve(amount) {\n var k = typeof amount === 'number' ? amount : 50;\n var numSamples = 44100;\n var curve = new Float32Array(numSamples);\n var deg = Math.PI / 180;\n var i = 0;\n var x;\n for ( ; i < numSamples; ++i ) {\n x = i * 2 / numSamples - 1;\n curve[i] = ( 3 + k ) * x * 20 * deg / ( Math.PI + k * Math.abs(x) );\n }\n return curve;\n }\n\n /**\n * A Distortion effect created with a Waveshaper Node,\n * with an approach adapted from\n * [Kevin Ennis](http://stackoverflow.com/questions/22312841/waveshaper-node-in-webaudio-how-to-emulate-distortion)\n *\n * This class extends p5.Effect.\n * Methods amp(), chain(),\n * drywet(), connect(), and\n * disconnect() are available.\n *\n * @class p5.Distortion\n * @extends p5.Effect\n * @constructor\n * @param {Number} [amount=0.25] Unbounded distortion amount.\n * Normal values range from 0-1.\n * @param {String} [oversample='none'] 'none', '2x', or '4x'.\n *\n */\n p5.Distortion = function(amount, oversample) {\n Effect.call(this);\n\n if (typeof amount === 'undefined') {\n amount = 0.25;\n } if (typeof amount !== 'number') {\n throw new Error('amount must be a number');\n } if (typeof oversample === 'undefined') {\n oversample = '2x';\n } if (typeof oversample !== 'string') {\n throw new Error('oversample must be a String');\n }\n\n var curveAmount = p5.prototype.map(amount, 0.0, 1.0, 0, 2000);\n\n /**\n * The p5.Distortion is built with a\n * \n * Web Audio WaveShaper Node.\n *\n * @property {AudioNode} WaveShaperNode\n */\n this.waveShaperNode = this.ac.createWaveShaper();\n\n this.amount = curveAmount;\n this.waveShaperNode.curve = makeDistortionCurve(curveAmount);\n this.waveShaperNode.oversample = oversample;\n\n this.input.connect(this.waveShaperNode);\n\n this.waveShaperNode.connect(this.wet);\n };\n\n p5.Distortion.prototype = Object.create(Effect.prototype);\n\n\n /**\n * Process a sound source, optionally specify amount and oversample values.\n *\n * @method process\n * @for p5.Distortion\n * @param {Number} [amount=0.25] Unbounded distortion amount.\n * Normal values range from 0-1.\n * @param {String} [oversample='none'] 'none', '2x', or '4x'.\n */\n p5.Distortion.prototype.process = function(src, amount, oversample) {\n src.connect(this.input);\n this.set(amount, oversample);\n };\n\n /**\n * Set the amount and oversample of the waveshaper distortion.\n *\n * @method set\n * @for p5.Distortion\n * @param {Number} [amount=0.25] Unbounded distortion amount.\n * Normal values range from 0-1.\n * @param {String} [oversample='none'] 'none', '2x', or '4x'.\n */\n p5.Distortion.prototype.set = function(amount, oversample) {\n if (amount) {\n var curveAmount = p5.prototype.map(amount, 0.0, 1.0, 0, 2000);\n this.amount = curveAmount;\n this.waveShaperNode.curve = makeDistortionCurve(curveAmount);\n }\n if (oversample) {\n this.waveShaperNode.oversample = oversample;\n }\n };\n\n /**\n * Return the distortion amount, typically between 0-1.\n *\n * @method getAmount\n * @for p5.Distortion\n * @return {Number} Unbounded distortion amount.\n * Normal values range from 0-1.\n */\n p5.Distortion.prototype.getAmount = function() {\n return this.amount;\n };\n\n /**\n * Return the oversampling.\n *\n * @method getOversample\n * @for p5.Distortion\n * @return {String} Oversample can either be 'none', '2x', or '4x'.\n */\n p5.Distortion.prototype.getOversample = function() {\n return this.waveShaperNode.oversample;\n };\n\n\n p5.Distortion.prototype.dispose = function() {\n Effect.prototype.dispose.apply(this);\n if (this.waveShaperNode) {\n this.waveShaperNode.disconnect();\n this.waveShaperNode = null;\n }\n };\n});\n"],"sourceRoot":""}
\ No newline at end of file
+{"version":3,"sources":["webpack:///webpack/bootstrap","webpack:///../node_modules/tone/Tone/core/Tone.js","webpack:///./master.js","webpack:///../node_modules/tone/Tone/signal/Signal.js","webpack:///../node_modules/tone/Tone/signal/Multiply.js","webpack:///./effect.js","webpack:///../node_modules/tone/Tone/signal/WaveShaper.js","webpack:///./helpers.js","webpack:///../node_modules/tone/Tone/signal/Add.js","webpack:///../node_modules/tone/Tone/type/Type.js","webpack:///../node_modules/tone/Tone/core/Gain.js","webpack:///./errorHandler.js","webpack:///../node_modules/tone/Tone/core/Context.js","webpack:///./audioWorklet/processorNames.js","webpack:///../node_modules/tone/Tone/signal/Scale.js","webpack:///../node_modules/tone/Tone/signal/TimelineSignal.js","webpack:///./filter.js","webpack:///../node_modules/tone/Tone/signal/Subtract.js","webpack:///./audiocontext.js","webpack:///../node_modules/tone/Tone/core/Emitter.js","webpack:///../node_modules/tone/Tone/signal/SignalBase.js","webpack:///../node_modules/tone/Tone/type/Time.js","webpack:///../node_modules/tone/Tone/type/TimeBase.js","webpack:///../node_modules/tone/Tone/core/Param.js","webpack:///./oscillator.js","webpack:///../node_modules/tone/Tone/core/Timeline.js","webpack:///../node_modules/tone/Tone/signal/Negate.js","webpack:///../node_modules/tone/Tone/signal/GreaterThanZero.js","webpack:///../node_modules/tone/Tone/core/Clock.js","webpack:///./monosynth.js","webpack:///./audioVoice.js","webpack:///./polysynth.js","webpack:///./app.js","webpack:///../node_modules/audioworklet-polyfill/dist/audioworklet-polyfill.js","webpack:///./shims.js","webpack:///../node_modules/webpack/buildin/global.js","webpack:///../node_modules/startaudiocontext/StartAudioContext.js","webpack:///./audioWorklet/index.js","webpack:///./audioWorklet/recorderProcessor.js","webpack:///./audioWorklet/soundFileProcessor.js","webpack:///./audioWorklet/amplitudeProcessor.js","webpack:///./panner.js","webpack:///./soundfile.js","webpack:///./amplitude.js","webpack:///./fft.js","webpack:///./signal.js","webpack:///../node_modules/tone/Tone/type/Frequency.js","webpack:///../node_modules/tone/Tone/type/TransportTime.js","webpack:///./envelope.js","webpack:///./pulse.js","webpack:///./noise.js","webpack:///./audioin.js","webpack:///../node_modules/tone/Tone/component/CrossFade.js","webpack:///../node_modules/tone/Tone/signal/Expr.js","webpack:///../node_modules/tone/Tone/signal/GreaterThan.js","webpack:///../node_modules/tone/Tone/signal/Abs.js","webpack:///../node_modules/tone/Tone/signal/Modulo.js","webpack:///../node_modules/tone/Tone/signal/Pow.js","webpack:///../node_modules/tone/Tone/signal/AudioToGain.js","webpack:///../node_modules/tone/Tone/signal/EqualPowerGain.js","webpack:///./eq.js","webpack:///./eqFilter.js","webpack:///./panner3d.js","webpack:///./listener3d.js","webpack:///./delay.js","webpack:///./reverb.js","webpack:///./metro.js","webpack:///../node_modules/tone/Tone/core/TimelineState.js","webpack:///./looper.js","webpack:///./soundLoop.js","webpack:///./compressor.js","webpack:///./soundRecorder.js","webpack:///./peakDetect.js","webpack:///./gain.js","webpack:///./distortion.js"],"names":["define","Tone","inputs","outputs","this","isUndef","input","context","createGain","Array","output","audioContext","prototype","set","params","value","rampTime","isObject","isString","tmpObj","paramLoop","attr","parent","indexOf","attrSplit","split","i","length","splice","innerParam","join","param","Signal","Param","rampTo","AudioParam","get","_collectDefaults","constructor","ret","subRet","j","subAttr","isFunction","constr","defaults","Object","keys","_super","superDefs","push","toString","className","isLetter","match","sameConstructor","defineProperty","isArray","dispose","AudioNode","disconnect","connect","unit","outputNum","inputNum","defaultArg","destination","isNumber","apply","arguments","connectSeries","currentUnit","toUnit","chain","fan","given","fallback","givenProp","fallbackProp","optionsObject","values","options","val","arg","call","isBoolean","noOp","_readOnly","property","writable","enumerable","_writable","State","Started","Stopped","Paused","equalPowerScale","percent","piFactor","Math","PI","sin","dbToGain","db","pow","gainToDb","gain","log","LN10","intervalToFrequencyRatio","interval","now","extend","child","TempConstructor","Context","emit","setContext","ctx","sampleRate","hasAudioContext","window","hasOwnProperty","hasPromises","hasWorkers","version","TONE_SILENCE_VERSION_LOGGING","console","audiocontext","Master","limiter","createDynamicsCompressor","threshold","ratio","knee","meter","fftMeter","soundArray","parts","extensions","p5sound","p5","getMasterVolume","masterVolume","vol","tFromNow","currentTime","currentVol","cancelScheduledValues","linearRampToValueAtTime","soundOut","_silentNode","_gain","_param","getConstant","units","Type","Default","convert","SignalBase","Multiply","createInsOuts","_mult","Gain","require","CrossFade","Effect","ac","_drywet","wet","a","b","amp","drywet","fade","u","index","undefined","WaveShaper","mapping","bufferLen","_shaper","createWaveShaper","_curve","curve","isFinite","Float32Array","setMap","len","normalized","oversample","oversampling","RangeError","freqToMidi","f","mathlog2","m","round","midiToFreq","noteToFreq","note","wholeNotes","A","B","C","D","E","F","G","toUpperCase","octave","slice","soundFormats","toLowerCase","disposeSound","registerMethod","_checkFileFormats","paths","path","extTest","pop","isFileSupported","pathSplit","pathCore","extension","supported","p","_mathChain","o","math","thisChain","nextChain","type","mathOps","convertToWav","audioBuffer","leftChannel","rightChannel","getChannelData","numberOfChannels","interleaved","interleave","buffer","ArrayBuffer","view","DataView","writeUTFBytes","setUint32","setUint16","lng","volume","setInt16","result","inputIndex","offset","string","setUint8","charCodeAt","Add","_sum","Time","Frequency","TransportTime","Ticks","NormalRange","AudioRange","Decibels","Interval","BPM","Positive","Cents","Degrees","MIDI","BarsBeatsSixteenths","Samples","Hertz","Note","Milliseconds","Seconds","Notation","toSeconds","time","TimeBase","toFrequency","freq","valueOf","toTicks","Transport","ticks","GainNode","AudioContext","createGainNode","_gainNode","CustomError","name","errorTrace","failedPath","err","Error","tempStack","splitStack","originalStack","stack","filter","ln","toneConnect","outNum","inNum","nativeConnect","e","nativeDisconnect","webkitAudioContext","prop","Emitter","_context","_defineProperty","_latencyHint","_lookAhead","_updateInterval","_computedUpdateInterval","_worker","_createWorker","_constants","mixin","bind","URL","webkitURL","blob","Blob","toFixed","blobUrl","createObjectURL","worker","Worker","addEventListener","_lastUpdate","diff","max","createBuffer","arr","constant","createBufferSource","channelCount","channelCountMode","loop","start","lA","blockTime","postMessage","hint","lookAhead","latencyHint","updateInterval","warn","module","exports","recorderProcessor","soundFileProcessor","amplitudeProcessor","Scale","outputMin","outputMax","_outputMin","_outputMax","_scale","_add","_setRange","min","TimelineSignal","_events","Timeline","_initial","_fromUnits","Linear","Exponential","Target","Curve","Set","getValueAtTime","_toUnits","convertedVal","setValueAtTime","startTime","add","endTime","exponentialRampToValueAtTime","beforeEvent","_searchBefore","_minOutput","setValue","sampleTime","setTargetAtTime","timeConstant","setValueCurveAtTime","duration","scaling","floats","segmentTime","after","cancel","setRampPoint","before","_searchAfter","linearRampToValueBetween","finish","exponentialRampToValueBetween","getAfter","previouVal","previous","getBefore","_exponentialApproach","_curveInterpolate","_linearInterpolate","_exponentialInterpolate","t0","v0","v1","t","exp","t1","progress","lowerIndex","floor","upperIndex","ceil","lowerVal","upperVal","Filter","biquad","createBiquadFilter","setType","_on","_untoggledType","create","process","src","res","frequency","Q","toggle","LowPass","HighPass","BandPass","Subtract","_neg","Negate","global","StartAudioContext","getAudioContext","userStartAudio","elements","callback","elt","Element","map","on","event","events","eventName","off","ev","eventList","args","object","functions","func","emitterFunc","node","outputNumber","inputNumber","overridden","_plusNow","_unaryExpressions","quantize","regexp","method","rh","nextSubdivision","lh","subdiv","_expr","expr","subdivision","addNow","_defaultExpr","_noOp","copy","toNotation","retNotation","_toNotationHelper","retTripletNotation","testNotations","_notationToUnits","notationTime","multiple","notation","primaryExprs","_primaryExpressions","notationExprs","n","toBarsBeatsSixteenths","quarterTime","_beatsToUnits","quarters","measures","_timeSignature","sixteenths","parseFloat","PPQ","toSamples","toMilliseconds","_defaultUnits","exprString","_parseExprString","clone","instance","parseInt","_ticksToUnits","hz","_frequencyToUnits","tr","q","s","total","_secondsToUnits","samples","default","_binaryExpressions","+","precedence","-","*","/","neg","_syntaxGlue","(",")","_tokenize","position","tokens","token","getNextToken","trim","substr","expressions","group","opName","op","reg","SyntaxError","next","peek","_matchGroup","prec","test","_parseBinary","lexer","_parseUnary","_parsePrimary","matching","beats","bpm","seconds","timeSignature","_pushExpr","sub","mult","div","_lfo","lfo","LFO","currentVal","exponentialRampToValue","linearRampToValue","Mult","Oscillator","started","phaseAmount","oscillator","createOscillator","_freqMods","panPosition","connection","panner","Panner","stop","abs","freqNode","self","getAmp","isNaN","phase","getFreq","getType","oscMods","pan","pval","getPan","osc2","delayAmt","dNode","createDelay","delayTime","sigChain","mathObj","chainSource","num","scale","inMin","inMax","outMin","outMax","mapOutMin","mapOutMax","SinOsc","TriOsc","SawOsc","SqrOsc","_timeline","_toRemove","_iterating","memory","Infinity","_search","remove","shift","cancelBefore","beginning","end","midPoint","nextEvent","_iterate","lowerBound","upperBound","forEach","forEachBefore","forEachAfter","forEachFrom","forEachAtTime","_multiply","GreaterThanZero","_thresh","Clock","_nextTick","_lastState","_state","TimelineState","_boundLoop","_loop","state","setStateAtTime","pause","loopInterval","lag","currentState","tickTime","getStateAtTime","AudioVoice","DEFAULT_SUSTAIN","MonoSynth","env","Envelope","setRange","setExp","setADSR","setInput","play","velocity","secondsFromNow","susTime","triggerAttack","triggerRelease","vel","ramp","attack","decay","sustain","release","defineProperties","aTime","dTime","sPercent","rTime","sustime","PolySynth","audioVoice","maxVoices","audiovoices","notes","_newest","_oldest","_voicesInUse","_allocateVoices","noteAttack","noteRelease","noteADSR","d","r","timeFromNow","voice","_note","_velocity","acTime","currentVoice","oldestNote","previousVal","_updateAfter","maxRange","nextTime","p5SOUND","fixSetTarget","setTargetValueAtTime","createDelayNode","createScriptProcessor","createJavaScriptNode","createPeriodicWave","createWaveTable","internal_createGain","internal_createDelay","maxDelayTime","internal_createBufferSource","when","noteGrainOn","noteOn","internal_start","noteOff","internal_stop","playbackRate","internal_createDynamicsCompressor","reduction","internal_createBiquadFilter","detune","internal_createOscillator","setPeriodicWave","setWaveTable","OfflineAudioContext","webkitOfflineAudioContext","navigator","getUserMedia","webkitGetUserMedia","mozGetUserMedia","msGetUserMedia","el","document","createElement","isSupported","canPlayType","isOGGSupported","isMP3Supported","isWAVSupported","isAACSupported","isAIFSupported","moduleSources","loadAudioWorkletModules","Promise","all","moduleSrc","objectURL","audioWorklet","addModule","preload","_preloadCount","onWorkletModulesLoad","_decrementPreload","then","createStereoPanner","stereoPanner","inputChannels","obj","numInputChannels","left","right","channelInterpretation","splitter","createChannelSplitter","createChannelMerger","v","rightVal","cos","leftVal","numChannels","processorNames","SoundFile","onload","onerror","whileLoading","url","File","FileReader","FileList","file","_onended","_looping","_playing","_paused","_pauseTime","_cues","_cueIDCounter","_lastPos","_counterNode","_workletNode","bufferSourceNodes","bufferSourceNode","reversed","pauseTime","mode","startMillis","load","_whileLoading","_clearOnEnd","registerPreloadMethod","loadSound","location","origin","cordova","alert","errorCallback","request","XMLHttpRequest","evt","_updateProgress","open","responseType","status","decodeAudioData","response","buff","msg","error","statusText","message","send","reader","readAsArrayBuffer","lengthComputable","percentComplete","loaded","isLoaded","rate","_cueStart","cueStart","cueEnd","setVolume","isPlaying","_initSourceNode","_initCounterNode","_arrayIndex","loopStart","loopEnd","playMode","str","pTime","setLoop","bool","isLooping","isPaused","stopAll","_time","_rampTime","_tFromNow","getVolume","reverse","reverseBuffer","setPitch","newPlaybackRate","getPlaybackRate","jump","cueTime","cTime","dur","channels","frames","getPeaks","width","sampleSize","sampleStep","peaks","c","chan","currentPos","curVol","onended","warning","getLevel","setPath","setBuffer","buf","size","newBuffer","channelNum","channel","_createCounterBuffer","audioBuf","arrayBuffer","cNode","AudioWorkletNode","port","onmessage","data","_onTimeUpdate","processPeaks","_initThreshold","_minThreshold","_minPeaks","bufLen","allPeaks","initialThreshold","minThreshold","minPeaks","offlineContext","source","startRendering","oncomplete","filteredBuffer","renderedBuffer","bufferData","getPeaksAtThreshold","intervalCounts","countIntervalsBetweenNearbyPeaks","groups","groupNeighborsByTempo","topTempos","sort","intA","intB","count","tempo","bpmVariance","tempoPeaks","getPeaksAtTopTempo","Peak","sampleIndex","amplitude","tempos","intervals","peaksObj","peak","peaksArray","startPeak","endPeak","startPos","endPos","foundInterval","some","intervalCount","tempoCounts","theoreticalTempo","mapTempo","foundTempo","tempoCount","peaksAtTopTempo","key","intervalBPM","peakTime","dif","Cue","id","addCue","cue","removeCue","cueLength","clearCues","playbackTime","callbackTime","_prevTime","save","fileName","dataView","saveSound","getBlob","thisBufferSourceNode","target","soundFile","removeEventListener","Amplitude","smoothing","bufferSize","outputChannelCount","processorOptions","normalize","volNorm","stereoVol","stereoVolNorm","parameters","toggleNormalize","smooth","FFT","bins","analyser","createAnalyser","fftSize","configurable","smoothingTimeConstant","freqDomain","Uint8Array","frequencyBinCount","timeDomain","bass","lowMid","mid","highMid","treble","waveform","normalArray","_isSafari","timeToFloat","getFloatTimeDomainData","timeToInt","getByteTimeDomainData","scaled","analyze","freqToFloat","getFloatFrequencyData","freqToInt","getByteFrequencyData","getEnergy","frequency1","frequency2","nyquist","swap","lowIndex","highIndex","numFrequencies","toReturn","freq1","freq2","x","getCentroid","cumulative_sum","centroid_normalization","mean_freq_index","spec_centroid_freq","linAverages","N","spectrum","spectrumLength","spectrumStep","linearAverages","groupIndex","specIndex","logAverages","octaveBands","octaveIndex","specIndexFrequency","hi","getOctaveBands","fCtr0","lastFrequencyBand","lo","ctr","newFrequencyBand","fft","_input","midi","midiToFrequency","pitch","noteNumber","noteToScaleIndex","transpose","harmonize","toMidi","frequencyToMidi","toNote","A4","LN2","scaleIndexToNote","cbb","cb","c#","cx","dbb","d#","dx","ebb","eb","e#","ex","fbb","fb","f#","fx","gbb","gb","g","g#","gx","abb","ab","a#","ax","bbb","bb","b#","bx","_secondsToTicks","l1","t2","l2","t3","l3","aLevel","dLevel","rLevel","_rampHighPercentage","_rampLowPercentage","control","_init","isExponential","sourceToClear","wasTriggered","_setRampAD","_rampAttackTime","checkExpInput","_rampDecayTime","TCDenominator","_rampAttackTC","_rampDecayTC","setRampPercentages","p1","p2","isExp","lastAttack","valToSet","v2","destination1","destination2","AudioIn","Reverb","Noise","Delay","Env","Pulse","w","dcOffset","createDCOffset","dcGain","mW","sig","SignalAdd","mods","currentFreq","freqMod","bufferSource","assignType","_brownNoise","_pinkNoise","_whiteNoise","whiteBuffer","noiseData","random","pinkBuffer","b0","b1","b2","b3","b4","b5","b6","white","brownBuffer","lastOut","noise","inputSources","stream","mediaStream","currentSource","enabled","MediaStreamTrack","mediaDevices","successCallback","audioSource","constraints","audio","echoCancellation","deviceId","createMediaStreamSource","getTracks","track","getSources","onSuccess","onError","resolve","reject","enumerateDevices","devices","device","kind","setSource","active","initialFade","_equalPowerA","EqualPowerGain","_equalPowerB","_invert","Expr","applyBinary","Constructor","_eval","applyUnary","getNumber","literalNumber","_replacements","inputCount","_parseInputs","_nodes","tree","_parseTree","_disposeNodes","_Expressions","signal","glue",",","Abs","mod","modulus","Modulo","Pow","a2g","AudioToGain","binary","unary","!","NOT","inputArray","inputMax","replace","matchSyntax","syn","matchGroup","groupName","parseExpression","parseUnary","operator","parsePrimary","parseArgumentList","parseFunctionCall","GreaterThan","_gtz","_abs","_subtract","_modSignal","_setWaveShaper","_exp","_expScaler","_expFunc","_norm","_eqPower","EQFilter","EQ","_eqsize","factor","bands","_newBand","Panner3D","createPanner","panningModel","distanceModel","xVal","yVal","zVal","positionX","positionY","positionZ","orient","orientX","orientY","orientZ","orientationX","orientationY","orientationZ","setFalloff","maxDistance","rolloffFactor","maxDist","rolloff","Listener3D","listener","xValF","yValF","zValF","xValU","yValU","zValU","orientForward","orientUp","forwardX","forwardY","forwardZ","upX","upY","upZ","_split","_merge","_leftGain","_rightGain","leftDelay","rightDelay","_leftFilter","_rightFilter","_maxDelay","maxValue","feedback","_delayTime","_feedback","_filter","_initConvolverNode","_seconds","_decay","_reverse","_buildImpulse","convolverNode","createConvolver","_teardownConvolverNode","_setBuffer","decayRate","rebuild","impulse","impulseL","impulseR","Convolver","impulses","_loadBuffer","cReverb","chunks","addImpulse","resetImpulse","toggleImpulse","Metro","clock","ontick","syncedParts","prevTick","tatumTime","tickCallback","elapsedTime","thisPart","incrementStep","phrases","thisPhrase","phraseArray","sequence","bNum","metroTicks","looping","setBPM","beatTime","tatums","getBPM","getRate","resetSync","part","pushSync","beatLength","initial","Phrase","phraseStep","Part","steps","bLength","partStep","noLoop","metro","addPhrase","array","removePhrase","getPhrase","replaceSequence","onStep","Score","currentPart","thisScore","nextPart","resetPart","playNextPart","resetParts","scoreStep","aScore","SoundLoop","musicalTimeMode","_interval","_bpm","maxIterations","iterations","_calcFreq","syncedStart","otherLoop","_update","_convertNotation","Number","_measure","timeSig","Compressor","compressor","number","SoundRecorder","_inputChannels","_outputChannels","buffers","leftBuffer","rightBuffer","_callback","record","sFile","writeFile","PeakDetect","_framesPerPeak","framesPerPeak","framesSinceLastPeak","cutoff","cutoffMult","energy","penergy","currentValue","isDetected","f1","f2","_onPeak","update","fftObject","nrg","onPeak","makeDistortionCurve","amount","k","numSamples","deg","Distortion","curveAmount","waveShaperNode","getAmount","getOversample"],"mappings":"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;;AAED;AACA;AACA;AACA,CAAC;AACD;AACA;AACA;;AAEA;AACA;AACA,4CAA4C;;AAE5C;;;;;;;ACnBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK,IAA0C;AAC/C,EAAE,iCAAO,EAAE,oCAAE,OAAO;AAAA;AAAA;AAAA,oGAAC;AACrB,GAAG,MAAM,EAIN;AACH,CAAC;;AAED;;AAEA;AACA;AACA,YAAY,QAAQ;AACpB;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA,YAAY,aAAa;AACzB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,aAAa,aAAa;AAC1B,aAAa;AACb;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,aAAa,aAAa;AAC1B,aAAa,SAAS;AACtB;AACA;;AAEA;AACA;AACA;AACA,IAAI;AACJ;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,GAAG;AACH;AACA;AACA;;AAEA;AACA;AACA,aAAa,4BAA4B;AACzC,YAAY,MAAM;AAClB;AACA;AACA;AACA,kBAAkB,oBAAoB;AACtC;AACA;AACA,GAAG;AACH;AACA,GAAG;AACH;AACA,GAAG;AACH;AACA;AACA;AACA,G;AACA;;AAEA;AACA,YAAY,aAAa;AACzB,YAAY,6BAA6B;AACzC;AACA;AACA;AACA;AACA,YAAY,UAAU;AACtB,aAAa,QAAQ;AACrB;AACA;AACA;;AAEA;AACA;AACA;AACA,GAAG;;AAEH;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,kBAAkB,yBAAyB;AAC3C;AACA;AACA;;AAEA;AACA;AACA;AACA,GAAG;;AAEH;AACA;;AAEA;AACA,CAAC,E;;;;;;AC7LD,IAAMnmB,OAAO,GAAGwB,mBAAO,CAAC,CAAD,CAAvB;;AACA,IAAM4kB,aAAa,GAAG,CACpB5kB,mBAAO,CAAC,EAAD,CAAP,WADoB,EAEpBA,mBAAO,CAAC,EAAD,CAAP,WAFoB,EAGpBA,mBAAO,CAAC,EAAD,CAAP,WAHoB,CAAtB;AAKA,IAAMG,EAAE,GAAG3B,OAAO,CAACZ,YAAnB;;AAEA,SAASinB,uBAAT,GAAmC;AACjC,SAAOC,OAAO,CAACC,GAAR,CAAYH,aAAa,CAAC1S,GAAd,CAAkB,UAAS8S,SAAT,EAAoB;AACvD,QAAM7a,IAAI,GAAG,IAAIC,IAAJ,CAAS,CAAC4a,SAAD,CAAT,EAAsB;AAAE5gB,UAAI,EAAE;AAAR,KAAtB,CAAb;AACA,QAAM6gB,SAAS,GAAGhb,GAAG,CAACM,eAAJ,CAAoBJ,IAApB,CAAlB;AACA,WAAOhK,EAAE,CAAC+kB,YAAH,CAAgBC,SAAhB,CAA0BF,SAA1B,CAAP;AACD,GAJkB,CAAZ,CAAP;AAKD;;AAEDxmB,EAAE,CAACjI,SAAH,CAAa2M,cAAb,CAA4B,MAA5B,EAAoC,YAAW;AAC7C;AACA,MAAI,CAAC,KAAKiiB,OAAN,IAAiB,CAAC/nB,MAAM,CAAC+nB,OAA7B,EAAsC;AACpC,SAAKA,OAAL,GAAe,YAAW,CAAE,CAA5B;AACD,GAJ4C,CAK7C;;;AACA,OAAKC,aAAL;;AACA,MAAMC,oBAAoB,GAAG,YAAW;AACtC,SAAKC,iBAAL;AACD,GAF4B,CAE3Bvb,IAF2B,CAEtB,IAFsB,CAA7B;;AAGA6a,yBAAuB,GAAGW,IAA1B,CAA+BF,oBAA/B;AACD,CAXD,E;;;;;;;AChBA;AAAe,uFAAwB,+EAA+E,kCAAkC,mBAAmB,GAAG,EAAE,OAAO,kCAAkC,kIAAkI,GAAG,EAAE,qBAAqB,EAAE,qDAAqD,0CAA0C,4DAA4D,EAAE,EAAE,+CAA+C,gBAAgB,kBAAkB,OAAO,2BAA2B,wDAAwD,gCAAgC,yDAAyD,2DAA2D,EAAE,EAAE,iEAAiE,sEAAsE,8DAA8D,oBAAoB,EAAE,qDAAqD,8EAA8E,aAAa,EAAE,qCAAqC,EAAE,2CAA2C,uBAAuB,yFAAyF,EAAE,aAAa,EAAE,8CAA8C,iEAAiE,6EAA6E,EAAE,yEAAyE,eAAe,sDAAsD,EAAE,EAAE,uDAAuD,EAAE,sCAAsC,kEAAkE,sDAAsD,+DAA+D,qCAAqC,6EAA6E,EAAE,uCAAuC,iDAAiD,4BAA4B,EAAE,qBAAqB,wEAAwE,EAAE,qDAAqD,eAAe,wEAAwE,EAAE,EAAE,wCAAwC,GAAG,gCAAgC,EAAE,yCAAyC,0EAA0E,0CAA0C,gDAAgD,MAAM,wEAAwE,GAAG,aAAa,EAAE,YAAY,cAAc,EAAE,EAAE,8CAA8C,kCAAkC,gCAAgC,EAAE,OAAO,wDAAwD,gBAAgB,uBAAuB,kDAAkD,kCAAkC,uDAAuD,iBAAiB,GAAG,EAAE,0CAA0C,EAAE,oCAAoC,qEAAqE,EAAE,oCAAoC,4EAA4E,iBAAiB,UAAU,GAAG,8BAA8B,EAAE,iCAAiC,gGAAgG,gDAAgD,GAAG,2BAA2B,EAAE,yHAAyH,8JAA8J,8EAA8E,wDAAwD,2CAA2C,gBAAgB,iDAAiD,gGAAgG,4DAA4D,sEAAsE,8BAA8B,sBAAsB,iDAAiD,8BAA8B,sCAAsC,sCAAsC,SAAS,iCAAiC,uBAAuB,SAAS,QAAQ,qBAAqB,KAAK,wCAAwC,uEAAuE,8BAA8B,sBAAsB,SAAS,yEAAyE,sBAAsB,sBAAsB,SAAS,gCAAgC,gCAAgC,+BAA+B,yBAAyB,aAAa,4CAA4C,gCAAgC,gDAAgD,gDAAgD,mDAAmD,aAAa,WAAW,uDAAuD,iDAAiD,WAAW,SAAS,mDAAmD,oBAAoB,OAAO,KAAK,GAAG,8DAA8D,uBAAuB,+DAA+D,SAAS,gCAAgC,OAAO,KAAK,GAAG,kDAAkD,+BAA+B,wCAAwC,2CAA2C,4CAA4C,+BAA+B,sGAAsG,6BAA6B,qBAAqB,OAAO,KAAK,GAAG,8DAA8D,yBAAyB,0DAA0D,2DAA2D,uBAAuB,OAAO,KAAK,GAAG,+EAA+E,4DAA4D,uBAAuB,uCAAuC,yBAAyB,SAAS,OAAO,wCAAwC,qCAAqC,kCAAkC,SAAS,wBAAwB,OAAO,KAAK,GAAG,oDAAoD,8BAA8B,+BAA+B,iCAAiC,gCAAgC,OAAO,KAAK,GAAG,+BAA+B,GAAG,0CAA0C,2EAA2E,C;;;;;;;ACA1tO;AAAe,uFAAwB,+EAA+E,kCAAkC,mBAAmB,GAAG,EAAE,OAAO,kCAAkC,kIAAkI,GAAG,EAAE,qBAAqB,EAAE,qDAAqD,0CAA0C,4DAA4D,EAAE,EAAE,+CAA+C,gBAAgB,kBAAkB,OAAO,2BAA2B,wDAAwD,gCAAgC,yDAAyD,2DAA2D,EAAE,EAAE,iEAAiE,sEAAsE,8DAA8D,oBAAoB,EAAE,qDAAqD,8EAA8E,aAAa,EAAE,qCAAqC,EAAE,2CAA2C,uBAAuB,yFAAyF,EAAE,aAAa,EAAE,8CAA8C,iEAAiE,6EAA6E,EAAE,yEAAyE,eAAe,sDAAsD,EAAE,EAAE,uDAAuD,EAAE,sCAAsC,kEAAkE,sDAAsD,+DAA+D,qCAAqC,6EAA6E,EAAE,uCAAuC,iDAAiD,4BAA4B,EAAE,qBAAqB,wEAAwE,EAAE,qDAAqD,eAAe,wEAAwE,EAAE,EAAE,wCAAwC,GAAG,gCAAgC,EAAE,yCAAyC,0EAA0E,0CAA0C,gDAAgD,MAAM,wEAAwE,GAAG,aAAa,EAAE,YAAY,cAAc,EAAE,EAAE,8CAA8C,kCAAkC,gCAAgC,EAAE,OAAO,wDAAwD,gBAAgB,uBAAuB,kDAAkD,kCAAkC,uDAAuD,iBAAiB,GAAG,EAAE,0CAA0C,EAAE,oCAAoC,qEAAqE,EAAE,oCAAoC,4EAA4E,iBAAiB,UAAU,GAAG,8BAA8B,EAAE,iCAAiC,gGAAgG,gDAAgD,GAAG,2BAA2B,EAAE,yHAAyH,8JAA8J,+EAA+E,yDAAyD,qCAAqC,gDAAgD,4GAA4G,KAAK,yCAAyC,8DAA8D,8BAA8B,oCAAoC,kEAAkE,+BAA+B,gEAAgE,EAAE,oBAAoB,OAAO,KAAK,GAAG,gCAAgC,GAAG,0CAA0C,6EAA6E,C;;;;;;;ACA72J;AAAe,uFAAwB,+EAA+E,kCAAkC,mBAAmB,GAAG,EAAE,OAAO,kCAAkC,kIAAkI,GAAG,EAAE,qBAAqB,EAAE,qDAAqD,0CAA0C,4DAA4D,EAAE,EAAE,+CAA+C,gBAAgB,kBAAkB,OAAO,2BAA2B,wDAAwD,gCAAgC,yDAAyD,2DAA2D,EAAE,EAAE,iEAAiE,sEAAsE,8DAA8D,oBAAoB,EAAE,qDAAqD,8EAA8E,aAAa,EAAE,qCAAqC,EAAE,2CAA2C,uBAAuB,yFAAyF,EAAE,aAAa,EAAE,8CAA8C,iEAAiE,6EAA6E,EAAE,yEAAyE,eAAe,sDAAsD,EAAE,EAAE,uDAAuD,EAAE,sCAAsC,kEAAkE,sDAAsD,+DAA+D,qCAAqC,6EAA6E,EAAE,uCAAuC,iDAAiD,4BAA4B,EAAE,qBAAqB,wEAAwE,EAAE,qDAAqD,eAAe,wEAAwE,EAAE,EAAE,wCAAwC,GAAG,gCAAgC,EAAE,yCAAyC,0EAA0E,0CAA0C,gDAAgD,MAAM,wEAAwE,GAAG,aAAa,EAAE,YAAY,cAAc,EAAE,EAAE,8CAA8C,kCAAkC,gCAAgC,EAAE,OAAO,wDAAwD,gBAAgB,uBAAuB,kDAAkD,kCAAkC,uDAAuD,iBAAiB,GAAG,EAAE,0CAA0C,EAAE,oCAAoC,qEAAqE,EAAE,oCAAoC,4EAA4E,iBAAiB,UAAU,GAAG,8BAA8B,EAAE,iCAAiC,gGAAgG,gDAAgD,GAAG,2BAA2B,EAAE,yHAAyH,8JAA8J,+EAA+E,yDAAyD,4CAA4C,gBAAgB,kDAAkD,iGAAiG,4DAA4D,wDAAwD,4DAA4D,+BAA+B,mCAAmC,2BAA2B,iDAAiD,8BAA8B,gDAAgD,2CAA2C,SAAS,sCAAsC,qEAAqE,SAAS,QAAQ,qBAAqB,KAAK,wGAAwG,uEAAuE,8BAA8B,gCAAgC,uCAAuC,+BAA+B,wBAAwB,aAAa,2CAA2C,6CAA6C,sBAAsB,2BAA2B,eAAe,OAAO,mCAAmC,mCAAmC,6GAA6G,aAAa,OAAO,2BAA2B,aAAa,WAAW,gGAAgG,uFAAuF,uEAAuE,SAAS,0GAA0G,6BAA6B,+BAA+B,WAAW,oGAAoG,0CAA0C,SAAS,yFAAyF,2FAA2F,+BAA+B,wKAAwK,EAAE,gEAAgE,0BAA0B,cAAc,gDAAgD,SAAS,sBAAsB,OAAO,KAAK,GAAG,gCAAgC,GAAG,0CAA0C,6EAA6E,C;;;;;;;ACAh+N,kCAAa;;;;AAEb1vB,mCAAO,UAAUoK,OAAV,EAAmB;AAExB,MAAIxB,OAAO,GAAGwB,mBAAO,CAAC,CAAD,CAArB;;AACA,MAAIG,EAAE,GAAG3B,OAAO,CAACZ,YAAjB,CAHwB,CAKxB;AACA;;AACA,MAAG,OAAOuC,EAAE,CAACslB,kBAAV,KAAiC,WAApC,EAAiD;AAC/ChnB,MAAE,CAAC2b,MAAH,GAAY,UAAUlkB,KAAV,EAAiBI,MAAjB,EAAyB;AACnC,WAAKovB,YAAL,GAAoB,KAAKxvB,KAAL,GAAaiK,EAAE,CAACslB,kBAAH,EAAjC;AACAvvB,WAAK,CAACuD,OAAN,CAAc,KAAKisB,YAAnB;AACA,WAAKA,YAAL,CAAkBjsB,OAAlB,CAA0BnD,MAA1B;AACD,KAJD;;AAMAmI,MAAE,CAAC2b,MAAH,CAAU5jB,SAAV,CAAoBukB,GAApB,GAA0B,UAASjgB,GAAT,EAAc+D,QAAd,EAAwB;AAChD,UAAIwI,IAAI,GAAGxI,QAAQ,IAAI,CAAvB;AACA,UAAIgR,CAAC,GAAG1P,EAAE,CAACrB,WAAH,GAAiBuI,IAAzB;AAEA,WAAKqe,YAAL,CAAkB3K,GAAlB,CAAsB9b,uBAAtB,CAA8CnE,GAA9C,EAAmD+U,CAAnD;AACD,KALD,CAP+C,CAc/C;AACA;AACA;AACA;;;AACApR,MAAE,CAAC2b,MAAH,CAAU5jB,SAAV,CAAoBmvB,aAApB,GAAoC,YAAW,CAAE,CAAjD;;AAEAlnB,MAAE,CAAC2b,MAAH,CAAU5jB,SAAV,CAAoBiD,OAApB,GAA8B,UAASmsB,GAAT,EAAc;AAC1C,WAAKF,YAAL,CAAkBjsB,OAAlB,CAA0BmsB,GAA1B;AACD,KAFD;;AAIAnnB,MAAE,CAAC2b,MAAH,CAAU5jB,SAAV,CAAoBgD,UAApB,GAAiC,YAAW;AAC1C,UAAI,KAAKksB,YAAT,EAAuB;AACrB,aAAKA,YAAL,CAAkBlsB,UAAlB;AACD;AACF,KAJD;AAMD,GA9BD,MA8BO;AACL;AACA;AACA;AACAiF,MAAE,CAAC2b,MAAH,GAAY,UAASlkB,KAAT,EAAgBI,MAAhB,EAAwBuvB,gBAAxB,EAA0C;AACpD,WAAK3vB,KAAL,GAAaiK,EAAE,CAAC/J,UAAH,EAAb;AACAF,WAAK,CAACuD,OAAN,CAAc,KAAKvD,KAAnB;AAEA,WAAK4vB,IAAL,GAAY3lB,EAAE,CAAC/J,UAAH,EAAZ;AACA,WAAK2vB,KAAL,GAAa5lB,EAAE,CAAC/J,UAAH,EAAb;AACA,WAAK0vB,IAAL,CAAUE,qBAAV,GAAkC,UAAlC;AACA,WAAKD,KAAL,CAAWC,qBAAX,GAAmC,UAAnC,CAPoD,CASpD;;AACA,UAAIH,gBAAgB,GAAG,CAAvB,EAA0B;AACxB,aAAKI,QAAL,GAAgB9lB,EAAE,CAAC+lB,qBAAH,CAAyB,CAAzB,CAAhB;AACA,aAAKhwB,KAAL,CAAWuD,OAAX,CAAmB,KAAKwsB,QAAxB;AAEA,aAAKA,QAAL,CAAcxsB,OAAd,CAAsB,KAAKqsB,IAA3B,EAAiC,CAAjC;AACA,aAAKG,QAAL,CAAcxsB,OAAd,CAAsB,KAAKssB,KAA3B,EAAkC,CAAlC;AACD,OAND,MAOK;AACH,aAAK7vB,KAAL,CAAWuD,OAAX,CAAmB,KAAKqsB,IAAxB;AACA,aAAK5vB,KAAL,CAAWuD,OAAX,CAAmB,KAAKssB,KAAxB;AACD;;AAED,WAAKzvB,MAAL,GAAc6J,EAAE,CAACgmB,mBAAH,CAAuB,CAAvB,CAAd;AACA,WAAKL,IAAL,CAAUrsB,OAAV,CAAkB,KAAKnD,MAAvB,EAA+B,CAA/B,EAAkC,CAAlC;AACA,WAAKyvB,KAAL,CAAWtsB,OAAX,CAAmB,KAAKnD,MAAxB,EAAgC,CAAhC,EAAmC,CAAnC;AACA,WAAKA,MAAL,CAAYmD,OAAZ,CAAoBnD,MAApB;AACD,KA1BD,CAJK,CAgCL;;;AACAmI,MAAE,CAAC2b,MAAH,CAAU5jB,SAAV,CAAoBukB,GAApB,GAA0B,UAASjgB,GAAT,EAAc+D,QAAd,EAAwB;AAChD,UAAIwI,IAAI,GAAGxI,QAAQ,IAAI,CAAvB;AACA,UAAIgR,CAAC,GAAG1P,EAAE,CAACrB,WAAH,GAAiBuI,IAAzB;AACA,UAAI+e,CAAC,GAAG,CAACtrB,GAAG,GAAG,CAAP,IAAY,CAApB;AACA,UAAIurB,QAAQ,GAAGtqB,IAAI,CAACuqB,GAAL,CAASF,CAAC,GAACrqB,IAAI,CAACC,EAAP,GAAU,CAAnB,CAAf;AACA,UAAIuqB,OAAO,GAAGxqB,IAAI,CAACE,GAAL,CAASmqB,CAAC,GAAGrqB,IAAI,CAACC,EAAT,GAAY,CAArB,CAAd;AACA,WAAK8pB,IAAL,CAAUxpB,IAAV,CAAe2C,uBAAf,CAAuCsnB,OAAvC,EAAgD1W,CAAhD;AACA,WAAKkW,KAAL,CAAWzpB,IAAX,CAAgB2C,uBAAhB,CAAwConB,QAAxC,EAAkDxW,CAAlD;AACD,KARD;;AAUApR,MAAE,CAAC2b,MAAH,CAAU5jB,SAAV,CAAoBmvB,aAApB,GAAoC,UAASa,WAAT,EAAsB;AACxD,UAAIA,WAAW,KAAK,CAApB,EAAuB;AACrB,aAAKtwB,KAAL,CAAWsD,UAAX;AACA,aAAKtD,KAAL,CAAWuD,OAAX,CAAmB,KAAKqsB,IAAxB;AACA,aAAK5vB,KAAL,CAAWuD,OAAX,CAAmB,KAAKssB,KAAxB;AACD,OAJD,MAIO,IAAIS,WAAW,KAAK,CAApB,EAAuB;AAC5B,oBAAW,KAAKP,QAAL,KAAkB,WAA7B,GAA2C;AACzC,eAAKA,QAAL,GAAgB9lB,EAAE,CAAC+lB,qBAAH,CAAyB,CAAzB,CAAhB;AACD;;AACD,aAAKhwB,KAAL,CAAWsD,UAAX;AACA,aAAKtD,KAAL,CAAWuD,OAAX,CAAmB,KAAKwsB,QAAxB;AACA,aAAKA,QAAL,CAAcxsB,OAAd,CAAsB,KAAKqsB,IAA3B,EAAiC,CAAjC;AACA,aAAKG,QAAL,CAAcxsB,OAAd,CAAsB,KAAKssB,KAA3B,EAAkC,CAAlC;AACD;AACF,KAdD;;AAgBAtnB,MAAE,CAAC2b,MAAH,CAAU5jB,SAAV,CAAoBiD,OAApB,GAA8B,UAASmsB,GAAT,EAAc;AAC1C,WAAKtvB,MAAL,CAAYmD,OAAZ,CAAoBmsB,GAApB;AACD,KAFD;;AAIAnnB,MAAE,CAAC2b,MAAH,CAAU5jB,SAAV,CAAoBgD,UAApB,GAAiC,YAAW;AAC1C,UAAI,KAAKlD,MAAT,EAAiB;AACf,aAAKA,MAAL,CAAYkD,UAAZ;AACD;AACF,KAJD;AAKD;AACF,CA1GK;AAAA,oGAAN,C;;;;;;;ACFA,kCAAa;;;;AAEb5D,mCAAO,UAAUoK,OAAV,EAAmB;AAExB,MAAIiI,WAAW,GAAGjI,mBAAO,CAAC,EAAD,CAAzB;;AACA,MAAIxB,OAAO,GAAGwB,mBAAO,CAAC,CAAD,CAArB;;AACA,MAAIG,EAAE,GAAG3B,OAAO,CAACZ,YAAjB;;AACA,MAAIsE,UAAU,GAAGlC,mBAAO,CAAC,CAAD,CAAP,CAAmBkC,UAApC;;AACA,MAAIoC,YAAY,GAAGtE,mBAAO,CAAC,CAAD,CAAP,CAAmBsE,YAAtC;;AACA,MAAImiB,cAAc,GAAGzmB,mBAAO,CAAC,EAAD,CAA5B;AAEA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAkDAvB,IAAE,CAACioB,SAAH,GAAe,UAASrjB,KAAT,EAAgBsjB,MAAhB,EAAwBC,OAAxB,EAAiCC,YAAjC,EAA+C;AAC5D,QAAI,OAAOxjB,KAAP,KAAiB,WAArB,EAAkC;AAChC,UAAI,OAAOA,KAAP,KAAiB,QAAjB,IAA6B,OAAOA,KAAK,CAAC,CAAD,CAAZ,KAAoB,QAArD,EAA+D;AAC7D,YAAIC,IAAI,GAAG7E,EAAE,CAACjI,SAAH,CAAa4M,iBAAb,CAA+BC,KAA/B,CAAX;;AACA,aAAKyjB,GAAL,GAAWxjB,IAAX;AACD,OAHD,MAIK,IAAG,QAAOD,KAAP,MAAiB,QAApB,EAA8B;AACjC,YAAI,EAAEhG,MAAM,CAAC0pB,IAAP,IAAe1pB,MAAM,CAAC2pB,UAAtB,IAAoC3pB,MAAM,CAAC4pB,QAA3C,IAAuD5pB,MAAM,CAAC+M,IAAhE,CAAJ,EAA2E;AACzE;AACA,gBAAM,2DAAN;AACD;AACF,OAV+B,CAYhC;;;AACA,UAAI/G,KAAK,CAAC6jB,IAAV,EAAgB;AACd7jB,aAAK,GAAGA,KAAK,CAAC6jB,IAAd;AACD;;AAED,WAAKA,IAAL,GAAY7jB,KAAZ;AACD,KAnB2D,CAqB5D;;;AACA,SAAK8jB,QAAL,GAAgB,YAAW,CAAE,CAA7B;;AAEA,SAAKC,QAAL,GAAgB,KAAhB;AACA,SAAKC,QAAL,GAAgB,KAAhB;AACA,SAAKC,OAAL,GAAe,KAAf;AACA,SAAKC,UAAL,GAAkB,CAAlB,CA3B4D,CA6B5D;;AACA,SAAKC,KAAL,GAAa,EAAb;AACA,SAAKC,aAAL,GAAqB,CAArB,CA/B4D,CAiC5D;;AACA,SAAKC,QAAL,GAAgB,CAAhB;AACA,SAAKC,YAAL,GAAoB,IAApB;AACA,SAAKC,YAAL,GAAoB,IAApB,CApC4D,CAsC5D;;AACA,SAAKC,iBAAL,GAAyB,EAAzB,CAvC4D,CAyC5D;;AACA,SAAKC,gBAAL,GAAwB,IAAxB;AAEA,SAAKhjB,MAAL,GAAc,IAAd;AACA,SAAKqe,YAAL,GAAoB,CAApB;AAEA,SAAKjtB,KAAL,GAAasI,OAAO,CAACZ,YAAR,CAAqBxH,UAArB,EAAb;AACA,SAAKE,MAAL,GAAckI,OAAO,CAACZ,YAAR,CAAqBxH,UAArB,EAAd;AAEA,SAAK2xB,QAAL,GAAgB,KAAhB,CAlD4D,CAoD5D;;AACA,SAAKra,SAAL,GAAiB,CAAjB;AACA,SAAKE,OAAL,GAAe,IAAf;AACA,SAAKoa,SAAL,GAAiB,CAAjB,CAvD4D,CAyD5D;;AACA,SAAKC,IAAL,GAAY,SAAZ,CA1D4D,CA4D5D;;AACA,SAAKC,WAAL,GAAmB,IAAnB,CA7D4D,CA+D5D;;AACA,SAAKjO,WAAL,GAAmB,GAAnB;AACA,SAAKE,MAAL,GAAc,IAAI1b,EAAE,CAAC2b,MAAP,CAAc,KAAK9jB,MAAnB,EAA2BkI,OAAO,CAACtI,KAAnC,EAA0C,CAA1C,CAAd,CAjE4D,CAmE5D;;AACA,QAAI,KAAK4wB,GAAL,IAAY,KAAKI,IAArB,EAA2B;AACzB,WAAKiB,IAAL,CAAUxB,MAAV,EAAkBC,OAAlB;AACD,KAtE2D,CAwE5D;;;AACApoB,WAAO,CAACH,UAAR,CAAmBvF,IAAnB,CAAwB,IAAxB;;AAEA,QAAI,OAAO+tB,YAAP,KAAwB,UAA5B,EAAwC;AACtC,WAAKuB,aAAL,GAAqBvB,YAArB;AACD,KAFD,MAEO;AACL,WAAKuB,aAAL,GAAqB,YAAW,CAAE,CAAlC;AACD;;AAED,SAAKC,WAAL,GAAmBA,WAAW,CAACre,IAAZ,CAAiB,IAAjB,CAAnB;AACD,GAlFD,CA3DwB,CA+IxB;;;AACAvL,IAAE,CAACjI,SAAH,CAAa8xB,qBAAb,CAAmC,WAAnC,EAAgD7pB,EAAE,CAACjI,SAAnD;AAEA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAmCAiI,IAAE,CAACjI,SAAH,CAAa+xB,SAAb,GAAyB,UAASjlB,IAAT,EAAeyO,QAAf,EAAyB6U,OAAzB,EAAkCC,YAAlC,EAAgD;AACvE;AACA,QAAIxpB,MAAM,CAACmrB,QAAP,CAAgBC,MAAhB,CAAuBtxB,OAAvB,CAA+B,SAA/B,IAA4C,CAAC,CAA7C,IAAkDkG,MAAM,CAACqrB,OAAP,KAAmB,WAAzE,EAAuF;AACrFrrB,YAAM,CAACsrB,KAAP,CAAa,2FAAb;AACD;;AAED,QAAInO,IAAI,GAAG,IAAX;AACA,QAAIlE,CAAC,GAAG,IAAI7X,EAAE,CAACioB,SAAP,CAAiBpjB,IAAjB,EAAuB,YAAW;AACxC,UAAG,OAAOyO,QAAP,KAAoB,UAAvB,EAAmC;AACjCA,gBAAQ,CAAC/X,KAAT,CAAewgB,IAAf,EAAqBvgB,SAArB;AACD;;AAED,UAAI,OAAOugB,IAAI,CAAC+K,iBAAZ,KAAkC,UAAtC,EAAkD;AAChD/K,YAAI,CAAC+K,iBAAL;AACD;AACF,KARO,EAQLqB,OARK,EAQIC,YARJ,CAAR;AAUA,WAAOvQ,CAAP;AACD,GAlBD;AAoBA;;;;;;;;;;;;AAUA7X,IAAE,CAACioB,SAAH,CAAalwB,SAAb,CAAuB2xB,IAAvB,GAA8B,UAASpW,QAAT,EAAmB6W,aAAnB,EAAkC;AAC9D,QAAIpO,IAAI,GAAG,IAAX;AACA,QAAIrS,UAAU,GAAG,IAAIG,KAAJ,GAAYI,KAA7B;;AAEA,QAAI,KAAKoe,GAAL,KAAajmB,SAAb,IAA0B,KAAKimB,GAAL,KAAa,EAA3C,EAA+C;AAC7C,UAAI+B,OAAO,GAAG,IAAIC,cAAJ,EAAd;AACAD,aAAO,CAACne,gBAAR,CAAyB,UAAzB,EAAqC,UAASqe,GAAT,EAAc;AACjDvO,YAAI,CAACwO,eAAL,CAAqBD,GAArB;AACD,OAFD,EAEG,KAFH;AAGAF,aAAO,CAACI,IAAR,CAAa,KAAb,EAAoB,KAAKnC,GAAzB,EAA8B,IAA9B;AACA+B,aAAO,CAACK,YAAR,GAAuB,aAAvB;;AAEAL,aAAO,CAAClC,MAAR,GAAiB,YAAW;AAC1B,YAAIkC,OAAO,CAACM,MAAR,KAAmB,GAAvB,EAA4B;AAC1B;AACA,cAAI,CAAC3O,IAAI,CAACL,MAAV,EAAkB;AAClBha,YAAE,CAACipB,eAAH,CAAmBP,OAAO,CAACQ,QAA3B,EACE;AACA,oBAASC,IAAT,EAAe;AACb,gBAAI,CAAC9O,IAAI,CAACL,MAAV,EAAkB;AAClBK,gBAAI,CAAC1V,MAAL,GAAcwkB,IAAd;AACA9O,gBAAI,CAACL,MAAL,CAAYwL,aAAZ,CAA0B2D,IAAI,CAAC3kB,gBAA/B;;AACA,gBAAIoN,QAAJ,EAAc;AACZA,sBAAQ,CAACyI,IAAD,CAAR;AACD;AACF,WATH,EAUE;AACA,sBAAW;AACT,gBAAI,CAACA,IAAI,CAACL,MAAV,EAAkB;AAClB,gBAAI9R,GAAG,GAAG,IAAIJ,WAAJ,CAAgB,iBAAhB,EAAmCE,UAAnC,EAA+CqS,IAAI,CAACsM,GAApD,CAAV;AACA,gBAAIyC,GAAG,GAAG,+CAA+C/O,IAAI,CAACsM,GAA9D;;AACA,gBAAI8B,aAAJ,EAAmB;AACjBvgB,iBAAG,CAACkhB,GAAJ,GAAUA,GAAV;AACAX,2BAAa,CAACvgB,GAAD,CAAb;AACD,aAHD,MAGO;AACL1K,qBAAO,CAAC6rB,KAAR,CAAcD,GAAG,GAAE,uCAAL,GAA+ClhB,GAAG,CAACK,KAAjE;AACD;AACF,WArBH;AAuBD,SA1BD,CA2BA;AA3BA,aA4BK;AACH,gBAAI,CAAC8R,IAAI,CAACL,MAAV,EAAkB;AAClB,gBAAI9R,GAAG,GAAG,IAAIJ,WAAJ,CAAgB,WAAhB,EAA6BE,UAA7B,EAAyCqS,IAAI,CAACsM,GAA9C,CAAV;AACA,gBAAIyC,GAAG,GAAG,oBAAoB/O,IAAI,CAACsM,GAAzB,GAA+B,4BAA/B,GACR+B,OAAO,CAACM,MADA,GACS,IADT,GACgBN,OAAO,CAACY,UADxB,GACqC,GAD/C;;AAGA,gBAAIb,aAAJ,EAAmB;AACjBvgB,iBAAG,CAACqhB,OAAJ,GAAcH,GAAd;AACAX,2BAAa,CAACvgB,GAAD,CAAb;AACD,aAHD,MAGO;AACL1K,qBAAO,CAAC6rB,KAAR,CAAcD,GAAG,GAAE,uCAAL,GAA+ClhB,GAAG,CAACK,KAAjE;AACD;AACF;AACF,OA1CD,CAR6C,CAoD7C;;;AACAmgB,aAAO,CAACjC,OAAR,GAAkB,YAAW;AAC3B,YAAIve,GAAG,GAAG,IAAIJ,WAAJ,CAAgB,WAAhB,EAA6BE,UAA7B,EAAyCqS,IAAI,CAACsM,GAA9C,CAAV;AACA,YAAIyC,GAAG,GAAG,8CAA8C/O,IAAI,CAACsM,GAAnD,GAAyD,4CAAnE;;AAEA,YAAI8B,aAAJ,EAAmB;AACjBvgB,aAAG,CAACqhB,OAAJ,GAAcH,GAAd;AACAX,uBAAa,CAACvgB,GAAD,CAAb;AACD,SAHD,MAGO;AACL1K,iBAAO,CAAC6rB,KAAR,CAAcD,GAAG,GAAE,uCAAL,GAA+ClhB,GAAG,CAACK,KAAjE;AACD;AACF,OAVD;;AAYAmgB,aAAO,CAACc,IAAR;AACD,KAlED,MAmEK,IAAI,KAAKzC,IAAL,KAAcrmB,SAAlB,EAA6B;AAChC,UAAI+oB,MAAM,GAAG,IAAI5C,UAAJ,EAAb;;AACA4C,YAAM,CAACjD,MAAP,GAAgB,YAAW;AACzB,YAAI,CAACnM,IAAI,CAACL,MAAV,EAAkB;AAClBha,UAAE,CAACipB,eAAH,CAAmBQ,MAAM,CAACpkB,MAA1B,EAAkC,UAAS8jB,IAAT,EAAe;AAC/C,cAAI,CAAC9O,IAAI,CAACL,MAAV,EAAkB;AAClBK,cAAI,CAAC1V,MAAL,GAAcwkB,IAAd;AACA9O,cAAI,CAACL,MAAL,CAAYwL,aAAZ,CAA0B2D,IAAI,CAAC3kB,gBAA/B;;AACA,cAAIoN,QAAJ,EAAc;AACZA,oBAAQ,CAACyI,IAAD,CAAR;AACD;AACF,SAPD;AAQD,OAVD;;AAWAoP,YAAM,CAAChD,OAAP,GAAiB,UAAS3d,CAAT,EAAY;AAC3B,YAAI,CAACuR,IAAI,CAACL,MAAV,EAAkB;;AAClB,YAAIyM,OAAJ,EAAa;AACXA,iBAAO,CAAC3d,CAAD,CAAP;AACD;AACF,OALD;;AAMA2gB,YAAM,CAACC,iBAAP,CAAyB,KAAK3C,IAA9B;AACD;AACF,GA5FD,CAnNwB,CAiTxB;;;AACAzoB,IAAE,CAACioB,SAAH,CAAalwB,SAAb,CAAuBwyB,eAAvB,GAAyC,UAASD,GAAT,EAAc;AACrD,QAAIA,GAAG,CAACe,gBAAR,EAA0B;AACxB,UAAIC,eAAe,GAAGhB,GAAG,CAACiB,MAAJ,GAAajB,GAAG,CAACxS,KAAjB,GAAyB,IAA/C;;AACA,WAAK6R,aAAL,CAAmB2B,eAAnB,EAAoChB,GAApC,EAFwB,CAGxB;;AACD,KAJD,MAIO;AACL;AACA,WAAKX,aAAL,CAAmB,cAAnB;AACD;AACF,GATD;AAWA;;;;;;;;;AAOA3pB,IAAE,CAACioB,SAAH,CAAalwB,SAAb,CAAuByzB,QAAvB,GAAkC,YAAW;AAC3C,QAAI,KAAKnlB,MAAT,EAAiB;AACf,aAAO,IAAP;AACD,KAFD,MAEO;AACL,aAAO,KAAP;AACD;AACF,GAND;AAQA;;;;;;;;;;;;;;AAYArG,IAAE,CAACioB,SAAH,CAAalwB,SAAb,CAAuB8oB,IAAvB,GAA8B,UAAS5R,SAAT,EAAoBwc,IAApB,EAA0B1pB,GAA1B,EAA+B2pB,SAA/B,EAA0C7b,QAA1C,EAAoD;AAChF,QAAI,CAAC,KAAKhY,MAAV,EAAkB;AAChBqH,aAAO,CAACkO,IAAR,CAAa,uCAAb;AACA;AACD;;AAED,QAAIlP,GAAG,GAAG6B,OAAO,CAACZ,YAAR,CAAqBkB,WAA/B;AACA,QAAIsrB,QAAJ,EAAcC,MAAd;AACA,QAAIhjB,IAAI,GAAGqG,SAAS,IAAI,CAAxB;;AACA,QAAIrG,IAAI,GAAG,CAAX,EAAc;AACZA,UAAI,GAAG,CAAP;AACD;;AAEDA,QAAI,GAAGA,IAAI,GAAG1K,GAAd;;AAEA,QAAI,OAAOutB,IAAP,KAAgB,WAApB,EAAiC;AAC/B,WAAKA,IAAL,CAAUA,IAAV;AACD;;AAED,QAAI,OAAO1pB,GAAP,KAAe,WAAnB,EAAgC;AAC9B,WAAK8pB,SAAL,CAAe9pB,GAAf;AACD,KArB+E,CAuBhF;;;AACA,QAAI,KAAKsE,MAAT,EAAiB;AACf;AACA,WAAKyiB,UAAL,GAAkB,CAAlB,CAFe,CAIf;;AACA,UAAI,KAAKU,IAAL,KAAc,SAAd,IAA2B,KAAKnjB,MAAhC,IAA0C,KAAKgjB,gBAAnD,EAAqE;AACnE,aAAKA,gBAAL,CAAsBzN,IAAtB,CAA2BhT,IAA3B;;AACA,aAAKsgB,YAAL,CAAkBtN,IAAlB,CAAuBhT,IAAvB;AACD,OARc,CAUf;;;AACA,UAAI,KAAK4gB,IAAL,KAAc,WAAd,IAA6B,KAAKsC,SAAL,EAAjC,EAAmD;AACjD;AACD,OAbc,CAcf;;;AACA,WAAKzC,gBAAL,GAAwB,KAAK0C,eAAL,EAAxB,CAfe,CAiBf;;AACA,aAAO,KAAK7C,YAAZ;AACA,WAAKA,YAAL,GAAoB,KAAK8C,gBAAL,EAApB;;AAEA,UAAIN,SAAJ,EAAe;AACb,YAAIA,SAAS,IAAG,CAAZ,IAAiBA,SAAS,GAAG,KAAKrlB,MAAL,CAAYwJ,QAA7C,EAAuD;AACrD;AACA8b,kBAAQ,GAAGD,SAAX;AACD,SAHD,MAGO;AAAE,gBAAM,yBAAN;AAAkC;AAC5C,OALD,MAKO;AACLC,gBAAQ,GAAG,CAAX;AACD;;AAED,UAAI9b,QAAJ,EAAc;AACZ;AACAA,gBAAQ,GAAGA,QAAQ,IAAI,KAAKxJ,MAAL,CAAYwJ,QAAZ,GAAuB8b,QAAnC,GAA8C9b,QAA9C,GAAyD,KAAKxJ,MAAL,CAAYwJ,QAAhF;AACD,OAjCc,CAmCf;;;AACA,UAAI,KAAKgZ,OAAT,EAAkB;AAChB,aAAKQ,gBAAL,CAAsBzc,KAAtB,CAA4BhE,IAA5B,EAAkC,KAAK2gB,SAAvC,EAAkD1Z,QAAlD;;AACA,aAAKqZ,YAAL,CAAkBtc,KAAlB,CAAwBhE,IAAxB,EAA8B,KAAK2gB,SAAnC,EAA8C1Z,QAA9C;AACD,OAHD,MAGO;AACL,aAAKwZ,gBAAL,CAAsBzc,KAAtB,CAA4BhE,IAA5B,EAAkC+iB,QAAlC,EAA4C9b,QAA5C;;AACA,aAAKqZ,YAAL,CAAkBtc,KAAlB,CAAwBhE,IAAxB,EAA8B+iB,QAA9B,EAAwC9b,QAAxC;AACD;;AAED,WAAK+Y,QAAL,GAAgB,IAAhB;AACA,WAAKC,OAAL,GAAe,KAAf,CA7Ce,CA+Cf;;AACA,WAAKO,iBAAL,CAAuB/uB,IAAvB,CAA4B,KAAKgvB,gBAAjC;AACA,WAAKA,gBAAL,CAAsB4C,WAAtB,GAAoC,KAAK7C,iBAAL,CAAuBtwB,MAAvB,GAAgC,CAApE;AAEA,WAAKuwB,gBAAL,CAAsBpd,gBAAtB,CAAuC,OAAvC,EAAgD,KAAK2d,WAArD;AACD,KApDD,CAqDA;AArDA,SAsDK;AACH,cAAM,+DAAN;AACD,OAhF+E,CAkFhF;;;AACA,SAAKP,gBAAL,CAAsB1c,IAAtB,GAA6B,KAAKgc,QAAlC;AACA,SAAKO,YAAL,CAAkBvc,IAAlB,GAAyB,KAAKgc,QAA9B;;AAEA,QAAI,KAAKA,QAAL,KAAkB,IAAtB,EAA4B;AAC1BiD,YAAM,GAAG/b,QAAQ,GAAGA,QAAH,GAAc8b,QAAQ,GAAG,iBAA1C;AACA,WAAKtC,gBAAL,CAAsB6C,SAAtB,GAAkCP,QAAlC;AACA,WAAKtC,gBAAL,CAAsB8C,OAAtB,GAAgCP,MAAhC;AACA,WAAK1C,YAAL,CAAkBgD,SAAlB,GAA8BP,QAA9B;AACA,WAAKzC,YAAL,CAAkBiD,OAAlB,GAA4BP,MAA5B;AACD;AAEF,GA9FD;AAiGA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA6BA5rB,IAAE,CAACioB,SAAH,CAAalwB,SAAb,CAAuBq0B,QAAvB,GAAkC,UAASC,GAAT,EAAc;AAC9C,QAAIxU,CAAC,GAAGwU,GAAG,CAAC7nB,WAAJ,EAAR,CAD8C,CAG9C;;AACA,QAAIqT,CAAC,KAAK,SAAN,IAAmB,KAAKxR,MAAxB,IAAkC,KAAKgjB,gBAA3C,EAA6D;AAC3D,WAAK,IAAIxwB,CAAC,GAAG,CAAb,EAAgBA,CAAC,GAAG,KAAKuwB,iBAAL,CAAuBtwB,MAAvB,GAAgC,CAApD,EAAuDD,CAAC,EAAxD,EAA4D;AAC1D,YAAIqF,GAAG,GAAG6B,OAAO,CAACZ,YAAR,CAAqBkB,WAA/B;AACA,aAAK+oB,iBAAL,CAAuBvwB,CAAvB,EAA0B+iB,IAA1B,CAA+B1d,GAA/B;AACD;AACF,KAT6C,CAW9C;;;AACA,QAAI2Z,CAAC,KAAK,SAAN,IAAmBA,CAAC,KAAK,SAAzB,IAAsCA,CAAC,KAAK,WAAhD,EAA6D;AAC3D,WAAK2R,IAAL,GAAY3R,CAAZ;AACD,KAFD,MAEO;AACL,YAAM,0DAAN;AACD;AACF,GAjBD;AAmBA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA0CA7X,IAAE,CAACioB,SAAH,CAAalwB,SAAb,CAAuB+nB,KAAvB,GAA+B,UAAS7Q,SAAT,EAAoB;AACjD,QAAI/Q,GAAG,GAAG6B,OAAO,CAACZ,YAAR,CAAqBkB,WAA/B;AACA,QAAIuI,IAAI,GAAGqG,SAAS,IAAI,CAAxB;AACA,QAAIqd,KAAK,GAAG1jB,IAAI,GAAG1K,GAAnB;;AAEA,QAAI,KAAK4tB,SAAL,MAAoB,KAAKzlB,MAAzB,IAAmC,KAAKgjB,gBAA5C,EAA8D;AAC5D,WAAKR,OAAL,GAAe,IAAf;AACA,WAAKD,QAAL,GAAgB,KAAhB;AAEA,WAAKW,SAAL,GAAiB,KAAKlpB,WAAL,EAAjB;AACA,WAAKgpB,gBAAL,CAAsBzN,IAAtB,CAA2B0Q,KAA3B;;AACA,WAAKpD,YAAL,CAAkBtN,IAAlB,CAAuB0Q,KAAvB;;AAEA,WAAKxD,UAAL,GAAkB,KAAKzoB,WAAL,EAAlB,CAR4D,CAS5D;AACD,KAVD,MAUO;AACL,WAAKyoB,UAAL,GAAkB,CAAlB;AACD;AACF,GAlBD;AAoBA;;;;;;;;;;;;;;;AAaA9oB,IAAE,CAACioB,SAAH,CAAalwB,SAAb,CAAuB4U,IAAvB,GAA8B,UAASsC,SAAT,EAAoBwc,IAApB,EAA0B1pB,GAA1B,EAA+BmqB,SAA/B,EAA0Crc,QAA1C,EAAoD;AAChF,SAAK8Y,QAAL,GAAgB,IAAhB;AACA,SAAK9H,IAAL,CAAU5R,SAAV,EAAqBwc,IAArB,EAA2B1pB,GAA3B,EAAgCmqB,SAAhC,EAA2Crc,QAA3C;AACD,GAHD;AAKA;;;;;;;;;;;AASA7P,IAAE,CAACioB,SAAH,CAAalwB,SAAb,CAAuBw0B,OAAvB,GAAiC,UAASC,IAAT,EAAe;AAC9C,QAAIA,IAAI,KAAK,IAAb,EAAmB;AACjB,WAAK7D,QAAL,GAAgB,IAAhB;AACD,KAFD,MAGK,IAAI6D,IAAI,KAAK,KAAb,EAAoB;AACvB,WAAK7D,QAAL,GAAgB,KAAhB;AACD,KAFI,MAGA;AACH,YAAM,6CAAN;AACD;;AACD,QAAI,KAAKU,gBAAT,EAA2B;AACzB,WAAKA,gBAAL,CAAsB1c,IAAtB,GAA6B,KAAKgc,QAAlC;AACA,WAAKO,YAAL,CAAkBvc,IAAlB,GAAyB,KAAKgc,QAA9B;AACD;AACF,GAdD;AAgBA;;;;;;;;;AAOA3oB,IAAE,CAACioB,SAAH,CAAalwB,SAAb,CAAuB00B,SAAvB,GAAmC,YAAW;AAC5C,QAAI,CAAC,KAAKpD,gBAAV,EAA4B;AAC1B,aAAO,KAAP;AACD;;AACD,QAAI,KAAKV,QAAL,KAAkB,IAAlB,IAA0B,KAAKmD,SAAL,OAAqB,IAAnD,EAAyD;AACvD,aAAO,IAAP;AACD;;AACD,WAAO,KAAP;AACD,GARD;AAUA;;;;;;;;;;AAQA9rB,IAAE,CAACioB,SAAH,CAAalwB,SAAb,CAAuB+zB,SAAvB,GAAmC,YAAW;AAC5C,WAAO,KAAKlD,QAAZ;AACD,GAFD;AAIA;;;;;;;;;;AAQA5oB,IAAE,CAACioB,SAAH,CAAalwB,SAAb,CAAuB20B,QAAvB,GAAkC,YAAW;AAC3C,WAAO,KAAK7D,OAAZ;AACD,GAFD;AAIA;;;;;;;;;;AAQA7oB,IAAE,CAACioB,SAAH,CAAalwB,SAAb,CAAuB6jB,IAAvB,GAA8B,UAASiH,WAAT,EAAsB;AAClD,QAAIja,IAAI,GAAGia,WAAW,IAAI,CAA1B;;AAEA,QAAI,KAAK2G,IAAL,KAAc,SAAd,IAA2B,KAAKA,IAAL,KAAc,WAA7C,EAA0D;AACxD,WAAKmD,OAAL,CAAa/jB,IAAb;AACA,WAAKggB,QAAL,GAAgB,KAAhB;AACA,WAAKW,SAAL,GAAiB,CAAjB;AACA,WAAKV,OAAL,GAAe,KAAf;AACD,KALD,MAMK,IAAI,KAAKxiB,MAAL,IAAe,KAAKgjB,gBAAxB,EAA0C;AAC7C,UAAInrB,GAAG,GAAG6B,OAAO,CAACZ,YAAR,CAAqBkB,WAA/B;AACA,UAAI+Q,CAAC,GAAGxI,IAAI,IAAI,CAAhB;AACA,WAAK2gB,SAAL,GAAiB,CAAjB;AACA,WAAKF,gBAAL,CAAsBzN,IAAtB,CAA2B1d,GAAG,GAAGkT,CAAjC;;AACA,WAAK8X,YAAL,CAAkBtN,IAAlB,CAAuB1d,GAAG,GAAGkT,CAA7B;;AACA,WAAKwX,QAAL,GAAgB,KAAhB;AACA,WAAKC,OAAL,GAAe,KAAf;AACD;AACF,GAlBD;AAoBA;;;;;;AAIA7oB,IAAE,CAACioB,SAAH,CAAalwB,SAAb,CAAuB40B,OAAvB,GAAiC,UAASC,KAAT,EAAgB;AAC/C,QAAI1uB,GAAG,GAAG6B,OAAO,CAACZ,YAAR,CAAqBkB,WAA/B;AACA,QAAIuI,IAAI,GAAGgkB,KAAK,IAAI,CAApB;;AACA,QAAI,KAAKvmB,MAAL,IAAe,KAAKgjB,gBAAxB,EAA0C;AACxC,WAAK,IAAIxwB,CAAT,IAAc,KAAKuwB,iBAAnB,EAAsC;AACpC,YAAMC,gBAAgB,GAAG,KAAKD,iBAAL,CAAuBvwB,CAAvB,CAAzB;;AACA,YAAI,CAAC,CAACwwB,gBAAN,EAAwB;AACtB,cAAI;AACFA,4BAAgB,CAACzN,IAAjB,CAAsB1d,GAAG,GAAG0K,IAA5B;AACD,WAFD,CAEE,OAAM4B,CAAN,EAAS,CACT;AACD;AACF;AACF;;AACD,WAAK0e,YAAL,CAAkBtN,IAAlB,CAAuB1d,GAAG,GAAG0K,IAA7B;;AACA,WAAK8f,QAAL,CAAc,IAAd;AACD;AACF,GAjBD;AAmBA;;;;;;;;;;;;;;;;;;;;;AAmBA1oB,IAAE,CAACioB,SAAH,CAAalwB,SAAb,CAAuB8zB,SAAvB,GAAmC,UAAS1rB,GAAT,EAAc0sB,SAAd,EAAyBC,SAAzB,EAAoC;AACrE,QAAI,OAAO3sB,GAAP,KAAe,QAAnB,EAA6B;AAC3B,UAAIhI,QAAQ,GAAG00B,SAAS,IAAI,CAA5B;AACA,UAAIzsB,QAAQ,GAAG0sB,SAAS,IAAI,CAA5B;AACA,UAAI5uB,GAAG,GAAG6B,OAAO,CAACZ,YAAR,CAAqBkB,WAA/B;AACA,UAAIC,UAAU,GAAG,KAAKzI,MAAL,CAAYgG,IAAZ,CAAiB3F,KAAlC;AACA,WAAKL,MAAL,CAAYgG,IAAZ,CAAiB0C,qBAAjB,CAAuCrC,GAAG,GAAGkC,QAA7C;AACA,WAAKvI,MAAL,CAAYgG,IAAZ,CAAiB2C,uBAAjB,CAAyCF,UAAzC,EAAqDpC,GAAG,GAAGkC,QAA3D;AACA,WAAKvI,MAAL,CAAYgG,IAAZ,CAAiB2C,uBAAjB,CAAyCL,GAAzC,EAA8CjC,GAAG,GAAGkC,QAAN,GAAiBjI,QAA/D;AACD,KARD,MASK,IAAIgI,GAAJ,EAAS;AACZA,SAAG,CAACnF,OAAJ,CAAY,KAAKnD,MAAL,CAAYgG,IAAxB;AACD,KAFI,MAEE;AACL;AACA,aAAO,KAAKhG,MAAL,CAAYgG,IAAnB;AACD;AACF,GAhBD,CAjsBwB,CAmtBxB;;;AACAmC,IAAE,CAACioB,SAAH,CAAalwB,SAAb,CAAuBgK,GAAvB,GAA6B/B,EAAE,CAACioB,SAAH,CAAalwB,SAAb,CAAuB8zB,SAApD,CAptBwB,CAstBxB;;AACA7rB,IAAE,CAACioB,SAAH,CAAalwB,SAAb,CAAuBkK,IAAvB,GAA8BjC,EAAE,CAACioB,SAAH,CAAalwB,SAAb,CAAuB8zB,SAArD;;AAEA7rB,IAAE,CAACioB,SAAH,CAAalwB,SAAb,CAAuBg1B,SAAvB,GAAmC,YAAW;AAC5C,WAAO,KAAKl1B,MAAL,CAAYgG,IAAZ,CAAiB3F,KAAxB;AACD,GAFD;AAIA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAoCA8H,IAAE,CAACioB,SAAH,CAAalwB,SAAb,CAAuBukB,GAAvB,GAA6B,UAASC,IAAT,EAAenc,QAAf,EAAyB;AACpD,SAAKob,WAAL,GAAmBe,IAAnB;AACA,SAAKb,MAAL,CAAYY,GAAZ,CAAgBC,IAAhB,EAAsBnc,QAAtB;AACD,GAHD;AAKA;;;;;;;;;;;AASAJ,IAAE,CAACioB,SAAH,CAAalwB,SAAb,CAAuBykB,MAAvB,GAAgC,YAAW;AACzC,WAAO,KAAKhB,WAAZ;AACD,GAFD;AAIA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAwCAxb,IAAE,CAACioB,SAAH,CAAalwB,SAAb,CAAuB0zB,IAAvB,GAA8B,UAAS/G,YAAT,EAAuB;AACnD,QAAIsI,OAAO,GAAG,KAAd;;AACA,QAAI,OAAOtI,YAAP,KAAwB,WAA5B,EAAyC;AACvC,aAAO,KAAKA,YAAZ;AACD;;AAED,SAAKA,YAAL,GAAoBA,YAApB;;AAEA,QAAIA,YAAY,KAAK,CAArB,EAAwB;AACtBA,kBAAY,GAAG,eAAf;AACD,KAFD,MAIK,IAAIA,YAAY,GAAG,CAAf,IAAoB,CAAC,KAAK4E,QAA9B,EAAwC;AAC3C5E,kBAAY,GAAGpnB,IAAI,CAACue,GAAL,CAAS6I,YAAT,CAAf;AACAsI,aAAO,GAAG,IAAV;AACD,KAHI,MAKA,IAAItI,YAAY,GAAG,CAAf,IAAoB,KAAK4E,QAA7B,EAAuC;AAC1C0D,aAAO,GAAG,IAAV;AACD;;AAED,QAAI,KAAK3D,gBAAT,EAA2B;AACzB,UAAInrB,GAAG,GAAG6B,OAAO,CAACZ,YAAR,CAAqBkB,WAA/B;AACA,WAAKgpB,gBAAL,CAAsB3E,YAAtB,CAAmCnkB,qBAAnC,CAAyDrC,GAAzD;AACA,WAAKmrB,gBAAL,CAAsB3E,YAAtB,CAAmClkB,uBAAnC,CAA2DlD,IAAI,CAACue,GAAL,CAAS6I,YAAT,CAA3D,EAAmFxmB,GAAnF;;AACA,WAAKgrB,YAAL,CAAkBxE,YAAlB,CAA+BnkB,qBAA/B,CAAqDrC,GAArD;;AACA,WAAKgrB,YAAL,CAAkBxE,YAAlB,CAA+BlkB,uBAA/B,CAAuDlD,IAAI,CAACue,GAAL,CAAS6I,YAAT,CAAvD,EAA+ExmB,GAA/E;AACD;;AAED,QAAI8uB,OAAJ,EAAa;AACX,WAAKC,aAAL;AACD;;AACD,WAAO,KAAKvI,YAAZ;AACD,GAjCD,CA3zBwB,CA81BxB;;;AACA1kB,IAAE,CAACioB,SAAH,CAAalwB,SAAb,CAAuBm1B,QAAvB,GAAkC,UAASjQ,GAAT,EAAc;AAC9C,QAAIkQ,eAAe,GAAG1pB,UAAU,CAACwZ,GAAD,CAAV,GAAkBxZ,UAAU,CAAC,EAAD,CAAlD;AACA,SAAKgoB,IAAL,CAAU0B,eAAV;AACD,GAHD;;AAKAntB,IAAE,CAACioB,SAAH,CAAalwB,SAAb,CAAuBq1B,eAAvB,GAAyC,YAAW;AAClD,WAAO,KAAK1I,YAAZ;AACD,GAFD;AAIA;;;;;;;;;AAOA1kB,IAAE,CAACioB,SAAH,CAAalwB,SAAb,CAAuB8X,QAAvB,GAAkC,YAAW;AAC3C;AACA,QAAI,KAAKxJ,MAAT,EAAiB;AACf,aAAO,KAAKA,MAAL,CAAYwJ,QAAnB;AACD,KAFD,MAEO;AACL,aAAO,CAAP;AACD;AACF,GAPD;AASA;;;;;;;;;;;AASA7P,IAAE,CAACioB,SAAH,CAAalwB,SAAb,CAAuBsI,WAAvB,GAAqC,YAAW;AAC9C,WAAO,KAAKipB,QAAL,GACHhsB,IAAI,CAACue,GAAL,CAAS,KAAKoN,QAAL,GAAgB,KAAK5iB,MAAL,CAAYvN,MAArC,IAA+C4I,EAAE,CAAChD,UAD/C,GAEH,KAAKuqB,QAAL,GAAgBvnB,EAAE,CAAChD,UAFvB;AAGD,GAJD;AAMA;;;;;;;;;;;;AAUAsB,IAAE,CAACioB,SAAH,CAAalwB,SAAb,CAAuBs1B,IAAvB,GAA8B,UAASC,OAAT,EAAkBzd,QAAlB,EAA4B;AACxD,QAAIyd,OAAO,GAAG,CAAV,IAAeA,OAAO,GAAG,KAAKjnB,MAAL,CAAYwJ,QAAzC,EAAmD;AACjD,YAAM,wBAAN;AACD;;AACD,QAAIA,QAAQ,GAAG,KAAKxJ,MAAL,CAAYwJ,QAAZ,GAAuByd,OAAtC,EAA+C;AAC7C,YAAM,uBAAN;AACD;;AAED,QAAIC,KAAK,GAAGD,OAAO,IAAI,CAAvB;AACA,QAAIE,GAAG,GAAG3d,QAAQ,IAAIzN,SAAtB;;AACA,QAAI,KAAK0pB,SAAL,EAAJ,EAAsB;AACpB,WAAKlQ,IAAL,CAAU,CAAV;AACD;;AACD,SAAKiF,IAAL,CAAU,CAAV,EAAa,KAAK6D,YAAlB,EAAgC,KAAK7sB,MAAL,CAAYgG,IAAZ,CAAiB3F,KAAjD,EAAwDq1B,KAAxD,EAA+DC,GAA/D;AACD,GAdD;AAgBA;;;;;;;;;;AAQAxtB,IAAE,CAACioB,SAAH,CAAalwB,SAAb,CAAuB01B,QAAvB,GAAkC,YAAW;AAC3C,WAAO,KAAKpnB,MAAL,CAAYH,gBAAnB;AACD,GAFD;AAIA;;;;;;;;;AAOAlG,IAAE,CAACioB,SAAH,CAAalwB,SAAb,CAAuB2G,UAAvB,GAAoC,YAAW;AAC7C,WAAO,KAAK2H,MAAL,CAAY3H,UAAnB;AACD,GAFD;AAIA;;;;;;;;;;AAQAsB,IAAE,CAACioB,SAAH,CAAalwB,SAAb,CAAuB21B,MAAvB,GAAgC,YAAW;AACzC,WAAO,KAAKrnB,MAAL,CAAYvN,MAAnB;AACD,GAFD;AAIA;;;;;;;;;;;;;;;;;;AAgBAkH,IAAE,CAACioB,SAAH,CAAalwB,SAAb,CAAuB41B,QAAvB,GAAkC,UAAS70B,MAAT,EAAiB;AAEjD,QAAI,KAAKuN,MAAT,EAAiB;AACf;AACA,UAAI,CAACvN,MAAL,EAAa;AACXA,cAAM,GAAG8F,MAAM,CAACgvB,KAAP,GAAa,CAAtB;AACD;;AACD,UAAI,KAAKvnB,MAAT,EAAiB;AACf,YAAIA,MAAM,GAAG,KAAKA,MAAlB;AACA,YAAIwnB,UAAU,GAAGxnB,MAAM,CAACvN,MAAP,GAAgBA,MAAjC;AACA,YAAIg1B,UAAU,GAAG,CAAC,EAAED,UAAU,GAAG,EAAf,CAAD,IAAuB,CAAxC;AACA,YAAIJ,QAAQ,GAAGpnB,MAAM,CAACH,gBAAtB;AACA,YAAI6nB,KAAK,GAAG,IAAIlrB,YAAJ,CAAiBvF,IAAI,CAACkG,KAAL,CAAW1K,MAAX,CAAjB,CAAZ;;AAEA,aAAK,IAAIk1B,CAAC,GAAG,CAAb,EAAgBA,CAAC,GAAGP,QAApB,EAA8BO,CAAC,EAA/B,EAAmC;AACjC,cAAIC,IAAI,GAAG5nB,MAAM,CAACJ,cAAP,CAAsB+nB,CAAtB,CAAX;;AACA,eAAK,IAAIn1B,CAAC,GAAG,CAAb,EAAgBA,CAAC,GAAGC,MAApB,EAA4BD,CAAC,EAA7B,EAAiC;AAC/B,gBAAI+T,KAAK,GAAG,CAAC,EAAE/T,CAAC,GAACg1B,UAAJ,CAAb;AACA,gBAAItP,GAAG,GAAG,CAAC,EAAE3R,KAAK,GAAGihB,UAAV,CAAX;AACA,gBAAIzhB,GAAG,GAAG,CAAV;;AACA,iBAAK,IAAIxS,CAAC,GAAGgT,KAAb,EAAoBhT,CAAC,GAAG2kB,GAAxB,EAA6B3kB,CAAC,IAAGk0B,UAAjC,EAA6C;AAC3C,kBAAI51B,KAAK,GAAG+1B,IAAI,CAACr0B,CAAD,CAAhB;;AACA,kBAAI1B,KAAK,GAAGkU,GAAZ,EAAiB;AACfA,mBAAG,GAAGlU,KAAN,CADe,CAEjB;AACC,eAHD,MAGO,IAAI,CAACA,KAAD,GAASkU,GAAb,EAAkB;AACvBA,mBAAG,GAAGlU,KAAN;AACD;AACF;;AACD,gBAAI81B,CAAC,KAAK,CAAN,IAAW1wB,IAAI,CAACue,GAAL,CAASzP,GAAT,IAAgB2hB,KAAK,CAACl1B,CAAD,CAApC,EAAyC;AACvCk1B,mBAAK,CAACl1B,CAAD,CAAL,GAAWuT,GAAX;AACD;AACF;AACF;;AAED,eAAO2hB,KAAP;AACD;AACF,KAnCD,MAqCK;AACH,YAAM,6CAAN;AACD;AACF,GA1CD;AA4CA;;;;;;;;;;;;;;;;;;;;;;;;AAsBA/tB,IAAE,CAACioB,SAAH,CAAalwB,SAAb,CAAuBk1B,aAAvB,GAAuC,YAAW;AAChD,QAAI,KAAK5mB,MAAT,EAAiB;AACf,UAAI6nB,UAAU,GAAG,KAAKjF,QAAL,GAAgBvnB,EAAE,CAAChD,UAApC;AACA,UAAIyvB,MAAM,GAAG,KAAKpB,SAAL,EAAb;AACA,WAAKlB,SAAL,CAAe,CAAf,EAAkB,KAAlB;AAEA,UAAM9D,WAAW,GAAG,KAAK1hB,MAAL,CAAYH,gBAAhC;;AACA,WAAK,IAAIrN,CAAC,GAAG,CAAb,EAAgBA,CAAC,GAAGkvB,WAApB,EAAiClvB,CAAC,EAAlC,EAAsC;AACpC,aAAKwN,MAAL,CAAYJ,cAAZ,CAA2BpN,CAA3B,EAA8Bm0B,OAA9B;AACD,OARc,CASf;;;AACA,WAAK1D,QAAL,GAAgB,CAAC,KAAKA,QAAtB;;AAEA,UAAI4E,UAAJ,EAAgB;AACd,aAAKb,IAAL,CAAU,KAAKxd,QAAL,KAAkBqe,UAA5B;AACD;;AACD,WAAKrC,SAAL,CAAesC,MAAf,EAAuB,KAAvB;AACD,KAhBD,MAgBO;AACL,YAAM,+BAAN;AACD;AACF,GApBD;AAsBA;;;;;;;;;;;;;;AAYAnuB,IAAE,CAACioB,SAAH,CAAalwB,SAAb,CAAuBq2B,OAAvB,GAAiC,UAAS9a,QAAT,EAAmB;AAClD,SAAKoV,QAAL,GAAgBpV,QAAhB;AACA,WAAO,IAAP;AACD,GAHD;;AAKAtT,IAAE,CAACioB,SAAH,CAAalwB,SAAb,CAAuBmX,GAAvB,GAA6B,YAAW,CACtC;AACD,GAFD;;AAIAlP,IAAE,CAACioB,SAAH,CAAalwB,SAAb,CAAuB8C,OAAvB,GAAiC,YAAW;AAC1C,QAAIqD,GAAG,GAAG6B,OAAO,CAACZ,YAAR,CAAqBkB,WAA/B,CAD0C,CAG1C;;AACA,QAAI8B,KAAK,GAAGpC,OAAO,CAACH,UAAR,CAAmBlH,OAAnB,CAA2B,IAA3B,CAAZ;AACAqH,WAAO,CAACH,UAAR,CAAmB7G,MAAnB,CAA0BoJ,KAA1B,EAAiC,CAAjC;AAEA,SAAKyZ,IAAL,CAAU1d,GAAV;;AACA,QAAI,KAAKmI,MAAL,IAAe,KAAKgjB,gBAAxB,EAA0C;AACxC,WAAK,IAAIxwB,CAAC,GAAG,CAAb,EAAgBA,CAAC,GAAG,KAAKuwB,iBAAL,CAAuBtwB,MAAvB,GAAgC,CAApD,EAAuDD,CAAC,EAAxD,EAA4D;AAC1D,YAAI,KAAKuwB,iBAAL,CAAuBvwB,CAAvB,MAA8B,IAAlC,EAAwC;AACtC,eAAKuwB,iBAAL,CAAuBvwB,CAAvB,EAA0BkC,UAA1B;;AACA,cAAI;AACF,iBAAKquB,iBAAL,CAAuBvwB,CAAvB,EAA0B+iB,IAA1B,CAA+B1d,GAA/B;AACD,WAFD,CAEE,OAAMsM,CAAN,EAAS;AACTtL,mBAAO,CAACmvB,OAAR,CAAgB,kCAAhB;AACD;;AACD,eAAKjF,iBAAL,CAAuBvwB,CAAvB,IAA4B,IAA5B;AACD;AACF;;AACD,UAAK,KAAKizB,SAAL,EAAL,EAAwB;AACtB,YAAI;AACF,eAAK5C,YAAL,CAAkBtN,IAAlB,CAAuB1d,GAAvB;AACD,SAFD,CAEE,OAAMsM,CAAN,EAAS;AACTtL,iBAAO,CAACpB,GAAR,CAAY0M,CAAZ;AACD;;AACD,aAAK0e,YAAL,GAAoB,IAApB;AACD;AACF;;AACD,QAAI,KAAKrxB,MAAT,EAAiB;AACf,WAAKA,MAAL,CAAYkD,UAAZ;AACA,WAAKlD,MAAL,GAAc,IAAd;AACD;;AACD,QAAI,KAAK6jB,MAAT,EAAiB;AACf,WAAKA,MAAL,CAAY3gB,UAAZ;AACA,WAAK2gB,MAAL,GAAc,IAAd;AACD;AACF,GArCD;AAuCA;;;;;;;;;;;;;AAWA1b,IAAE,CAACioB,SAAH,CAAalwB,SAAb,CAAuBiD,OAAvB,GAAiC,UAASC,IAAT,EAAe;AAC9C,QAAI,CAACA,IAAL,EAAW;AACT,WAAKygB,MAAL,CAAY1gB,OAAZ,CAAoB+E,OAAO,CAACtI,KAA5B;AACD,KAFD,MAGK;AACH,UAAIwD,IAAI,CAAC4D,cAAL,CAAoB,OAApB,CAAJ,EAAkC;AAChC,aAAK6c,MAAL,CAAY1gB,OAAZ,CAAoBC,IAAI,CAACxD,KAAzB;AACD,OAFD,MAEO;AACL,aAAKikB,MAAL,CAAY1gB,OAAZ,CAAoBC,IAApB;AACD;AACF;AACF,GAXD;AAaA;;;;;;;;AAMA+E,IAAE,CAACioB,SAAH,CAAalwB,SAAb,CAAuBgD,UAAvB,GAAoC,YAAW;AAC7C,QAAI,KAAK2gB,MAAT,EAAiB;AACf,WAAKA,MAAL,CAAY3gB,UAAZ;AACD;AACF,GAJD;AAMA;;;;AAEAiF,IAAE,CAACioB,SAAH,CAAalwB,SAAb,CAAuBu2B,QAAvB,GAAkC,YAAW;AAC3CpvB,WAAO,CAACkO,IAAR,CAAa,mFAAb;AACD,GAFD;AAIA;;;;;;;;;;;AASApN,IAAE,CAACioB,SAAH,CAAalwB,SAAb,CAAuBw2B,OAAvB,GAAiC,UAASlpB,CAAT,EAAYiO,QAAZ,EAAsB;AACrD,QAAIzO,IAAI,GAAG7E,EAAE,CAACjI,SAAH,CAAa4M,iBAAb,CAA+BU,CAA/B,CAAX;;AACA,SAAKgjB,GAAL,GAAWxjB,IAAX;AACA,SAAK6kB,IAAL,CAAUpW,QAAV;AACD,GAJD;AAMA;;;;;;;;;;;AASAtT,IAAE,CAACioB,SAAH,CAAalwB,SAAb,CAAuBy2B,SAAvB,GAAmC,UAASC,GAAT,EAAc;AAC/C,QAAI1G,WAAW,GAAG0G,GAAG,CAAC31B,MAAtB;AACA,QAAI41B,IAAI,GAAGD,GAAG,CAAC,CAAD,CAAH,CAAO31B,MAAlB;AACA,QAAI61B,SAAS,GAAGjtB,EAAE,CAAC2K,YAAH,CAAgB0b,WAAhB,EAA6B2G,IAA7B,EAAmChtB,EAAE,CAAChD,UAAtC,CAAhB;;AAEA,QAAI,EAAE+vB,GAAG,CAAC,CAAD,CAAH,YAAkB5rB,YAApB,CAAJ,EAAuC;AACrC4rB,SAAG,CAAC,CAAD,CAAH,GAAS,IAAI5rB,YAAJ,CAAiB4rB,GAAG,CAAC,CAAD,CAApB,CAAT;AACD;;AAED,SAAK,IAAIG,UAAU,GAAG,CAAtB,EAAyBA,UAAU,GAAG7G,WAAtC,EAAmD6G,UAAU,EAA7D,EAAiE;AAC/D,UAAIC,OAAO,GAAGF,SAAS,CAAC1oB,cAAV,CAA0B2oB,UAA1B,CAAd;AACAC,aAAO,CAAC72B,GAAR,CAAYy2B,GAAG,CAACG,UAAD,CAAf;AACD;;AAED,SAAKvoB,MAAL,GAAcsoB,SAAd,CAd+C,CAgB/C;;AACA,SAAKjT,MAAL,CAAYwL,aAAZ,CAA0Ba,WAA1B;AACD,GAlBD,CA1qCwB,CA8rCxB;AACA;AACA;AACA;AACA;AACA;AACA;;;AAEA,MAAI+G,oBAAoB,GAAG,SAAvBA,oBAAuB,CAASzoB,MAAT,EAAiB;AAC1C,QAAMtD,GAAG,GAAGsD,MAAM,CAACvN,MAAnB;AACA,QAAMi2B,QAAQ,GAAGrtB,EAAE,CAAC2K,YAAH,CAAiB,CAAjB,EAAoBhG,MAAM,CAACvN,MAA3B,EAAmC4I,EAAE,CAAChD,UAAtC,CAAjB;AACA,QAAMswB,WAAW,GAAGD,QAAQ,CAAC9oB,cAAT,CAAwB,CAAxB,CAApB;;AACA,SAAK,IAAI9D,KAAK,GAAG,CAAjB,EAAoBA,KAAK,GAAGY,GAA5B,EAAiCZ,KAAK,EAAtC,EAA0C;AACxC6sB,iBAAW,CAAC7sB,KAAD,CAAX,GAAqBA,KAArB;AACD;;AACD,WAAO4sB,QAAP;AACD,GARD,CAtsCwB,CAgtCxB;;;AACA/uB,IAAE,CAACioB,SAAH,CAAalwB,SAAb,CAAuBi0B,gBAAvB,GAA0C,YAAW;AAAA;;AACnD,QAAIjQ,IAAI,GAAG,IAAX;AACA,QAAI7d,GAAG,GAAGwD,EAAE,CAACrB,WAAb;AACA,QAAI4uB,KAAK,GAAGvtB,EAAE,CAAC8K,kBAAH,EAAZ,CAHmD,CAKnD;;AACA,QAAIuP,IAAI,CAACoN,YAAT,EAAuB;AACrBpN,UAAI,CAACoN,YAAL,CAAkBpuB,UAAlB;;AACA,aAAOghB,IAAI,CAACoN,YAAZ;AACD;;AACDpN,QAAI,CAACoN,YAAL,GAAoB,IAAI+F,gBAAJ,CAAqBxtB,EAArB,EAAyBsmB,cAAc,CAACxa,kBAAxC,CAApB;;AACAuO,QAAI,CAACoN,YAAL,CAAkBgG,IAAlB,CAAuBC,SAAvB,GAAmC,UAAAzb,KAAK,EAAI;AAC1C,UAAIA,KAAK,CAAC0b,IAAN,CAAW5lB,IAAX,KAAoB,UAAxB,EAAoC;AAClC;AACA,YAAIkK,KAAK,CAAC0b,IAAN,CAAWxW,QAAX,KAAwB,CAA5B,EAA+B;AAC7B;AACD;;AACD,aAAI,CAACoQ,QAAL,GAAgBtV,KAAK,CAAC0b,IAAN,CAAWxW,QAA3B,CALkC,CAOlC;;AACA,aAAI,CAACyW,aAAL,CAAmBvT,IAAI,CAACkN,QAAxB;AACD;AACF,KAXD,CAXmD,CAwBnD;;;AACAgG,SAAK,CAAC5oB,MAAN,GAAeyoB,oBAAoB,CAAE/S,IAAI,CAAC1V,MAAP,CAAnC;AAEA4oB,SAAK,CAACvK,YAAN,CAAmB1V,cAAnB,CAAkC+M,IAAI,CAAC2I,YAAvC,EAAqDxmB,GAArD;AAEA+wB,SAAK,CAACj0B,OAAN,CAAc+gB,IAAI,CAACoN,YAAnB;;AACApN,QAAI,CAACoN,YAAL,CAAkBnuB,OAAlB,CAA0BgF,EAAE,CAACS,QAAH,CAAYC,WAAtC;;AAEA,WAAOuuB,KAAP;AACD,GAjCD,CAjtCwB,CAovCxB;;;AACAjvB,IAAE,CAACioB,SAAH,CAAalwB,SAAb,CAAuBg0B,eAAvB,GAAyC,YAAW;AAClD,QAAI1C,gBAAgB,GAAG3nB,EAAE,CAAC8K,kBAAH,EAAvB;AACA6c,oBAAgB,CAAChjB,MAAjB,GAA0B,KAAKA,MAA/B;AACAgjB,oBAAgB,CAAC3E,YAAjB,CAA8BxsB,KAA9B,GAAsC,KAAKwsB,YAA3C;AACA2E,oBAAgB,CAACruB,OAAjB,CAAyB,KAAKnD,MAA9B;AACA,WAAOwxB,gBAAP;AACD,GAND;AAQA;;;;;;;;;;;;;;;;;;;;AAkBArpB,IAAE,CAACioB,SAAH,CAAalwB,SAAb,CAAuBw3B,YAAvB,GAAsC,UAASjc,QAAT,EAAmBkc,cAAnB,EAAmCC,aAAnC,EAAkDC,SAAlD,EAA6D;AACjG,QAAIC,MAAM,GAAG,KAAKtpB,MAAL,CAAYvN,MAAzB;AACA,QAAI4F,UAAU,GAAG,KAAK2H,MAAL,CAAY3H,UAA7B;AACA,QAAI2H,MAAM,GAAG,KAAKA,MAAlB;AACA,QAAIupB,QAAQ,GAAG,EAAf;AAEA,QAAIC,gBAAgB,GAAGL,cAAc,IAAI,GAAzC;AAAA,QACEjwB,SAAS,GAAGswB,gBADd;AAAA,QAEEC,YAAY,GAAGL,aAAa,IAAI,IAFlC;AAAA,QAGEM,QAAQ,GAAGL,SAAS,IAAI,GAH1B,CANiG,CAWjG;;AACA,QAAIM,cAAc,GAAG,IAAIpxB,MAAM,CAACsmB,mBAAX,CAA+B,CAA/B,EAAkCyK,MAAlC,EAA0CjxB,UAA1C,CAArB,CAZiG,CAcjG;;AACA,QAAIuxB,MAAM,GAAGD,cAAc,CAACxjB,kBAAf,EAAb;AACAyjB,UAAM,CAAC5pB,MAAP,GAAgBA,MAAhB,CAhBiG,CAkBjG;;AACA,QAAI6D,MAAM,GAAG8lB,cAAc,CAAChe,kBAAf,EAAb;AACA9H,UAAM,CAACvE,IAAP,GAAc,SAAd;AACAsqB,UAAM,CAACj1B,OAAP,CAAekP,MAAf;AACAA,UAAM,CAAClP,OAAP,CAAeg1B,cAAc,CAAC30B,WAA9B,EAtBiG,CAwBjG;;AACA40B,UAAM,CAACrjB,KAAP,CAAa,CAAb;AACAojB,kBAAc,CAACE,cAAf,GA1BiG,CA0BhE;AAEjC;;AACAF,kBAAc,CAACG,UAAf,GAA4B,UAAS3lB,CAAT,EAAY;AACtC,UAAI,CAACuR,IAAI,CAACL,MAAV,EAAkB;AAClB,UAAI0U,cAAc,GAAG5lB,CAAC,CAAC6lB,cAAvB;AACA,UAAIC,UAAU,GAAGF,cAAc,CAACnqB,cAAf,CAA8B,CAA9B,CAAjB,CAHsC,CAMtC;AACA;;AACA,SAAG;AACD2pB,gBAAQ,GAAGW,mBAAmB,CAACD,UAAD,EAAa/wB,SAAb,CAA9B;AACAA,iBAAS,IAAI,KAAb;AACD,OAHD,QAGStF,MAAM,CAACC,IAAP,CAAY01B,QAAZ,EAAsB92B,MAAtB,GAA+Bi3B,QAA/B,IAA2CxwB,SAAS,IAAIuwB,YAHjE,EARsC,CActC;AACA;;;AACA,UAAIU,cAAc,GAAGC,gCAAgC,CAACb,QAAD,CAArD,CAhBsC,CAkBtC;;AACA,UAAIc,MAAM,GAAGC,qBAAqB,CAACH,cAAD,EAAiBJ,cAAc,CAAC1xB,UAAhC,CAAlC,CAnBsC,CAqBtC;;AACA,UAAIkyB,SAAS,GAAGF,MAAM,CAACG,IAAP,CAAY,UAASC,IAAT,EAAeC,IAAf,EAAqB;AAC/C,eAAOA,IAAI,CAACC,KAAL,GAAaF,IAAI,CAACE,KAAzB;AAED,OAHe,EAGbj4B,MAHa,CAGN,CAHM,EAGJ,CAHI,CAAhB,CAtBsC,CA2BtC;;AACA,WAAKk4B,KAAL,GAAaL,SAAS,CAAC,CAAD,CAAT,CAAaK,KAA1B,CA5BsC,CA8BtC;AACA;;AACA,UAAIC,WAAW,GAAG,CAAlB;AACA,UAAIC,UAAU,GAAGC,kBAAkB,CAACxB,QAAD,EAAWgB,SAAS,CAAC,CAAD,CAAT,CAAaK,KAAxB,EAA+Bb,cAAc,CAAC1xB,UAA9C,EAA0DwyB,WAA1D,CAAnC;AAEA5d,cAAQ,CAAC6d,UAAD,CAAR;AACD,KApCD;AAqCD,GAlED,CA/wCwB,CAm1CxB;;;AACA,MAAIE,IAAI,GAAG,SAAPA,IAAO,CAAStvB,GAAT,EAAclJ,CAAd,EAAiB;AAC1B,SAAKy4B,WAAL,GAAmBz4B,CAAnB;AACA,SAAK04B,SAAL,GAAiBxvB,GAAjB;AACA,SAAKyvB,MAAL,GAAc,EAAd;AACA,SAAKC,SAAL,GAAiB,EAAjB;AACD,GALD,CAp1CwB,CA21CxB;AACA;;;AACA,WAASlB,mBAAT,CAA6BlB,IAA7B,EAAmC9vB,SAAnC,EAA8C;AAC5C,QAAImyB,QAAQ,GAAG,EAAf;AACA,QAAI54B,MAAM,GAAGu2B,IAAI,CAACv2B,MAAlB;;AAEA,SAAK,IAAID,CAAC,GAAG,CAAb,EAAgBA,CAAC,GAAGC,MAApB,EAA4BD,CAAC,EAA7B,EAAiC;AAC/B,UAAIw2B,IAAI,CAACx2B,CAAD,CAAJ,GAAU0G,SAAd,EAAyB;AACvB,YAAIwC,GAAG,GAAGstB,IAAI,CAACx2B,CAAD,CAAd;AACA,YAAI84B,IAAI,GAAG,IAAIN,IAAJ,CAAStvB,GAAT,EAAclJ,CAAd,CAAX;AACA64B,gBAAQ,CAAC74B,CAAD,CAAR,GAAc84B,IAAd,CAHuB,CAIvB;;AACA94B,SAAC,IAAI,IAAL;AACD;;AACDA,OAAC;AACF;;AACD,WAAO64B,QAAP;AACD,GA52CuB,CA82CxB;;;AACA,WAASjB,gCAAT,CAA0CiB,QAA1C,EAAoD;AAClD,QAAIlB,cAAc,GAAG,EAArB;AACA,QAAIoB,UAAU,GAAG33B,MAAM,CAACC,IAAP,CAAYw3B,QAAZ,EAAsBb,IAAtB,EAAjB;;AAEA,SAAK,IAAI1uB,KAAK,GAAG,CAAjB,EAAoBA,KAAK,GAAGyvB,UAAU,CAAC94B,MAAvC,EAA+CqJ,KAAK,EAApD,EAAwD;AAEtD;AACA,WAAK,IAAItJ,CAAC,GAAG,CAAb,EAAgBA,CAAC,GAAG,EAApB,EAAwBA,CAAC,EAAzB,EAA6B;AAC3B,YAAIg5B,SAAS,GAAGH,QAAQ,CAACE,UAAU,CAACzvB,KAAD,CAAX,CAAxB;AACA,YAAI2vB,OAAO,GAAGJ,QAAQ,CAACE,UAAU,CAACzvB,KAAK,GAAGtJ,CAAT,CAAX,CAAtB;;AAEA,YAAIg5B,SAAS,IAAIC,OAAjB,EAA0B;AACxB,cAAIC,QAAQ,GAAGF,SAAS,CAACP,WAAzB;AACA,cAAIU,MAAM,GAAGF,OAAO,CAACR,WAArB;AACA,cAAIrzB,QAAQ,GAAI+zB,MAAM,GAAGD,QAAzB,CAHwB,CAKxB;;AACA,cAAI9zB,QAAQ,GAAG,CAAf,EAAkB;AAChB4zB,qBAAS,CAACJ,SAAV,CAAoBp3B,IAApB,CAAyB4D,QAAzB;AACD,WARuB,CAUxB;;;AACA,cAAIg0B,aAAa,GAAGzB,cAAc,CAAC0B,IAAf,CAAoB,UAASC,aAAT,EAAwB;AAC9D,gBAAIA,aAAa,CAACl0B,QAAd,KAA2BA,QAA/B,EAAyC;AACvCk0B,2BAAa,CAACnB,KAAd;AACA,qBAAOmB,aAAP;AACD;AACF,WALmB,CAApB,CAXwB,CAkBxB;;AACA,cAAI,CAACF,aAAL,EAAoB;AAClBzB,0BAAc,CAACn2B,IAAf,CAAoB;AAClB4D,sBAAQ,EAAEA,QADQ;AAElB+yB,mBAAK,EAAE;AAFW,aAApB;AAID;AACF;AACF;AACF;;AAED,WAAOR,cAAP;AACD,GAx5CuB,CA25CxB;;;AACA,WAASG,qBAAT,CAA+BH,cAA/B,EAA+C9xB,UAA/C,EAA2D;AACzD,QAAI0zB,WAAW,GAAG,EAAlB;AAEA5B,kBAAc,CAAC3R,OAAf,CAAuB,UAASsT,aAAT,EAAwB;AAE7C,UAAI;AACF;AACA,YAAIE,gBAAgB,GAAG/0B,IAAI,CAACue,GAAL,CAAU,MAAMsW,aAAa,CAACl0B,QAAd,GAAyBS,UAA/B,CAAV,CAAvB;AAEA2zB,wBAAgB,GAAGC,QAAQ,CAACD,gBAAD,CAA3B;AAEA,YAAIE,UAAU,GAAGH,WAAW,CAACF,IAAZ,CAAiB,UAASM,UAAT,EAAqB;AACrD,cAAIA,UAAU,CAACvB,KAAX,KAAqBoB,gBAAzB,EACE,OAAOG,UAAU,CAACxB,KAAX,IAAoBmB,aAAa,CAACnB,KAAzC;AACH,SAHgB,CAAjB;;AAIA,YAAI,CAACuB,UAAL,EAAiB;AACf,cAAItW,KAAK,CAACoW,gBAAD,CAAT,EAA6B;AAC3B;AACD;;AACDD,qBAAW,CAAC/3B,IAAZ,CAAiB;AACf42B,iBAAK,EAAE3zB,IAAI,CAACkG,KAAL,CAAW6uB,gBAAX,CADQ;AAEfrB,iBAAK,EAAEmB,aAAa,CAACnB;AAFN,WAAjB;AAID;AACF,OAnBD,CAmBE,OAAMxmB,CAAN,EAAS;AACT,cAAMA,CAAN;AACD;AAEF,KAzBD;AA2BA,WAAO4nB,WAAP;AACD,GA37CuB,CA67CxB;;;AACA,WAAShB,kBAAT,CAA4BM,QAA5B,EAAsCT,KAAtC,EAA6CvyB,UAA7C,EAAyDwyB,WAAzD,EAAsE;AACpE,QAAIuB,eAAe,GAAG,EAAtB;AACA,QAAIb,UAAU,GAAG33B,MAAM,CAACC,IAAP,CAAYw3B,QAAZ,EAAsBb,IAAtB,EAAjB,CAFoE,CAIpE;;AACA,SAAK,IAAIh4B,CAAC,GAAG,CAAb,EAAgBA,CAAC,GAAG+4B,UAAU,CAAC94B,MAA/B,EAAuCD,CAAC,EAAxC,EAA4C;AAC1C,UAAI65B,GAAG,GAAGd,UAAU,CAAC/4B,CAAD,CAApB;AACA,UAAI84B,IAAI,GAAGD,QAAQ,CAACgB,GAAD,CAAnB;;AAEA,WAAK,IAAI94B,CAAC,GAAG,CAAb,EAAgBA,CAAC,GAAG+3B,IAAI,CAACF,SAAL,CAAe34B,MAAnC,EAA2Cc,CAAC,EAA5C,EAAgD;AAC9C,YAAI+4B,WAAW,GAAGr1B,IAAI,CAACkG,KAAL,CAAWlG,IAAI,CAACue,GAAL,CAAU,MAAM8V,IAAI,CAACF,SAAL,CAAe73B,CAAf,IAAoB8E,UAA1B,CAAV,CAAX,CAAlB;AAEAi0B,mBAAW,GAAGL,QAAQ,CAACK,WAAD,CAAtB;;AAEA,YAAKr1B,IAAI,CAACue,GAAL,CAAS8W,WAAW,GAAG1B,KAAvB,IAAgCC,WAArC,EAAmD;AACjD;AACAuB,yBAAe,CAACp4B,IAAhB,CAAqBs3B,IAAI,CAACL,WAAL,GAAiB5yB,UAAtC;AACD;AACF;AACF,KAnBmE,CAqBpE;;;AACA+zB,mBAAe,GAAGA,eAAe,CAACvoB,MAAhB,CAAuB,UAAS0oB,QAAT,EAAmBzwB,KAAnB,EAA0BmK,GAA1B,EAA+B;AACtE,UAAIumB,GAAG,GAAGvmB,GAAG,CAACnK,KAAK,GAAG,CAAT,CAAH,GAAiBywB,QAA3B;;AACA,UAAIC,GAAG,GAAG,IAAV,EAAgB;AACd,eAAO,IAAP;AACD;AACF,KALiB,CAAlB;AAOA,WAAOJ,eAAP;AACD,GA59CuB,CA89CxB;;;AACA,WAASH,QAAT,CAAkBD,gBAAlB,EAAoC;AAClC;AACA,QAAI,CAACzvB,QAAQ,CAACyvB,gBAAD,CAAT,IAA+BA,gBAAgB,KAAK,CAAxD,EAA4D;AAC1D;AACD,KAJiC,CAMlC;;;AACA,WAAOA,gBAAgB,GAAG,EAA1B;AAA8BA,sBAAgB,IAAI,CAApB;AAA9B;;AACA,WAAOA,gBAAgB,GAAG,GAAnB,IAA0BA,gBAAgB,GAAG,EAApD;AAAwDA,sBAAgB,IAAI,CAApB;AAAxD;;AAEA,WAAOA,gBAAP;AACD;AAGD;AAEA;AACA;;;AACA,MAAIS,GAAG,GAAG,SAANA,GAAM,CAASxf,QAAT,EAAmB1K,IAAnB,EAAyBmqB,EAAzB,EAA6B12B,GAA7B,EAAkC;AAC1C,SAAKiX,QAAL,GAAgBA,QAAhB;AACA,SAAK1K,IAAL,GAAYA,IAAZ;AACA,SAAKmqB,EAAL,GAAUA,EAAV;AACA,SAAK12B,GAAL,GAAWA,GAAX;AACD,GALD;AAOA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAsEA2D,IAAE,CAACioB,SAAH,CAAalwB,SAAb,CAAuBi7B,MAAvB,GAAgC,UAASpqB,IAAT,EAAe0K,QAAf,EAAyBjX,GAAzB,EAA8B;AAC5D,QAAI02B,EAAE,GAAG,KAAK/J,aAAL,EAAT;AAEA,QAAIiK,GAAG,GAAG,IAAIH,GAAJ,CAAQxf,QAAR,EAAkB1K,IAAlB,EAAwBmqB,EAAxB,EAA4B12B,GAA5B,CAAV;;AACA,SAAK0sB,KAAL,CAAW1uB,IAAX,CAAgB44B,GAAhB,EAJ4D,CAM5D;AACA;AACA;;;AAEA,WAAOF,EAAP;AACD,GAXD;AAaA;;;;;;;;;;AAQA/yB,IAAE,CAACioB,SAAH,CAAalwB,SAAb,CAAuBm7B,SAAvB,GAAmC,UAASH,EAAT,EAAa;AAC9C,QAAII,SAAS,GAAG,KAAKpK,KAAL,CAAWjwB,MAA3B;;AACA,SAAK,IAAID,CAAC,GAAG,CAAb,EAAgBA,CAAC,GAAGs6B,SAApB,EAA+Bt6B,CAAC,EAAhC,EAAoC;AAClC,UAAIo6B,GAAG,GAAG,KAAKlK,KAAL,CAAWlwB,CAAX,CAAV;;AACA,UAAIo6B,GAAG,CAACF,EAAJ,KAAWA,EAAf,EAAmB;AACjB,aAAKhK,KAAL,CAAWhwB,MAAX,CAAkBF,CAAlB,EAAqB,CAArB;;AACA;AACD;AACF;;AAED,QAAI,KAAKkwB,KAAL,CAAWjwB,MAAX,KAAsB,CAA1B,EAA6B,CAC3B;AACA;AACD;AACF,GAdD;AAgBA;;;;;;;;AAMAkH,IAAE,CAACioB,SAAH,CAAalwB,SAAb,CAAuBq7B,SAAvB,GAAmC,YAAW;AAC5C,SAAKrK,KAAL,GAAa,EAAb,CAD4C,CAE5C;AACD,GAHD,CAzmDwB,CA8mDxB;AACA;;;AACA/oB,IAAE,CAACioB,SAAH,CAAalwB,SAAb,CAAuBu3B,aAAvB,GAAuC,UAASzW,QAAT,EAAmB;AACxD,QAAIwa,YAAY,GAAGxa,QAAQ,GAAC,KAAKxS,MAAL,CAAY3H,UAAxC;AACA,QAAIy0B,SAAS,GAAG,KAAKpK,KAAL,CAAWjwB,MAA3B;;AAEA,SAAK,IAAID,CAAC,GAAG,CAAb,EAAiBA,CAAC,GAAGs6B,SAArB,EAAgCt6B,CAAC,EAAjC,EAAqC;AACnC,UAAIo6B,GAAG,GAAG,KAAKlK,KAAL,CAAWlwB,CAAX,CAAV;AACA,UAAIy6B,YAAY,GAAGL,GAAG,CAACrqB,IAAvB;AACA,UAAIvM,GAAG,GAAG42B,GAAG,CAAC52B,GAAd;;AAEA,UAAI,KAAKk3B,SAAL,GAAiBD,YAAjB,IAAiCA,YAAY,IAAID,YAArD,EAAmE;AAEjE;AACAJ,WAAG,CAAC3f,QAAJ,CAAajX,GAAb;AACD;AAEF;;AAED,SAAKk3B,SAAL,GAAiBF,YAAjB;AACD,GAlBD;AAoBA;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA0BArzB,IAAE,CAACioB,SAAH,CAAalwB,SAAb,CAAuBy7B,IAAvB,GAA8B,UAASC,QAAT,EAAmB;AAC/C,QAAMC,QAAQ,GAAG7tB,YAAY,CAAC,KAAKQ,MAAN,CAA7B;AACArG,MAAE,CAACjI,SAAH,CAAa47B,SAAb,CAAuB,CAACD,QAAD,CAAvB,EAAmCD,QAAnC,EAA6C,KAA7C;AACD,GAHD;AAKA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAoDAzzB,IAAE,CAACioB,SAAH,CAAalwB,SAAb,CAAuB67B,OAAvB,GAAiC,YAAW;AAC1C,QAAMF,QAAQ,GAAG7tB,YAAY,CAAC,KAAKQ,MAAN,CAA7B;AACA,WAAO,IAAIsF,IAAJ,CAAS,CAAC+nB,QAAD,CAAT,EAAqB;AAAE/tB,UAAI,EAAE;AAAR,KAArB,CAAP;AACD,GAHD,CAvtDwB,CA4tDxB;;;AACA,WAASikB,WAAT,CAAqBpf,CAArB,EAAwB;AACtB,QAAMqpB,oBAAoB,GAAGrpB,CAAC,CAACspB,MAA/B;AACA,QAAMC,SAAS,GAAG,IAAlB,CAFsB,CAItB;;AACAF,wBAAoB,CAACjL,QAArB,GAAgC,KAAhC;AACAiL,wBAAoB,CAACG,mBAArB,CAAyC,OAAzC,EAAkDD,SAAS,CAACnK,WAA5D,EANsB,CAQtB;;AACAmK,aAAS,CAACrL,QAAV,CAAmBqL,SAAnB;;AAEAA,aAAS,CAAC3K,iBAAV,CAA4BvK,OAA5B,CAAoC,UAAUvI,CAAV,EAAazd,CAAb,EAAgB;AAClD,UAAIyd,CAAC,CAACsS,QAAF,KAAe,KAAnB,EAA0B;AACxBmL,iBAAS,CAAC3K,iBAAV,CAA4BrwB,MAA5B,CAAmCF,CAAnC;AACD;AACF,KAJD;;AAMA,QAAIk7B,SAAS,CAAC3K,iBAAV,CAA4BtwB,MAA5B,KAAuC,CAA3C,EAA8C;AAC5Ci7B,eAAS,CAACnL,QAAV,GAAqB,KAArB;AACD;AACF;AACF,CAlvDK;AAAA,oGAAN,C;;;;;;;ACFA,kCAAa;;AAEbzxB,mCAAO,UAAUoK,OAAV,EAAmB;AACxB,MAAIxB,OAAO,GAAGwB,mBAAO,CAAC,CAAD,CAArB;;AACA,MAAIymB,cAAc,GAAGzmB,mBAAO,CAAC,EAAD,CAA5B;AAEA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAwCAvB,IAAE,CAACi0B,SAAH,GAAe,UAASC,SAAT,EAAoB;AAEjC;AACA,SAAKC,UAAL,GAAkB,IAAlB,CAHiC,CAKjC;;AACA,SAAKh1B,YAAL,GAAoBY,OAAO,CAACZ,YAA5B;AACA,SAAKgqB,YAAL,GAAoB,IAAI+F,gBAAJ,CAAqB,KAAK/vB,YAA1B,EAAwC6oB,cAAc,CAACva,kBAAvD,EAA2E;AAC7F2mB,wBAAkB,EAAE,CAAC,CAAD,CADyE;AAE7FC,sBAAgB,EAAE;AAChBC,iBAAS,EAAE,KADK;AAEhBJ,iBAAS,EAAEA,SAAS,IAAI;AAFR;AAF2E,KAA3E,CAApB;;AAQA,SAAK/K,YAAL,CAAkBgG,IAAlB,CAAuBC,SAAvB,GAAmC,UAASzb,KAAT,EAAgB;AACjD,UAAIA,KAAK,CAAC0b,IAAN,CAAW5lB,IAAX,KAAoB,WAAxB,EAAqC;AACnC,aAAK5C,MAAL,GAAc8M,KAAK,CAAC0b,IAAN,CAAWxoB,MAAzB;AACA,aAAK0tB,OAAL,GAAe5gB,KAAK,CAAC0b,IAAN,CAAWkF,OAA1B;AACA,aAAKC,SAAL,GAAiB7gB,KAAK,CAAC0b,IAAN,CAAWmF,SAA5B;AACA,aAAKC,aAAL,GAAqB9gB,KAAK,CAAC0b,IAAN,CAAWoF,aAAhC;AACD;AACF,KAPkC,CAOjClpB,IAPiC,CAO5B,IAP4B,CAAnC,CAfiC,CAwBjC;;;AACA,SAAK9T,KAAL,GAAa,KAAK0xB,YAAlB;AAEA,SAAKtxB,MAAL,GAAc,KAAKsH,YAAL,CAAkBxH,UAAlB,EAAd,CA3BiC,CA6BjC;;AACA,SAAKkP,MAAL,GAAc,CAAd;AACA,SAAK0tB,OAAL,GAAe,CAAf;AACA,SAAKC,SAAL,GAAiB,CAAC,CAAD,EAAI,CAAJ,CAAjB;AACA,SAAKC,aAAL,GAAqB,CAAC,CAAD,EAAI,CAAJ,CAArB;AAEA,SAAKH,SAAL,GAAiB,KAAjB;;AAEA,SAAKnL,YAAL,CAAkBnuB,OAAlB,CAA0B,KAAKnD,MAA/B;;AACA,SAAKA,MAAL,CAAYgG,IAAZ,CAAiB3F,KAAjB,GAAyB,CAAzB,CAtCiC,CAwCjC;;AACA,SAAKL,MAAL,CAAYmD,OAAZ,CAAoB,KAAKmE,YAAL,CAAkB9D,WAAtC,EAzCiC,CA2CjC;;AACA0E,WAAO,CAACL,KAAR,CAAc1E,OAAd,CAAsB,KAAKmuB,YAA3B,EA5CiC,CA8CjC;;AACAppB,WAAO,CAACH,UAAR,CAAmBvF,IAAnB,CAAwB,IAAxB;AACD,GAhDD;AAkDA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAoCA2F,IAAE,CAACi0B,SAAH,CAAal8B,SAAb,CAAuB6oB,QAAvB,GAAkC,UAASqP,MAAT,EAAiBiE,SAAjB,EAA4B;AAE5Dn0B,WAAO,CAACL,KAAR,CAAc3E,UAAd;;AAEA,QAAIm5B,SAAJ,EAAe;AACb,WAAK/K,YAAL,CAAkBuL,UAAlB,CAA6Bn7B,GAA7B,CAAiC,WAAjC,EAA8CrB,KAA9C,GAAsDg8B,SAAtD;AACD,KAN2D,CAQ5D;;;AACA,QAAIjE,MAAM,IAAI,IAAd,EAAoB;AAClB/wB,aAAO,CAACpB,GAAR,CAAY,0EAAZ;AACAiC,aAAO,CAACL,KAAR,CAAc1E,OAAd,CAAsB,KAAKmuB,YAA3B;AACD,KAHD,CAKA;AALA,SAMK,IAAI8G,MAAM,YAAYjwB,EAAE,CAAC7G,MAAzB,EAAiC;AACpC82B,cAAM,CAACp4B,MAAP,CAAcmD,OAAd,CAAsB,KAAKmuB,YAA3B;AACD,OAFI,CAGL;AAHK,WAIA,IAAI8G,MAAJ,EAAY;AACfA,gBAAM,CAACj1B,OAAP,CAAe,KAAKmuB,YAApB;;AACA,eAAKA,YAAL,CAAkBpuB,UAAlB;;AACA,eAAKouB,YAAL,CAAkBnuB,OAAlB,CAA0B,KAAKnD,MAA/B;AACD,SAJI,CAML;AANK,aAOA;AACHkI,mBAAO,CAACL,KAAR,CAAc1E,OAAd,CAAsB,KAAKmuB,YAA3B;AACD;AACF,GA7BD;;AA+BAnpB,IAAE,CAACi0B,SAAH,CAAal8B,SAAb,CAAuBiD,OAAvB,GAAiC,UAASC,IAAT,EAAe;AAC9C,QAAIA,IAAJ,EAAU;AACR,UAAIA,IAAI,CAAC4D,cAAL,CAAoB,OAApB,CAAJ,EAAkC;AAChC,aAAKhH,MAAL,CAAYmD,OAAZ,CAAoBC,IAAI,CAACxD,KAAzB;AACD,OAFD,MAEO;AACL,aAAKI,MAAL,CAAYmD,OAAZ,CAAoBC,IAApB;AACD;AACF,KAND,MAMO;AACL,WAAKpD,MAAL,CAAYmD,OAAZ,CAAoB,KAAK0gB,MAAL,CAAY1gB,OAAZ,CAAoB+E,OAAO,CAACtI,KAA5B,CAApB;AACD;AACF,GAVD;;AAYAuI,IAAE,CAACi0B,SAAH,CAAal8B,SAAb,CAAuBgD,UAAvB,GAAoC,YAAW;AAC7C,QAAI,KAAKlD,MAAT,EAAiB;AACf,WAAKA,MAAL,CAAYkD,UAAZ;AACD;AACF,GAJD;AAMA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA6BAiF,IAAE,CAACi0B,SAAH,CAAal8B,SAAb,CAAuBu2B,QAAvB,GAAkC,UAASO,OAAT,EAAkB;AAClD,QAAI,OAAOA,OAAP,KAAmB,WAAvB,EAAoC;AAClC,UAAI,KAAKyF,SAAT,EAAoB;AAClB,eAAO,KAAKG,aAAL,CAAmB5F,OAAnB,CAAP;AACD,OAFD,MAEO;AACL,eAAO,KAAK2F,SAAL,CAAe3F,OAAf,CAAP;AACD;AACF,KAND,MAOK,IAAI,KAAKyF,SAAT,EAAoB;AACvB,aAAO,KAAKC,OAAZ;AACD,KAFI,MAGA;AACH,aAAO,KAAK1tB,MAAZ;AACD;AACF,GAdD;AAgBA;;;;;;;;;;;;;;;;AAcA7G,IAAE,CAACi0B,SAAH,CAAal8B,SAAb,CAAuB48B,eAAvB,GAAyC,UAASnI,IAAT,EAAe;AACtD,QAAI,OAAOA,IAAP,KAAgB,SAApB,EAA+B;AAC7B,WAAK8H,SAAL,GAAiB9H,IAAjB;AACD,KAFD,MAGK;AACH,WAAK8H,SAAL,GAAiB,CAAC,KAAKA,SAAvB;AACD;;AACD,SAAKnL,YAAL,CAAkBgG,IAAlB,CAAuBpiB,WAAvB,CAAmC;AAAEtD,UAAI,EAAE,iBAAR;AAA2B6qB,eAAS,EAAE,KAAKA;AAA3C,KAAnC;AACD,GARD;AAUA;;;;;;;;;;AAQAt0B,IAAE,CAACi0B,SAAH,CAAal8B,SAAb,CAAuB68B,MAAvB,GAAgC,UAAS/c,CAAT,EAAY;AAC1C,QAAIA,CAAC,IAAI,CAAL,IAAUA,CAAC,GAAG,CAAlB,EAAqB;AACnB,WAAKsR,YAAL,CAAkBgG,IAAlB,CAAuBpiB,WAAvB,CAAmC;AAAEtD,YAAI,EAAE,WAAR;AAAqByqB,iBAAS,EAAErc;AAAhC,OAAnC;AACD,KAFD,MAEO;AACL3Y,aAAO,CAACpB,GAAR,CAAY,0CAAZ;AACD;AACF,GAND;;AAQAkC,IAAE,CAACi0B,SAAH,CAAal8B,SAAb,CAAuB8C,OAAvB,GAAiC,YAAW;AAC1C;AACA,QAAIsH,KAAK,GAAGpC,OAAO,CAACH,UAAR,CAAmBlH,OAAnB,CAA2B,IAA3B,CAAZ;AACAqH,WAAO,CAACH,UAAR,CAAmB7G,MAAnB,CAA0BoJ,KAA1B,EAAiC,CAAjC;;AAEA,QAAI,KAAK1K,KAAT,EAAgB;AACd,WAAKA,KAAL,CAAWsD,UAAX;AACA,aAAO,KAAKtD,KAAZ;AACD;;AACD,QAAI,KAAKI,MAAT,EAAiB;AACf,WAAKA,MAAL,CAAYkD,UAAZ;AACA,aAAO,KAAKlD,MAAZ;AACD;;AAED,SAAKsxB,YAAL,CAAkBpuB,UAAlB;;AACA,WAAO,KAAKouB,YAAZ;AACD,GAhBD;AAkBD,CA1RK;AAAA,oGAAN,C;;;;;;;ACFA,kCAAa;;AAEbhyB,mCAAO,UAASoK,OAAT,EAAkB;AACvB,MAAIxB,OAAO,GAAGwB,mBAAO,CAAC,CAAD,CAArB;AAEA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAsFAvB,IAAE,CAAC60B,GAAH,GAAS,UAASX,SAAT,EAAoBY,IAApB,EAA0B;AACjC,SAAKr9B,KAAL,GAAa,KAAKs9B,QAAL,GAAgBh1B,OAAO,CAACZ,YAAR,CAAqB61B,cAArB,EAA7B;AAEA/6B,UAAM,CAACwnB,gBAAP,CAAwB,IAAxB,EAA8B;AAC5BqT,UAAI,EAAE;AACJv7B,WAAG,EAAE,eAAW;AACd,iBAAO,KAAKw7B,QAAL,CAAcE,OAAd,GAAwB,CAA/B;AACD,SAHG;AAIJj9B,WAAG,EAAE,aAAS8J,CAAT,EAAY;AACf,eAAKizB,QAAL,CAAcE,OAAd,GAAwBnzB,CAAC,GAAG,CAA5B;AACD,SANG;AAOJozB,oBAAY,EAAE,IAPV;AAQJr4B,kBAAU,EAAE;AARR,OADsB;AAW5Bq3B,eAAS,EAAE;AACT36B,WAAG,EAAE,eAAW;AACd,iBAAO,KAAKw7B,QAAL,CAAcI,qBAArB;AACD,SAHQ;AAITn9B,WAAG,EAAE,aAAS6f,CAAT,EAAY;AACf,eAAKkd,QAAL,CAAcI,qBAAd,GAAsCtd,CAAtC;AACD,SANQ;AAOTqd,oBAAY,EAAE,IAPL;AAQTr4B,kBAAU,EAAE;AARH;AAXiB,KAA9B,EAHiC,CA0BjC;;AACA,SAAK+3B,MAAL,CAAYV,SAAZ;AACA,SAAKY,IAAL,GAAYA,IAAI,IAAI,IAApB,CA5BiC,CA8BjC;;AACA/0B,WAAO,CAACJ,QAAR,CAAiB3E,OAAjB,CAAyB,KAAK+5B,QAA9B;AAEA,SAAKK,UAAL,GAAkB,IAAIC,UAAJ,CAAe,KAAKN,QAAL,CAAcO,iBAA7B,CAAlB;AACA,SAAKC,UAAL,GAAkB,IAAIF,UAAJ,CAAe,KAAKN,QAAL,CAAcO,iBAA7B,CAAlB,CAlCiC,CAoCjC;;AACA,SAAKE,IAAL,GAAY,CAAC,EAAD,EAAK,GAAL,CAAZ;AACA,SAAKC,MAAL,GAAc,CAAC,GAAD,EAAM,GAAN,CAAd;AACA,SAAKC,GAAL,GAAW,CAAC,GAAD,EAAM,IAAN,CAAX;AACA,SAAKC,OAAL,GAAe,CAAC,IAAD,EAAO,IAAP,CAAf;AACA,SAAKC,MAAL,GAAc,CAAC,IAAD,EAAO,KAAP,CAAd,CAzCiC,CA2CjC;;AACA71B,WAAO,CAACH,UAAR,CAAmBvF,IAAnB,CAAwB,IAAxB;AACD,GA7CD;AA+CA;;;;;;;;;;AAQA2F,IAAE,CAAC60B,GAAH,CAAO98B,SAAP,CAAiB6oB,QAAjB,GAA4B,UAASqP,MAAT,EAAiB;AAC3C,QAAI,CAACA,MAAL,EAAa;AACXlwB,aAAO,CAACJ,QAAR,CAAiB3E,OAAjB,CAAyB,KAAK+5B,QAA9B;AACD,KAFD,MAEO;AACL,UAAI9E,MAAM,CAACp4B,MAAX,EAAmB;AACjBo4B,cAAM,CAACp4B,MAAP,CAAcmD,OAAd,CAAsB,KAAK+5B,QAA3B;AACD,OAFD,MAEO,IAAI9E,MAAM,CAACj1B,OAAX,EAAoB;AACzBi1B,cAAM,CAACj1B,OAAP,CAAe,KAAK+5B,QAApB;AACD;;AACDh1B,aAAO,CAACJ,QAAR,CAAiB5E,UAAjB;AACD;AACF,GAXD;AAaA;;;;;;;;;;;;;;;;;;;AAiBAiF,IAAE,CAAC60B,GAAH,CAAO98B,SAAP,CAAiB89B,QAAjB,GAA4B,YAAW;AACrC,QAAIf,IAAJ,EAAUtL,IAAV,EAAgBsM,WAAhB;;AAEA,SAAK,IAAIj9B,CAAC,GAAG,CAAb,EAAgBA,CAAC,GAAG2C,SAAS,CAAC1C,MAA9B,EAAsCD,CAAC,EAAvC,EAA2C;AACzC,UAAI,OAAO2C,SAAS,CAAC3C,CAAD,CAAhB,KAAwB,QAA5B,EAAsC;AACpCi8B,YAAI,GAAGt5B,SAAS,CAAC3C,CAAD,CAAhB;AACA,aAAKk8B,QAAL,CAAcE,OAAd,GAAwBH,IAAI,GAAG,CAA/B;AACD;;AACD,UAAI,OAAOt5B,SAAS,CAAC3C,CAAD,CAAhB,KAAwB,QAA5B,EAAsC;AACpC2wB,YAAI,GAAGhuB,SAAS,CAAC3C,CAAD,CAAhB;AACD;AACF,KAXoC,CAarC;;;AACA,QAAI2wB,IAAI,IAAI,CAACxpB,EAAE,CAACjI,SAAH,CAAag+B,SAAb,EAAb,EAAuC;AACrCC,iBAAW,CAAC,IAAD,EAAO,KAAKT,UAAZ,CAAX;AACA,WAAKR,QAAL,CAAckB,sBAAd,CAAqC,KAAKV,UAA1C;AACA,aAAO,KAAKA,UAAZ;AACD,KAJD,MAIO;AACLW,eAAS,CAAC,IAAD,EAAO,KAAKX,UAAZ,CAAT;AACA,WAAKR,QAAL,CAAcoB,qBAAd,CAAoC,KAAKZ,UAAzC;AACA,UAAIO,WAAW,GAAG,IAAIl+B,KAAJ,EAAlB;;AACA,WAAK,IAAIgC,CAAC,GAAG,CAAb,EAAgBA,CAAC,GAAG,KAAK27B,UAAL,CAAgBz8B,MAApC,EAA4Cc,CAAC,EAA7C,EAAiD;AAC/C,YAAIw8B,MAAM,GAAGp2B,EAAE,CAACjI,SAAH,CAAa0b,GAAb,CAAiB,KAAK8hB,UAAL,CAAgB37B,CAAhB,CAAjB,EAAqC,CAArC,EAAwC,GAAxC,EAA6C,CAAC,CAA9C,EAAiD,CAAjD,CAAb;AACAk8B,mBAAW,CAACz7B,IAAZ,CAAiB+7B,MAAjB;AACD;;AACD,aAAON,WAAP;AACD;AACF,GA5BD;AA8BA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAqEA91B,IAAE,CAAC60B,GAAH,CAAO98B,SAAP,CAAiBs+B,OAAjB,GAA2B,YAAW;AACpC,QAAI7M,IAAJ;;AAEA,SAAK,IAAI3wB,CAAC,GAAG,CAAb,EAAgBA,CAAC,GAAG2C,SAAS,CAAC1C,MAA9B,EAAsCD,CAAC,EAAvC,EAA2C;AACzC,UAAI,OAAO2C,SAAS,CAAC3C,CAAD,CAAhB,KAAwB,QAA5B,EAAsC;AACpC,aAAKi8B,IAAL,GAAYt5B,SAAS,CAAC3C,CAAD,CAArB;AACA,aAAKk8B,QAAL,CAAcE,OAAd,GAAwB,KAAKH,IAAL,GAAY,CAApC;AACD;;AACD,UAAI,OAAOt5B,SAAS,CAAC3C,CAAD,CAAhB,KAAwB,QAA5B,EAAsC;AACpC2wB,YAAI,GAAGhuB,SAAS,CAAC3C,CAAD,CAAhB;AACD;AACF;;AAED,QAAI2wB,IAAI,IAAIA,IAAI,CAAChlB,WAAL,OAAuB,IAAnC,EAAyC;AACvC8xB,iBAAW,CAAC,IAAD,CAAX;AACA,WAAKvB,QAAL,CAAcwB,qBAAd,CAAoC,KAAKnB,UAAzC;AACA,aAAO,KAAKA,UAAZ;AACD,KAJD,MAIO;AACLoB,eAAS,CAAC,IAAD,EAAO,KAAKpB,UAAZ,CAAT;AACA,WAAKL,QAAL,CAAc0B,oBAAd,CAAmC,KAAKrB,UAAxC;AACA,UAAIU,WAAW,GAAGl+B,KAAK,CAAC2D,KAAN,CAAY,EAAZ,EAAgB,KAAK65B,UAArB,CAAlB;AAEA,aAAOU,WAAP;AACD;AACF,GAxBD;AA0BA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA6BA91B,IAAE,CAAC60B,GAAH,CAAO98B,SAAP,CAAiB2+B,SAAjB,GAA6B,UAASC,UAAT,EAAqBC,UAArB,EAAiC;AAC5D,QAAIC,OAAO,GAAG92B,OAAO,CAACZ,YAAR,CAAqBT,UAArB,GAAkC,CAAhD;;AAEA,QAAIi4B,UAAU,KAAK,MAAnB,EAA2B;AACzBA,gBAAU,GAAG,KAAKnB,IAAL,CAAU,CAAV,CAAb;AACAoB,gBAAU,GAAG,KAAKpB,IAAL,CAAU,CAAV,CAAb;AACD,KAHD,MAGO,IAAImB,UAAU,KAAK,QAAnB,EAA6B;AAClCA,gBAAU,GAAG,KAAKlB,MAAL,CAAY,CAAZ,CAAb;AACAmB,gBAAU,GAAG,KAAKnB,MAAL,CAAY,CAAZ,CAAb;AACD,KAHM,MAGA,IAAIkB,UAAU,KAAK,KAAnB,EAA0B;AAC/BA,gBAAU,GAAG,KAAKjB,GAAL,CAAS,CAAT,CAAb;AACAkB,gBAAU,GAAG,KAAKlB,GAAL,CAAS,CAAT,CAAb;AACD,KAHM,MAGA,IAAIiB,UAAU,KAAK,SAAnB,EAA8B;AACnCA,gBAAU,GAAG,KAAKhB,OAAL,CAAa,CAAb,CAAb;AACAiB,gBAAU,GAAG,KAAKjB,OAAL,CAAa,CAAb,CAAb;AACD,KAHM,MAGA,IAAIgB,UAAU,KAAK,QAAnB,EAA6B;AAClCA,gBAAU,GAAG,KAAKf,MAAL,CAAY,CAAZ,CAAb;AACAgB,gBAAU,GAAG,KAAKhB,MAAL,CAAY,CAAZ,CAAb;AACD;;AAED,QAAI,OAAOe,UAAP,KAAsB,QAA1B,EAAoC;AAClC,YAAM,+BAAN;AACD,KAFD,MAEO,IAAI,CAACC,UAAL,EAAiB;AACtB;AACA,UAAIz0B,KAAK,GAAG7E,IAAI,CAACkG,KAAL,CAAWmzB,UAAU,GAAGE,OAAb,GAAuB,KAAKzB,UAAL,CAAgBt8B,MAAlD,CAAZ;AACA,aAAO,KAAKs8B,UAAL,CAAgBjzB,KAAhB,CAAP;AACD,KAJM,MAIA,IAAIw0B,UAAU,IAAIC,UAAlB,EAA8B;AACnC;AACA;AACA,UAAID,UAAU,GAAGC,UAAjB,EAA6B;AAC3B,YAAIE,IAAI,GAAGF,UAAX;AACAA,kBAAU,GAAGD,UAAb;AACAA,kBAAU,GAAGG,IAAb;AACD;;AACD,UAAIC,QAAQ,GAAGz5B,IAAI,CAACkG,KAAL,CAAWmzB,UAAU,GAAGE,OAAb,GAAuB,KAAKzB,UAAL,CAAgBt8B,MAAlD,CAAf;AACA,UAAIk+B,SAAS,GAAG15B,IAAI,CAACkG,KAAL,CAAWozB,UAAU,GAAGC,OAAb,GAAuB,KAAKzB,UAAL,CAAgBt8B,MAAlD,CAAhB;AAEA,UAAIgf,KAAK,GAAG,CAAZ;AACA,UAAImf,cAAc,GAAG,CAArB,CAZmC,CAanC;;AACA,WAAK,IAAIp+B,CAAC,GAAGk+B,QAAb,EAAuBl+B,CAAC,IAAIm+B,SAA5B,EAAuCn+B,CAAC,EAAxC,EAA4C;AAC1Cif,aAAK,IAAI,KAAKsd,UAAL,CAAgBv8B,CAAhB,CAAT;AACAo+B,sBAAc,IAAI,CAAlB;AACD,OAjBkC,CAkBnC;;;AACA,UAAIC,QAAQ,GAAGpf,KAAK,GAAGmf,cAAvB;AACA,aAAOC,QAAP;AACD,KArBM,MAqBA;AACL,YAAM,+BAAN;AACD;AACF,GAlDD,CAxUuB,CA4XvB;;;AACAl3B,IAAE,CAAC60B,GAAH,CAAO98B,SAAP,CAAiBokB,OAAjB,GAA2B,UAASgb,KAAT,EAAgBC,KAAhB,EAAuB;AAChDl4B,WAAO,CAACpB,GAAR,CAAY,0DAAZ;AACA,QAAIu5B,CAAC,GAAG,KAAKX,SAAL,CAAeS,KAAf,EAAsBC,KAAtB,CAAR;AACA,WAAOC,CAAP;AACD,GAJD;AAMA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAkEAr3B,IAAE,CAAC60B,GAAH,CAAO98B,SAAP,CAAiBu/B,WAAjB,GAA+B,YAAW;AACxC,QAAIT,OAAO,GAAG92B,OAAO,CAACZ,YAAR,CAAqBT,UAArB,GAAkC,CAAhD;AACA,QAAI64B,cAAc,GAAG,CAArB;AACA,QAAIC,sBAAsB,GAAG,CAA7B;;AAEA,SAAK,IAAI3+B,CAAC,GAAG,CAAb,EAAgBA,CAAC,GAAG,KAAKu8B,UAAL,CAAgBt8B,MAApC,EAA4CD,CAAC,EAA7C,EAAiD;AAC/C0+B,oBAAc,IAAI1+B,CAAC,GAAG,KAAKu8B,UAAL,CAAgBv8B,CAAhB,CAAtB;AACA2+B,4BAAsB,IAAI,KAAKpC,UAAL,CAAgBv8B,CAAhB,CAA1B;AACD;;AAED,QAAI4+B,eAAe,GAAG,CAAtB;;AAEA,QAAID,sBAAsB,KAAK,CAA/B,EAAkC;AAChCC,qBAAe,GAAGF,cAAc,GAAGC,sBAAnC;AACD;;AAED,QAAIE,kBAAkB,GACpBD,eAAe,IAAIZ,OAAO,GAAG,KAAKzB,UAAL,CAAgBt8B,MAA9B,CADjB;AAEA,WAAO4+B,kBAAP;AACD,GAnBD;AAqBA;;;;;;;;;AAOA13B,IAAE,CAAC60B,GAAH,CAAO98B,SAAP,CAAiB68B,MAAjB,GAA0B,UAAS/c,CAAT,EAAY;AACpC,QAAI,OAAOA,CAAP,KAAa,WAAjB,EAA8B;AAC5B,WAAKqc,SAAL,GAAiBrc,CAAjB;AACD;;AACD,WAAO,KAAKqc,SAAZ;AACD,GALD;;AAOAl0B,IAAE,CAAC60B,GAAH,CAAO98B,SAAP,CAAiB8C,OAAjB,GAA2B,YAAW;AACpC;AACA,QAAIsH,KAAK,GAAGpC,OAAO,CAACH,UAAR,CAAmBlH,OAAnB,CAA2B,IAA3B,CAAZ;AACAqH,WAAO,CAACH,UAAR,CAAmB7G,MAAnB,CAA0BoJ,KAA1B,EAAiC,CAAjC;;AAEA,QAAI,KAAK4yB,QAAT,EAAmB;AACjB,WAAKA,QAAL,CAAch6B,UAAd;AACA,aAAO,KAAKg6B,QAAZ;AACD;AACF,GATD;AAWA;;;;;;;;;;;;;;AAYA/0B,IAAE,CAAC60B,GAAH,CAAO98B,SAAP,CAAiB4/B,WAAjB,GAA+B,UAASC,CAAT,EAAY;AACzC,QAAIA,CAAC,GAAGA,CAAC,IAAI,EAAb,CADyC,CACxB;;AAEjB,QAAIC,QAAQ,GAAG,KAAKzC,UAApB;AACA,QAAI0C,cAAc,GAAGD,QAAQ,CAAC/+B,MAA9B;AACA,QAAIi/B,YAAY,GAAGz6B,IAAI,CAACmU,KAAL,CAAWqmB,cAAc,GAAGF,CAA5B,CAAnB;AAEA,QAAII,cAAc,GAAG,IAAIpgC,KAAJ,CAAUggC,CAAV,CAArB,CAPyC,CAQzC;AACA;;AACA,QAAIK,UAAU,GAAG,CAAjB;;AAEA,SAAK,IAAIC,SAAS,GAAG,CAArB,EAAwBA,SAAS,GAAGJ,cAApC,EAAoDI,SAAS,EAA7D,EAAiE;AAC/DF,oBAAc,CAACC,UAAD,CAAd,GACED,cAAc,CAACC,UAAD,CAAd,KAA+B71B,SAA/B,GACI,CAAC41B,cAAc,CAACC,UAAD,CAAd,GAA6BJ,QAAQ,CAACK,SAAD,CAAtC,IAAqD,CADzD,GAEIL,QAAQ,CAACK,SAAD,CAHd,CAD+D,CAM/D;;AACA,UAAIA,SAAS,GAAGH,YAAZ,KAA6BA,YAAY,GAAG,CAAhD,EAAmD;AACjDE,kBAAU;AACX;AACF;;AAED,WAAOD,cAAP;AACD,GAzBD;AA2BA;;;;;;;;;;;;;;;AAaAh4B,IAAE,CAAC60B,GAAH,CAAO98B,SAAP,CAAiBogC,WAAjB,GAA+B,UAASC,WAAT,EAAsB;AACnD,QAAIvB,OAAO,GAAG92B,OAAO,CAACZ,YAAR,CAAqBT,UAArB,GAAkC,CAAhD;AACA,QAAIm5B,QAAQ,GAAG,KAAKzC,UAApB;AACA,QAAI0C,cAAc,GAAGD,QAAQ,CAAC/+B,MAA9B;AAEA,QAAIq/B,WAAW,GAAG,IAAIvgC,KAAJ,CAAUwgC,WAAW,CAACt/B,MAAtB,CAAlB,CALmD,CAMnD;AACA;;AACA,QAAIu/B,WAAW,GAAG,CAAlB;;AAEA,SAAK,IAAIH,SAAS,GAAG,CAArB,EAAwBA,SAAS,GAAGJ,cAApC,EAAoDI,SAAS,EAA7D,EAAiE;AAC/D,UAAII,kBAAkB,GAAGh7B,IAAI,CAACkG,KAAL,CACvB00B,SAAS,GAAGrB,OAAZ,GAAsB,KAAKzB,UAAL,CAAgBt8B,MADf,CAAzB,CAD+D,CAK/D;;AACA,UAAIw/B,kBAAkB,GAAGF,WAAW,CAACC,WAAD,CAAX,CAAyBE,EAAlD,EAAsD;AACpDF,mBAAW;AACZ;;AAEDF,iBAAW,CAACE,WAAD,CAAX,GACEF,WAAW,CAACE,WAAD,CAAX,KAA6Bj2B,SAA7B,GACI,CAAC+1B,WAAW,CAACE,WAAD,CAAX,GAA2BR,QAAQ,CAACK,SAAD,CAApC,IAAmD,CADvD,GAEIL,QAAQ,CAACK,SAAD,CAHd;AAID;;AAED,WAAOC,WAAP;AACD,GA3BD;AA6BA;;;;;;;;;;;;;;;;AAcAn4B,IAAE,CAAC60B,GAAH,CAAO98B,SAAP,CAAiBygC,cAAjB,GAAkC,UAASZ,CAAT,EAAYa,KAAZ,EAAmB;AACnD,QAAIb,CAAC,GAAGA,CAAC,IAAI,CAAb,CADmD,CACnC;;AAChB,QAAIa,KAAK,GAAGA,KAAK,IAAI,MAArB,CAFmD,CAEtB;;AAE7B,QAAIL,WAAW,GAAG,EAAlB;AACA,QAAIM,iBAAiB,GAAG;AACtBC,QAAE,EAAEF,KAAK,GAAGn7B,IAAI,CAACK,GAAL,CAAS,CAAT,EAAY,KAAK,IAAIi6B,CAAT,CAAZ,CADU;AAEtBgB,SAAG,EAAEH,KAFiB;AAGtBF,QAAE,EAAEE,KAAK,GAAGn7B,IAAI,CAACK,GAAL,CAAS,CAAT,EAAY,KAAK,IAAIi6B,CAAT,CAAZ;AAHU,KAAxB;AAKAQ,eAAW,CAAC/9B,IAAZ,CAAiBq+B,iBAAjB;AAEA,QAAI7B,OAAO,GAAG92B,OAAO,CAACZ,YAAR,CAAqBT,UAArB,GAAkC,CAAhD;;AACA,WAAOg6B,iBAAiB,CAACH,EAAlB,GAAuB1B,OAA9B,EAAuC;AACrC,UAAIgC,gBAAgB,GAAG,EAAvB;AACAA,sBAAgB,CAACF,EAAjB,GAAsBD,iBAAiB,CAACH,EAAxC;AACAM,sBAAgB,CAACD,GAAjB,GAAuBF,iBAAiB,CAACE,GAAlB,GAAwBt7B,IAAI,CAACK,GAAL,CAAS,CAAT,EAAY,IAAIi6B,CAAhB,CAA/C;AACAiB,sBAAgB,CAACN,EAAjB,GAAsBM,gBAAgB,CAACD,GAAjB,GAAuBt7B,IAAI,CAACK,GAAL,CAAS,CAAT,EAAY,KAAK,IAAIi6B,CAAT,CAAZ,CAA7C;AAEAQ,iBAAW,CAAC/9B,IAAZ,CAAiBw+B,gBAAjB;AACAH,uBAAiB,GAAGG,gBAApB;AACD;;AAED,WAAOT,WAAP;AACD,GAxBD,CAllBuB,CA4mBvB;;;AACA,MAAI9B,WAAW,GAAG,SAAdA,WAAc,CAASwC,GAAT,EAAc;AAC9B,QAAIA,GAAG,CAAC1D,UAAJ,YAA0BvyB,YAA1B,KAA2C,KAA/C,EAAsD;AACpDi2B,SAAG,CAAC1D,UAAJ,GAAiB,IAAIvyB,YAAJ,CAAiBi2B,GAAG,CAAC/D,QAAJ,CAAaO,iBAA9B,CAAjB;AACD;AACF,GAJD;;AAKA,MAAIkB,SAAS,GAAG,SAAZA,SAAY,CAASsC,GAAT,EAAc;AAC5B,QAAIA,GAAG,CAAC1D,UAAJ,YAA0BC,UAA1B,KAAyC,KAA7C,EAAoD;AAClDyD,SAAG,CAAC1D,UAAJ,GAAiB,IAAIC,UAAJ,CAAeyD,GAAG,CAAC/D,QAAJ,CAAaO,iBAA5B,CAAjB;AACD;AACF,GAJD;;AAKA,MAAIU,WAAW,GAAG,SAAdA,WAAc,CAAS8C,GAAT,EAAc;AAC9B,QAAIA,GAAG,CAACvD,UAAJ,YAA0B1yB,YAA1B,KAA2C,KAA/C,EAAsD;AACpDi2B,SAAG,CAACvD,UAAJ,GAAiB,IAAI1yB,YAAJ,CAAiBi2B,GAAG,CAAC/D,QAAJ,CAAaO,iBAA9B,CAAjB;AACD;AACF,GAJD;;AAKA,MAAIY,SAAS,GAAG,SAAZA,SAAY,CAAS4C,GAAT,EAAc;AAC5B,QAAIA,GAAG,CAACvD,UAAJ,YAA0BF,UAA1B,KAAyC,KAA7C,EAAoD;AAClDyD,SAAG,CAACvD,UAAJ,GAAiB,IAAIF,UAAJ,CAAeyD,GAAG,CAAC/D,QAAJ,CAAaO,iBAA5B,CAAjB;AACD;AACF,GAJD;AAKD,CAjoBK;AAAA,oGAAN,C;;;;;;;ACFA,kCAAa;;AAEbn+B,mCAAO,UAAUoK,OAAV,EAAmB;AAExB;AACA;AACA,MAAIpI,MAAM,GAAGoI,mBAAO,CAAC,CAAD,CAApB;;AACA,MAAI8F,GAAG,GAAG9F,mBAAO,CAAC,CAAD,CAAjB;;AACA,MAAI0Z,IAAI,GAAG1Z,mBAAO,CAAC,CAAD,CAAlB;;AACA,MAAImM,KAAK,GAAGnM,mBAAO,CAAC,EAAD,CAAnB;AAEA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAwCAvB,IAAE,CAAC7G,MAAH,GAAY,UAASjB,KAAT,EAAgB;AAC1B,QAAI2f,CAAC,GAAG,IAAI1e,MAAJ,CAAWjB,KAAX,CAAR,CAD0B,CAE1B;;AACA,WAAO2f,CAAP,CAH0B,CAGhB;AACX,GAJD;AAMA;;;;;;;;;;AAQA1e,QAAM,CAACpB,SAAP,CAAiBkK,IAAjB,GAAwB9I,MAAM,CAACpB,SAAP,CAAiByI,uBAAzC;AACAya,MAAI,CAACljB,SAAL,CAAekK,IAAf,GAAwB9I,MAAM,CAACpB,SAAP,CAAiBkK,IAAzC;AACAoF,KAAG,CAACtP,SAAJ,CAAckK,IAAd,GAAuB9I,MAAM,CAACpB,SAAP,CAAiBkK,IAAxC;AACAyL,OAAK,CAAC3V,SAAN,CAAgBkK,IAAhB,GAAyB9I,MAAM,CAACpB,SAAP,CAAiBkK,IAA1C;AAGA;;;;;;;;;AAQA9I,QAAM,CAACpB,SAAP,CAAiB6oB,QAAjB,GAA4B,UAASmY,MAAT,EAAiB;AAC3CA,UAAM,CAAC/9B,OAAP,CAAe,IAAf;AACD,GAFD;;AAGAigB,MAAI,CAACljB,SAAL,CAAe6oB,QAAf,GAA4BznB,MAAM,CAACpB,SAAP,CAAiB6oB,QAA7C;AACAvZ,KAAG,CAACtP,SAAJ,CAAc6oB,QAAd,GAA2BznB,MAAM,CAACpB,SAAP,CAAiB6oB,QAA5C;AACAlT,OAAK,CAAC3V,SAAN,CAAgB6oB,QAAhB,GAA6BznB,MAAM,CAACpB,SAAP,CAAiB6oB,QAA9C,CAlFwB,CAqFxB;;AAEA;;;;;;;;;;;;AAWAznB,QAAM,CAACpB,SAAP,CAAiBmX,GAAjB,GAAuB,UAAS+N,GAAT,EAAc;AACnC,QAAI/N,GAAG,GAAG,IAAI7H,GAAJ,CAAQ4V,GAAR,CAAV,CADmC,CAEnC;;AACA,SAAKjiB,OAAL,CAAakU,GAAb;AACA,WAAOA,GAAP;AACD,GALD;;AAMA+L,MAAI,CAACljB,SAAL,CAAemX,GAAf,GAAuB/V,MAAM,CAACpB,SAAP,CAAiBmX,GAAxC;AACA7H,KAAG,CAACtP,SAAJ,CAAcmX,GAAd,GAAsB/V,MAAM,CAACpB,SAAP,CAAiBmX,GAAvC;AACAxB,OAAK,CAAC3V,SAAN,CAAgBmX,GAAhB,GAAwB/V,MAAM,CAACpB,SAAP,CAAiBmX,GAAzC;AAEA;;;;;;;;;;;;AAWA/V,QAAM,CAACpB,SAAP,CAAiB0iB,IAAjB,GAAwB,UAASwC,GAAT,EAAc;AACpC,QAAIxC,IAAI,GAAG,IAAIQ,IAAJ,CAASgC,GAAT,CAAX,CADoC,CAEpC;;AACA,SAAKjiB,OAAL,CAAayf,IAAb;AACA,WAAOA,IAAP;AACD,GALD;;AAMAQ,MAAI,CAACljB,SAAL,CAAe0iB,IAAf,GAAwBthB,MAAM,CAACpB,SAAP,CAAiB0iB,IAAzC;AACApT,KAAG,CAACtP,SAAJ,CAAc0iB,IAAd,GAAuBthB,MAAM,CAACpB,SAAP,CAAiB0iB,IAAxC;AACA/M,OAAK,CAAC3V,SAAN,CAAgB0iB,IAAhB,GAAyBthB,MAAM,CAACpB,SAAP,CAAiB0iB,IAA1C;AAEA;;;;;;;;;;;;;;;;AAeAthB,QAAM,CAACpB,SAAP,CAAiBmlB,KAAjB,GAAyB,UAASC,KAAT,EAAgBC,KAAhB,EAAuBC,MAAvB,EAA+BC,MAA/B,EAAuC;AAC9D,QAAIC,SAAJ,EAAeC,SAAf;;AACA,QAAIhiB,SAAS,CAAC1C,MAAV,KAAqB,CAAzB,EAA4B;AAC1BykB,eAAS,GAAGvd,EAAE,CAACjI,SAAH,CAAa0b,GAAb,CAAiB4J,MAAjB,EAAyBF,KAAzB,EAAgCC,KAAhC,EAAuC,CAAvC,EAA0C,CAA1C,IAA+C,GAA3D;AACAI,eAAS,GAAGxd,EAAE,CAACjI,SAAH,CAAa0b,GAAb,CAAiB6J,MAAjB,EAAyBH,KAAzB,EAAgCC,KAAhC,EAAuC,CAAvC,EAA0C,CAA1C,IAA+C,GAA3D;AACD,KAHD,MAIK;AACHG,eAAS,GAAG/hB,SAAS,CAAC,CAAD,CAArB;AACAgiB,eAAS,GAAGhiB,SAAS,CAAC,CAAD,CAArB;AACD;;AACD,QAAI0hB,KAAK,GAAG,IAAIxP,KAAJ,CAAU6P,SAAV,EAAqBC,SAArB,CAAZ;AACA,SAAKxiB,OAAL,CAAakiB,KAAb;AACA,WAAOA,KAAP;AACD,GAbD;;AAcAjC,MAAI,CAACljB,SAAL,CAAemlB,KAAf,GAAyB/jB,MAAM,CAACpB,SAAP,CAAiBmlB,KAA1C;AACA7V,KAAG,CAACtP,SAAJ,CAAcmlB,KAAd,GAAwB/jB,MAAM,CAACpB,SAAP,CAAiBmlB,KAAzC;AACAxP,OAAK,CAAC3V,SAAN,CAAgBmlB,KAAhB,GAA0B/jB,MAAM,CAACpB,SAAP,CAAiBmlB,KAA3C;AAED,CAlKK;AAAA,oGAAN,C;;;;;;ACFA/lB,iGAAO,CAAC,sBAAgB,CAAE,uBAAoB,CAAC,mCAAE,SAAUC,GAe1DA,EAAKoQ,UAAY,SAASnL,EAAKyE,GAC9B,KAAIvJ,gBAAgBH,EAAKoQ,WAKxB,OAAO,IAAIpQ,EAAKoQ,UAAUnL,EAAKyE,GAH/B1J,EAAKyR,SAAStM,KAAKhF,KAAM8E,EAAKyE,IAOhC1J,EAAK+G,OAAO/G,EAAKoQ,UAAWpQ,EAAKyR,UAQjCzR,EAAKoQ,UAAUzP,UAAUqe,oBAAsBnc,OAAOmY,OAAOhb,EAAKyR,SAAS9Q,UAAUqe,qBAOrFhf,EAAKoQ,UAAUzP,UAAUqe,oBAAoB4iB,KAAO,CACnDnkB,OAAS,uBACTC,OAAS,SAAS5c,GACjB,OAAOX,KAAK0hC,gBAAgB/gC,KAS9Bd,EAAKoQ,UAAUzP,UAAUqe,oBAAoBzS,KAAO,CACnDkR,OAAS,sCACTC,OAAS,SAASokB,EAAO70B,GACxB,IACI80B,EADQC,EAAiBF,EAAM10B,eACe,IAAxB+S,SAASlT,GAAU,GAC7C,OAAO9M,KAAK0hC,gBAAgBE,KAS9B/hC,EAAKoQ,UAAUzP,UAAUqe,oBAAoBuB,GAAK,CAChD9C,OAAS,qDACTC,OAAS,SAASvR,EAAGqU,EAAGC,GACxB,IAAIC,EAAQ,EAUZ,OATIvU,GAAW,MAANA,IACRuU,GAASvgB,KAAKkf,cAAclf,KAAKqf,iBAAmBE,WAAWvT,KAE5DqU,GAAW,MAANA,IACRE,GAASvgB,KAAKkf,cAAcK,WAAWc,KAEpCC,GAAW,MAANA,IACRC,GAASvgB,KAAKkf,cAAcK,WAAWe,GAAK,IAEtCC,IAeT1gB,EAAKoQ,UAAUzP,UAAUshC,UAAY,SAASp7B,GAK7C,OAJA1G,KAAK4d,MAAQ,SAASC,EAAMnX,GAE3B,OADUmX,IACG7d,KAAKyG,yBAAyBC,IAC1CsN,KAAKhU,KAAMA,KAAK4d,MAAOlX,GAClB1G,MAWRH,EAAKoQ,UAAUzP,UAAUuhC,UAAY,SAAS7H,GAS7C,OARAl6B,KAAK4d,MAAQ,SAASC,EAAMqc,GAG3B,IAFA,IAAIp1B,EAAM+Y,IACN1b,EAAM,GACDb,EAAI,EAAGA,EAAI44B,EAAU34B,OAAQD,IACrCa,EAAIb,GAAKwD,EAAM9E,KAAKyG,yBAAyByzB,EAAU54B,IAExD,OAAOa,GACN6R,KAAKhU,KAAMA,KAAK4d,MAAOsc,GAClBl6B,MAaRH,EAAKoQ,UAAUzP,UAAUwhC,OAAS,WACjC,OAAOhiC,KAAKiiC,gBAAgBjiC,KAAKyR,YASlC5R,EAAKoQ,UAAUzP,UAAU0hC,OAAS,WACjC,IAAI1wB,EAAOxR,KAAKyR,UACZlL,EAAMR,KAAKQ,IAAIiL,EAAO3R,EAAKoQ,UAAUkyB,IAAMp8B,KAAKq8B,IAChDR,EAAa77B,KAAKkG,MAAM,GAAK1F,GAAO,GACpCuG,EAAS/G,KAAKmU,MAAM0nB,EAAW,IAKnC,OAJG90B,EAAS,IACX80B,IAAe,GAAK90B,GAENu1B,EAAiBT,EAAa,IAC3B90B,EAAO/J,YAO1BlD,EAAKoQ,UAAUzP,UAAU4Q,UAAY,WACpC,OAAO,EAAIpR,KAAKyR,WAOjB5R,EAAKoQ,UAAUzP,UAAU+Q,YAAc,WACtC,OAAOvR,KAAKyR,WAOb5R,EAAKoQ,UAAUzP,UAAUkR,QAAU,WAClC,IAAIuN,EAAcjf,KAAKkf,cAAc,GACjCC,EAAWnf,KAAKyR,UAAYwN,EAChC,OAAOlZ,KAAKmU,MAAMiF,EAAWtf,EAAK8R,UAAU6N,MAa7C3f,EAAKoQ,UAAUzP,UAAU2f,kBAAoB,SAAS3O,GACrD,OAAOA,GASR3R,EAAKoQ,UAAUzP,UAAUyf,cAAgB,SAASrO,GACjD,OAAO,GAAc,GAARA,GAAe/R,EAAK8R,UAAUkR,IAAIliB,MAAQd,EAAK8R,UAAU6N,OASvE3f,EAAKoQ,UAAUzP,UAAU0e,cAAgB,SAAS0D,GACjD,OAAO,EAAI/iB,EAAKyR,SAAS9Q,UAAU0e,cAAcla,KAAKhF,KAAM4iB,IAS7D/iB,EAAKoQ,UAAUzP,UAAUggB,gBAAkB,SAASsC,GACnD,OAAO,EAAIA,GAOZjjB,EAAKoQ,UAAUzP,UAAUmf,cAAgB,KAUzC,IAAIkiB,EAAmB,CACtBS,KAAS,EAAGC,IAAQ,EAAG9L,EAAM,EAAI+L,KAAO,EAAIC,GAAO,EACnDC,IAAQ,EAAIv8B,GAAO,EAAIilB,EAAM,EAAIuX,KAAO,EAAIC,GAAO,EACnDC,IAAQ,EAAIC,GAAO,EAAI7vB,EAAM,EAAI8vB,KAAO,EAAIC,GAAO,EACnDC,IAAQ,EAAIC,GAAO,EAAIp3B,EAAM,EAAIq3B,KAAO,EAAIC,GAAO,EACnDC,IAAQ,EAAIC,GAAO,EAAIC,EAAM,EAAIC,KAAO,EAAIC,GAAO,EACnDC,IAAQ,EAAIC,GAAO,EAAIr5B,EAAM,EAAIs5B,KAAO,GAAIC,GAAO,GACnDC,IAAQ,EAAIC,GAAO,GAAIx5B,EAAM,GAAIy5B,KAAO,GAAIC,GAAO,IAOhD5B,EAAmB,CAAC,IAAK,KAAM,IAAK,KAAM,IAAK,IAAK,KAAM,IAAK,KAAM,IAAK,KAAM,KAgCpF,OAxBAxiC,EAAKoQ,UAAUkyB,GAAK,IASpBtiC,EAAKoQ,UAAUzP,UAAUkhC,gBAAkB,SAASD,GACnD,OAAO5hC,EAAKoQ,UAAUkyB,GAAKp8B,KAAKK,IAAI,GAAIq7B,EAAO,IAAM,KAUtD5hC,EAAKoQ,UAAUzP,UAAUyhC,gBAAkB,SAAShnB,GACnD,OAAO,GAAK,GAAKlV,KAAKQ,IAAI0U,EAAYpb,EAAKoQ,UAAUkyB,IAAMp8B,KAAKq8B,KAG1DviC,EAAKoQ;AAAAA,qG;;;;;;AC5RbrQ,iGAAO,CAAC,sBAAgB,CAAE,uBAAgB,CAAC,mCAAE,SAAUC,GAyFtD,OA7EAA,EAAKqQ,cAAgB,SAASpL,EAAKyE,GAClC,KAAIvJ,gBAAgBH,EAAKqQ,eAKxB,OAAO,IAAIrQ,EAAKqQ,cAAcpL,EAAKyE,GAHnC1J,EAAKmQ,KAAKhL,KAAKhF,KAAM8E,EAAKyE,IAO5B1J,EAAK+G,OAAO/G,EAAKqQ,cAAerQ,EAAKmQ,MAIrCnQ,EAAKqQ,cAAc1P,UAAU4c,kBAAoB1a,OAAOmY,OAAOhb,EAAKmQ,KAAKxP,UAAU4c,mBAQnFvd,EAAKqQ,cAAc1P,UAAU4c,kBAAkBC,SAAW,CACzDC,OAAS,KACTC,OAAS,SAASC,GACjB,IAAIM,EAAc9d,KAAKkkC,gBAAgB1mB,KACnCkB,EAAW3Y,KAAKqU,KAAKva,EAAK8R,UAAUC,MAAQkM,GAChD,OAAO9d,KAAKigB,cAAcvB,EAAWZ,KAUvCje,EAAKqQ,cAAc1P,UAAU0jC,gBAAkB,SAASphB,GACvD,IACI3D,EAAW2D,EADG9iB,KAAKkf,cAAc,GAErC,OAAOnZ,KAAKkG,MAAMkT,EAAWtf,EAAK8R,UAAU6N,MAO7C3f,EAAKqQ,cAAc1P,UAAUiR,QAAU,WAEtC,OADUzR,KAAKkkC,gBAAgBlkC,KAAK4d,UACtB5d,KAAKmd,SAAWtd,EAAK8R,UAAUC,MAAQ,IAOtD/R,EAAKqQ,cAAc1P,UAAUkR,QAAU,WACtC,OAAO1R,KAAKyR,WAOb5R,EAAKqQ,cAAc1P,UAAU4Q,UAAY,WAExC,OADUpR,KAAK4d,SACD5d,KAAKmd,SAAWtd,EAAK8R,UAAUmR,QAAU,IAOxDjjB,EAAKqQ,cAAc1P,UAAU+Q,YAAc,WAC1C,OAAO,EAAEvR,KAAKoR,aAGRvR,EAAKqQ;AAAAA,qG;;;;;;;ACzFb,kCAAa;;AAEbtQ,mCAAO,UAAUoK,OAAV,EAAmB;AAExB,MAAIxB,OAAO,GAAGwB,mBAAO,CAAC,CAAD,CAArB;;AACA,MAAI8F,GAAG,GAAG9F,mBAAO,CAAC,CAAD,CAAjB;;AACA,MAAI0Z,IAAI,GAAG1Z,mBAAO,CAAC,CAAD,CAAlB;;AACA,MAAImM,KAAK,GAAGnM,mBAAO,CAAC,EAAD,CAAnB;;AACA,MAAI4M,cAAc,GAAG5M,mBAAO,CAAC,EAAD,CAA5B;AAEA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAoDAvB,IAAE,CAACwgB,QAAH,GAAc,UAASlP,EAAT,EAAaoqB,EAAb,EAAiBC,EAAjB,EAAqBC,EAArB,EAAyBC,EAAzB,EAA6BC,EAA7B,EAAiC;AAC7C;;;;AAIA,SAAKpa,KAAL,GAAapQ,EAAE,IAAI,GAAnB;AACA;;;;;AAIA,SAAKyqB,MAAL,GAAcL,EAAE,IAAI,CAApB;AACA;;;;;AAIA,SAAK/Z,KAAL,GAAaga,EAAE,IAAI,GAAnB;AACA;;;;;AAIA,SAAKK,MAAL,GAAcJ,EAAE,IAAI,CAApB;AACA;;;;;AAIA,SAAK/Z,KAAL,GAAaga,EAAE,IAAI,CAAnB;AACA;;;;;AAIA,SAAKI,MAAL,GAAcH,EAAE,IAAI,CAApB;AAEA,SAAKI,mBAAL,GAA2B,IAA3B;AAEA,SAAKC,kBAAL,GAA0B,IAA1B;AAGA,SAAKtkC,MAAL,GAAckI,OAAO,CAACZ,YAAR,CAAqBxH,UAArB,EAAd;AAEA,SAAKykC,OAAL,GAAe,IAAIjuB,cAAJ,EAAf;;AAEA,SAAKkuB,KAAL,GAzC6C,CAyC/B;;;AAEd,SAAKD,OAAL,CAAaphC,OAAb,CAAqB,KAAKnD,MAA1B,EA3C6C,CA2CV;;AAEnC,SAAK4jB,UAAL,GAAkB,IAAlB,CA7C6C,CA6CrB;AAExB;;AACA,SAAK7V,OAAL,GAAe,CAAC,KAAKw2B,OAAN,CAAf,CAhD6C,CAkD7C;;AACA,SAAKE,aAAL,GAAqB,KAArB,CAnD6C,CAqD7C;AACA;;AACA,SAAKC,aAAL,GAAqB,IAArB,CAvD6C,CAyD7C;;AACA,SAAKC,YAAL,GAAoB,KAApB,CA1D6C,CA6D7C;;AACAz8B,WAAO,CAACH,UAAR,CAAmBvF,IAAnB,CAAwB,IAAxB;AACD,GA/DD,CA5DwB,CA6HxB;AACA;;;AACA2F,IAAE,CAACwgB,QAAH,CAAYzoB,SAAZ,CAAsBskC,KAAtB,GAA8B,YAAY;AACxC,QAAIn+B,GAAG,GAAG6B,OAAO,CAACZ,YAAR,CAAqBkB,WAA/B;AACA,QAAI+Q,CAAC,GAAGlT,GAAR;AACA,SAAKk+B,OAAL,CAAa1sB,eAAb,CAA6B,OAA7B,EAAsC0B,CAAtC,EAAyC,IAAzC,EAHwC,CAIxC;;AACA,SAAKqrB,UAAL,CAAgB,KAAK/a,KAArB,EAA4B,KAAKC,KAAjC;AACD,GAND;AAQA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAkDA3hB,IAAE,CAACwgB,QAAH,CAAYzoB,SAAZ,CAAsBC,GAAtB,GAA4B,UAASsZ,EAAT,EAAaoqB,EAAb,EAAiBC,EAAjB,EAAqBC,EAArB,EAAyBC,EAAzB,EAA6BC,EAA7B,EAAiC;AAC3D,SAAKpa,KAAL,GAAapQ,EAAb;AACA,SAAKyqB,MAAL,GAAcL,EAAd;AACA,SAAK/Z,KAAL,GAAaga,EAAE,IAAI,CAAnB;AACA,SAAKK,MAAL,GAAcJ,EAAE,IAAI,CAApB;AACA,SAAK/Z,KAAL,GAAaga,EAAE,IAAI,CAAnB;AACA,SAAKI,MAAL,GAAcH,EAAE,IAAI,CAApB,CAN2D,CAQ3D;;AACA,SAAKW,UAAL,CAAgBnrB,EAAhB,EAAoBqqB,EAApB;AACD,GAVD;AAYA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAwDA37B,IAAE,CAACwgB,QAAH,CAAYzoB,SAAZ,CAAsB4oB,OAAtB,GAAgC,UAASe,KAAT,EAAgBC,KAAhB,EAAuBC,QAAvB,EAAiCC,KAAjC,EAAwC;AACtE,SAAKH,KAAL,GAAaA,KAAb;AACA,SAAKC,KAAL,GAAaA,KAAK,IAAI,CAAtB,CAFsE,CAItE;;AACA,SAAKC,QAAL,GAAgBA,QAAQ,IAAI,CAA5B;AACA,SAAKoa,MAAL,GAAc,OAAOpa,QAAP,KAAoB,WAApB,GAAkCA,QAAQ,IAAI,KAAKma,MAAL,GAAc,KAAKE,MAAvB,CAAR,GAAyC,KAAKA,MAAhF,GAAyF,CAAvG;AAEA,SAAKpa,KAAL,GAAaA,KAAK,IAAI,CAAtB,CARsE,CAUtE;;AACA,SAAK4a,UAAL,CAAgB/a,KAAhB,EAAuBC,KAAvB;AACD,GAZD;AAcA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA0CA3hB,IAAE,CAACwgB,QAAH,CAAYzoB,SAAZ,CAAsB0oB,QAAtB,GAAiC,UAASsb,MAAT,EAAiBE,MAAjB,EAAyB;AACxD,SAAKF,MAAL,GAAcA,MAAM,IAAI,CAAxB;AACA,SAAKE,MAAL,GAAcA,MAAM,IAAI,CAAxB,CAFwD,CAIxD;AAEA;AACA;AACA;AACA;AACA;AACA;AACD,GAZD,CArTwB,CAmUxB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;AACAj8B,IAAE,CAACwgB,QAAH,CAAYzoB,SAAZ,CAAsB0kC,UAAtB,GAAmC,UAASnrB,EAAT,EAAaqqB,EAAb,EAAiB;AAClD,SAAKe,eAAL,GAAuB,KAAKC,aAAL,CAAmBrrB,EAAnB,CAAvB;AACA,SAAKsrB,cAAL,GAAsB,KAAKD,aAAL,CAAmBhB,EAAnB,CAAtB;AAEA,QAAIkB,aAAa,GAAG,GAApB,CAJkD,CAKlD;;AACAA,iBAAa,GAAGv/B,IAAI,CAACQ,GAAL,CAAS,MAAM,KAAK6+B,aAAL,CAAmB,MAAM,KAAKT,mBAA9B,CAAf,CAAhB;AACA,SAAKY,aAAL,GAAqBxrB,EAAE,GAAG,KAAKqrB,aAAL,CAAmBE,aAAnB,CAA1B;AACAA,iBAAa,GAAGv/B,IAAI,CAACQ,GAAL,CAAS,MAAM,KAAKq+B,kBAApB,CAAhB;AACA,SAAKY,YAAL,GAAoBpB,EAAE,GAAG,KAAKgB,aAAL,CAAmBE,aAAnB,CAAzB;AACD,GAVD,CA9UwB,CA0VxB;;;AACA78B,IAAE,CAACwgB,QAAH,CAAYzoB,SAAZ,CAAsBilC,kBAAtB,GAA2C,UAASC,EAAT,EAAaC,EAAb,EAAiB;AAC1D;AACA,SAAKhB,mBAAL,GAA2B,KAAKS,aAAL,CAAmBM,EAAnB,CAA3B;AACA,SAAKd,kBAAL,GAA0B,KAAKQ,aAAL,CAAmBO,EAAnB,CAA1B;AACA,QAAIL,aAAa,GAAG,GAApB,CAJ0D,CAK1D;AACA;;AACAA,iBAAa,GAAGv/B,IAAI,CAACQ,GAAL,CAAS,MAAM,KAAK6+B,aAAL,CAAmB,MAAM,KAAKT,mBAA9B,CAAf,CAAhB;AACA,SAAKY,aAAL,GAAqB,KAAKJ,eAAL,GAAuB,KAAKC,aAAL,CAAmBE,aAAnB,CAA5C;AACAA,iBAAa,GAAGv/B,IAAI,CAACQ,GAAL,CAAS,MAAM,KAAKq+B,kBAApB,CAAhB;AACA,SAAKY,YAAL,GAAoB,KAAKH,cAAL,GAAsB,KAAKD,aAAL,CAAmBE,aAAnB,CAA1C;AACD,GAXD;AAcA;;;;;;;;;;;;;AAWA78B,IAAE,CAACwgB,QAAH,CAAYzoB,SAAZ,CAAsB6oB,QAAtB,GAAiC,YAAW;AAC1C,SAAK,IAAI/nB,CAAC,GAAG,CAAb,EAAgBA,CAAC,GAAC2C,SAAS,CAAC1C,MAA5B,EAAoCD,CAAC,EAArC,EAAyC;AACvC,WAAKmC,OAAL,CAAaQ,SAAS,CAAC3C,CAAD,CAAtB;AACD;AACF,GAJD;AAMA;;;;;;;;;;;AASAmH,IAAE,CAACwgB,QAAH,CAAYzoB,SAAZ,CAAsB2oB,MAAtB,GAA+B,UAASyc,KAAT,EAAgB;AAC7C,SAAKb,aAAL,GAAqBa,KAArB;AACD,GAFD,CAnYwB,CAuYxB;;;AACAn9B,IAAE,CAACwgB,QAAH,CAAYzoB,SAAZ,CAAsB4kC,aAAtB,GAAsC,UAASzkC,KAAT,EAAgB;AACpD,QAAIA,KAAK,IAAI,CAAb,EACA;AACEA,WAAK,GAAG,UAAR;AACD;;AACD,WAAOA,KAAP;AACD,GAND;AAQA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAmDA8H,IAAE,CAACwgB,QAAH,CAAYzoB,SAAZ,CAAsB8oB,IAAtB,GAA6B,UAAS5lB,IAAT,EAAe8lB,cAAf,EAA+BC,OAA/B,EAAwC;AACnE,QAAI5gB,QAAQ,GAAG2gB,cAAc,IAAI,CAAjC;AACA,QAAIC,OAAO,GAAGA,OAAO,IAAI,CAAzB;;AAEA,QAAI/lB,IAAJ,EAAU;AACR,UAAI,KAAKwgB,UAAL,KAAoBxgB,IAAxB,EAA8B;AAC5B,aAAKD,OAAL,CAAaC,IAAb;AACD;AACF;;AAED,SAAKgmB,aAAL,CAAmBhmB,IAAnB,EAAyBmF,QAAzB;AAEA,SAAK8gB,cAAL,CAAoBjmB,IAApB,EAA0BmF,QAAQ,GAAG,KAAKshB,KAAhB,GAAwB,KAAKC,KAA7B,GAAqCX,OAA/D;AAED,GAdD;AAgBA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA2DAhhB,IAAE,CAACwgB,QAAH,CAAYzoB,SAAZ,CAAsBkpB,aAAtB,GAAsC,UAAShmB,IAAT,EAAe8lB,cAAf,EAA+B;AACnE,QAAI7iB,GAAG,GAAI6B,OAAO,CAACZ,YAAR,CAAqBkB,WAAhC;AACA,QAAID,QAAQ,GAAG2gB,cAAc,IAAI,CAAjC;AACA,QAAI3P,CAAC,GAAGlT,GAAG,GAAGkC,QAAd;AACA,SAAKg9B,UAAL,GAAkBhsB,CAAlB;AACA,SAAKorB,YAAL,GAAoB,IAApB;;AAEA,QAAIvhC,IAAJ,EAAU;AACR,UAAI,KAAKwgB,UAAL,KAAoBxgB,IAAxB,EAA8B;AAC5B,aAAKD,OAAL,CAAaC,IAAb;AACD;AACF,KAXkE,CAanE;;;AACA,QAAIoiC,QAAQ,GAAG,KAAKjB,OAAL,CAAavtB,cAAb,CAA4BuC,CAA5B,CAAf;;AAEA,QAAI,KAAKkrB,aAAL,KAAuB,IAA3B,EACA;AACE,WAAKF,OAAL,CAAahtB,4BAAb,CAA0C,KAAKutB,aAAL,CAAmBU,QAAnB,CAA1C,EAAwEjsB,CAAxE;AACD,KAHD,MAKA;AACE,WAAKgrB,OAAL,CAAa57B,uBAAb,CAAqC68B,QAArC,EAA+CjsB,CAA/C;AACD,KAvBkE,CAyBnE;AACA;AACA;AACA;AAEA;;;AACAA,KAAC,IAAI,KAAKsQ,KAAV;;AACA,QAAI,KAAK4a,aAAL,KAAuB,IAA3B,EACA;AACE,WAAKF,OAAL,CAAahtB,4BAAb,CAA0C,KAAKutB,aAAL,CAAmB,KAAKZ,MAAxB,CAA1C,EAA2E3qB,CAA3E;AACAisB,cAAQ,GAAG,KAAKV,aAAL,CAAmB,KAAKP,OAAL,CAAavtB,cAAb,CAA4BuC,CAA5B,CAAnB,CAAX;AACA,WAAKgrB,OAAL,CAAa77B,qBAAb,CAAmC6Q,CAAnC;AACA,WAAKgrB,OAAL,CAAahtB,4BAAb,CAA0CiuB,QAA1C,EAAoDjsB,CAApD;AACD,KAND,MAQA;AACE,WAAKgrB,OAAL,CAAa57B,uBAAb,CAAqC,KAAKu7B,MAA1C,EAAkD3qB,CAAlD;AACAisB,cAAQ,GAAG,KAAKjB,OAAL,CAAavtB,cAAb,CAA4BuC,CAA5B,CAAX;AACA,WAAKgrB,OAAL,CAAa77B,qBAAb,CAAmC6Q,CAAnC;AACA,WAAKgrB,OAAL,CAAa57B,uBAAb,CAAqC68B,QAArC,EAA+CjsB,CAA/C;AAED,KA9CkE,CAgDnE;;;AACAA,KAAC,IAAI,KAAKuQ,KAAV;;AACA,QAAI,KAAK2a,aAAL,KAAuB,IAA3B,EACA;AACE,WAAKF,OAAL,CAAahtB,4BAAb,CAA0C,KAAKutB,aAAL,CAAmB,KAAKX,MAAxB,CAA1C,EAA2E5qB,CAA3E;AACAisB,cAAQ,GAAG,KAAKV,aAAL,CAAmB,KAAKP,OAAL,CAAavtB,cAAb,CAA4BuC,CAA5B,CAAnB,CAAX;AACA,WAAKgrB,OAAL,CAAa77B,qBAAb,CAAmC6Q,CAAnC;AACA,WAAKgrB,OAAL,CAAahtB,4BAAb,CAA0CiuB,QAA1C,EAAoDjsB,CAApD;AACD,KAND,MAQA;AACE,WAAKgrB,OAAL,CAAa57B,uBAAb,CAAqC,KAAKw7B,MAA1C,EAAkD5qB,CAAlD;AACAisB,cAAQ,GAAG,KAAKjB,OAAL,CAAavtB,cAAb,CAA4BuC,CAA5B,CAAX;AACA,WAAKgrB,OAAL,CAAa77B,qBAAb,CAAmC6Q,CAAnC;AACA,WAAKgrB,OAAL,CAAa57B,uBAAb,CAAqC68B,QAArC,EAA+CjsB,CAA/C;AACD;AACF,GAhED;AAkEA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAwDApR,IAAE,CAACwgB,QAAH,CAAYzoB,SAAZ,CAAsBmpB,cAAtB,GAAuC,UAASjmB,IAAT,EAAe8lB,cAAf,EAA+B;AAEpE;AACA,QAAI,CAAC,KAAKyb,YAAV,EAAwB;AACtB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACD;;AAED,QAAIt+B,GAAG,GAAI6B,OAAO,CAACZ,YAAR,CAAqBkB,WAAhC;AACA,QAAID,QAAQ,GAAG2gB,cAAc,IAAI,CAAjC;AACA,QAAI3P,CAAC,GAAGlT,GAAG,GAAGkC,QAAd;;AAEA,QAAInF,IAAJ,EAAU;AACR,UAAI,KAAKwgB,UAAL,KAAoBxgB,IAAxB,EAA8B;AAC5B,aAAKD,OAAL,CAAaC,IAAb;AACD;AACF,KAtBmE,CAwBpE;;;AACA,QAAIoiC,QAAQ,GAAG,KAAKjB,OAAL,CAAavtB,cAAb,CAA4BuC,CAA5B,CAAf;;AACA,QAAI,KAAKkrB,aAAL,KAAuB,IAA3B,EACA;AACE,WAAKF,OAAL,CAAahtB,4BAAb,CAA0C,KAAKutB,aAAL,CAAmBU,QAAnB,CAA1C,EAAwEjsB,CAAxE;AACD,KAHD,MAKA;AACE,WAAKgrB,OAAL,CAAa57B,uBAAb,CAAqC68B,QAArC,EAA+CjsB,CAA/C;AACD,KAjCmE,CAmCpE;;;AACAA,KAAC,IAAI,KAAKyQ,KAAV;;AAEA,QAAI,KAAKya,aAAL,KAAuB,IAA3B,EACA;AACE,WAAKF,OAAL,CAAahtB,4BAAb,CAA0C,KAAKutB,aAAL,CAAmB,KAAKV,MAAxB,CAA1C,EAA2E7qB,CAA3E;AACAisB,cAAQ,GAAG,KAAKV,aAAL,CAAmB,KAAKP,OAAL,CAAavtB,cAAb,CAA4BuC,CAA5B,CAAnB,CAAX;AACA,WAAKgrB,OAAL,CAAa77B,qBAAb,CAAmC6Q,CAAnC;AACA,WAAKgrB,OAAL,CAAahtB,4BAAb,CAA0CiuB,QAA1C,EAAoDjsB,CAApD;AACD,KAND,MAQA;AACE,WAAKgrB,OAAL,CAAa57B,uBAAb,CAAqC,KAAKy7B,MAA1C,EAAkD7qB,CAAlD;AACAisB,cAAQ,GAAG,KAAKjB,OAAL,CAAavtB,cAAb,CAA4BuC,CAA5B,CAAX;AACA,WAAKgrB,OAAL,CAAa77B,qBAAb,CAAmC6Q,CAAnC;AACA,WAAKgrB,OAAL,CAAa57B,uBAAb,CAAqC68B,QAArC,EAA+CjsB,CAA/C;AACD;;AAED,SAAKorB,YAAL,GAAoB,KAApB;AACD,GAtDD;AAwDA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAqDAx8B,IAAE,CAACwgB,QAAH,CAAYzoB,SAAZ,CAAsBqpB,IAAtB,GAA6B,UAASnmB,IAAT,EAAe8lB,cAAf,EAA+B5P,EAA/B,EAAmCmsB,EAAnC,EAAuC;AAElE,QAAIp/B,GAAG,GAAI6B,OAAO,CAACZ,YAAR,CAAqBkB,WAAhC;AACA,QAAID,QAAQ,GAAG2gB,cAAc,IAAI,CAAjC;AACA,QAAI3P,CAAC,GAAGlT,GAAG,GAAGkC,QAAd;AACA,QAAIm9B,YAAY,GAAG,KAAKZ,aAAL,CAAmBxrB,EAAnB,CAAnB;AACA,QAAIqsB,YAAY,GAAG,OAAOF,EAAP,KAAc,WAAd,GAA4B,KAAKX,aAAL,CAAmBW,EAAnB,CAA5B,GAAqDl7B,SAAxE,CANkE,CAQlE;;AACA,QAAInH,IAAJ,EAAU;AACR,UAAI,KAAKwgB,UAAL,KAAoBxgB,IAAxB,EAA8B;AAC5B,aAAKD,OAAL,CAAaC,IAAb;AACD;AACF,KAbiE,CAelE;;;AACA,QAAI6f,UAAU,GAAG,KAAK6hB,aAAL,CAAmB,KAAKP,OAAL,CAAavtB,cAAb,CAA4BuC,CAA5B,CAAnB,CAAjB,CAhBkE,CAiBlE;AAEA;;AACA,QAAImsB,YAAY,GAAGziB,UAAnB,EAA+B;AAC7B,WAAKshB,OAAL,CAAa1sB,eAAb,CAA6B6tB,YAA7B,EAA2CnsB,CAA3C,EAA8C,KAAK0rB,aAAnD;AACA1rB,OAAC,IAAI,KAAKsrB,eAAV;AACD,KAHD,CAKA;AALA,SAMK,IAAIa,YAAY,GAAGziB,UAAnB,EAA+B;AAClC,aAAKshB,OAAL,CAAa1sB,eAAb,CAA6B6tB,YAA7B,EAA2CnsB,CAA3C,EAA8C,KAAK2rB,YAAnD;AACA3rB,SAAC,IAAI,KAAKwrB,cAAV;AACD,OA7BiE,CA+BlE;;;AACA,QAAIY,YAAY,KAAKp7B,SAArB,EAAgC,OAhCkC,CAkClE;;AACA,QAAIo7B,YAAY,GAAGD,YAAnB,EAAiC;AAC/B,WAAKnB,OAAL,CAAa1sB,eAAb,CAA6B8tB,YAA7B,EAA2CpsB,CAA3C,EAA8C,KAAK0rB,aAAnD;AACD,KAFD,CAIA;AAJA,SAKK,IAAIU,YAAY,GAAGD,YAAnB,EAAiC;AACpC,aAAKnB,OAAL,CAAa1sB,eAAb,CAA6B8tB,YAA7B,EAA2CpsB,CAA3C,EAA8C,KAAK2rB,YAAnD;AACD;AACF,GA3CD;;AA8CA/8B,IAAE,CAACwgB,QAAH,CAAYzoB,SAAZ,CAAsBiD,OAAtB,GAAgC,UAASC,IAAT,EAAe;AAC7C,SAAKwgB,UAAL,GAAkBxgB,IAAlB,CAD6C,CAG7C;AACA;;AACA,QAAIA,IAAI,YAAY+E,EAAE,CAACkb,UAAnB,IACAjgB,IAAI,YAAY+E,EAAE,CAACioB,SADnB,IAEAhtB,IAAI,YAAY+E,EAAE,CAACy9B,OAFnB,IAGAxiC,IAAI,YAAY+E,EAAE,CAAC09B,MAHnB,IAIAziC,IAAI,YAAY+E,EAAE,CAAC29B,KAJnB,IAKA1iC,IAAI,YAAY+E,EAAE,CAAC8R,MALnB,IAMA7W,IAAI,YAAY+E,EAAE,CAAC49B,KANvB,EAOE;AACA3iC,UAAI,GAAGA,IAAI,CAACpD,MAAL,CAAYgG,IAAnB;AACD;;AACD,QAAI5C,IAAI,YAAY3B,UAApB,EAAgC;AAC9B;AACA2B,UAAI,CAAC+T,cAAL,CAAoB,CAApB,EAAuBjP,OAAO,CAACZ,YAAR,CAAqBkB,WAA5C;AACD;;AACD,QAAIpF,IAAI,YAAY+E,EAAE,CAAC7G,MAAvB,EAA+B;AAC7B8B,UAAI,CAACuU,QAAL,CAAc,CAAd;AACD;;AACD,SAAK3X,MAAL,CAAYmD,OAAZ,CAAoBC,IAApB;AACD,GAvBD;;AAyBA+E,IAAE,CAACwgB,QAAH,CAAYzoB,SAAZ,CAAsBgD,UAAtB,GAAmC,YAAW;AAC5C,QAAI,KAAKlD,MAAT,EAAiB;AACf,WAAKA,MAAL,CAAYkD,UAAZ;AACD;AACF,GAJD,CA5zBwB,CAm0BxB;;AAEA;;;;;;;;;;;;;AAWAiF,IAAE,CAACwgB,QAAH,CAAYzoB,SAAZ,CAAsBmX,GAAtB,GAA4B,UAAS+N,GAAT,EAAc;AACxC,QAAI/N,GAAG,GAAG,IAAI7H,GAAJ,CAAQ4V,GAAR,CAAV;AACA,QAAIxX,SAAS,GAAG,KAAKG,OAAL,CAAa9M,MAA7B;AACA,QAAI4M,SAAS,GAAG,KAAK7N,MAArB;AACA,WAAOmI,EAAE,CAACjI,SAAH,CAAauN,UAAb,CAAwB,IAAxB,EAA8B4J,GAA9B,EAAmCzJ,SAAnC,EAA8CC,SAA9C,EAAyD2B,GAAzD,CAAP;AACD,GALD;AAOA;;;;;;;;;;;;;AAWArH,IAAE,CAACwgB,QAAH,CAAYzoB,SAAZ,CAAsB0iB,IAAtB,GAA6B,UAASwC,GAAT,EAAc;AACzC,QAAIxC,IAAI,GAAG,IAAIQ,IAAJ,CAASgC,GAAT,CAAX;AACA,QAAIxX,SAAS,GAAG,KAAKG,OAAL,CAAa9M,MAA7B;AACA,QAAI4M,SAAS,GAAG,KAAK7N,MAArB;AACA,WAAOmI,EAAE,CAACjI,SAAH,CAAauN,UAAb,CAAwB,IAAxB,EAA8BmV,IAA9B,EAAoChV,SAApC,EAA+CC,SAA/C,EAA0DuV,IAA1D,CAAP;AACD,GALD;AAOA;;;;;;;;;;;;;;;;AAcAjb,IAAE,CAACwgB,QAAH,CAAYzoB,SAAZ,CAAsBmlB,KAAtB,GAA8B,UAASC,KAAT,EAAgBC,KAAhB,EAAuBC,MAAvB,EAA+BC,MAA/B,EAAuC;AACnE,QAAIJ,KAAK,GAAG,IAAIxP,KAAJ,CAAUyP,KAAV,EAAiBC,KAAjB,EAAwBC,MAAxB,EAAgCC,MAAhC,CAAZ;AACA,QAAI7X,SAAS,GAAG,KAAKG,OAAL,CAAa9M,MAA7B;AACA,QAAI4M,SAAS,GAAG,KAAK7N,MAArB;AACA,WAAOmI,EAAE,CAACjI,SAAH,CAAauN,UAAb,CAAwB,IAAxB,EAA8B4X,KAA9B,EAAqCzX,SAArC,EAAgDC,SAAhD,EAA2DgI,KAA3D,CAAP;AACD,GALD,CAv3BwB,CA+3BxB;;;AACA1N,IAAE,CAACwgB,QAAH,CAAYzoB,SAAZ,CAAsB8C,OAAtB,GAAgC,YAAW;AACzC;AACA,QAAIsH,KAAK,GAAGpC,OAAO,CAACH,UAAR,CAAmBlH,OAAnB,CAA2B,IAA3B,CAAZ;AACAqH,WAAO,CAACH,UAAR,CAAmB7G,MAAnB,CAA0BoJ,KAA1B,EAAiC,CAAjC;AAEA,SAAKpH,UAAL;;AACA,QAAI,KAAKqhC,OAAT,EAAkB;AAChB,WAAKA,OAAL,CAAavhC,OAAb;AACA,WAAKuhC,OAAL,GAAe,IAAf;AACD;;AACD,SAAK,IAAIvjC,CAAC,GAAG,CAAb,EAAgBA,CAAC,GAAG,KAAK+M,OAAL,CAAa9M,MAAjC,EAAyCD,CAAC,EAA1C,EAA8C;AAC5C,WAAK+M,OAAL,CAAa/M,CAAb,EAAgBgC,OAAhB;AACD;AACF,GAbD,CAh4BwB,CA+4BxB;;;AACAmF,IAAE,CAAC69B,GAAH,GAAS,UAASvsB,EAAT,EAAaoqB,EAAb,EAAiBC,EAAjB,EAAqBC,EAArB,EAAyBC,EAAzB,EAA6BC,EAA7B,EAAiC;AACxC58B,WAAO,CAACkO,IAAR,CAAa,8EACX,yCADF;AAEApN,MAAE,CAACwgB,QAAH,CAAYjkB,IAAZ,CAAiB,IAAjB,EAAuB+U,EAAvB,EAA2BoqB,EAA3B,EAA+BC,EAA/B,EAAmCC,EAAnC,EAAuCC,EAAvC,EAA2CC,EAA3C;AACD,GAJD;;AAKA97B,IAAE,CAAC69B,GAAH,CAAO9lC,SAAP,GAAmBkC,MAAM,CAACmY,MAAP,CAAcpS,EAAE,CAACwgB,QAAH,CAAYzoB,SAA1B,CAAnB;AAED,CAv5BK;AAAA,oGAAN,C;;;;;;;ACFA,kCAAa;;AAEbZ,mCAAO,UAAUoK,OAAV,EAAmB;AAExB,MAAIxB,OAAO,GAAGwB,mBAAO,CAAC,CAAD,CAArB;;AACAA,qBAAO,CAAC,EAAD,CAAP;AAEA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAmCAvB,IAAE,CAAC89B,KAAH,GAAW,UAAS/0B,IAAT,EAAeg1B,CAAf,EAAkB;AAC3B/9B,MAAE,CAACkb,UAAH,CAAc3e,IAAd,CAAmB,IAAnB,EAAyBwM,IAAzB,EAA+B,UAA/B,EAD2B,CAG3B;;AACA,SAAKg1B,CAAL,GAASA,CAAC,IAAI,CAAd,CAJ2B,CAM3B;;AACA,SAAKthB,IAAL,GAAY,IAAIzc,EAAE,CAAC2d,MAAP,CAAc5U,IAAd,CAAZ,CAP2B,CAS3B;;AACA,SAAK4T,KAAL,GAAa5c,OAAO,CAACZ,YAAR,CAAqByd,WAArB,EAAb,CAV2B,CAY3B;;AACA,SAAKohB,QAAL,GAAgBC,cAAc,EAA9B;AACA,SAAKC,MAAL,GAAcn+B,OAAO,CAACZ,YAAR,CAAqBxH,UAArB,EAAd;AACA,SAAKqmC,QAAL,CAAchjC,OAAd,CAAsB,KAAKkjC,MAA3B;AACA,SAAKA,MAAL,CAAYljC,OAAZ,CAAoB,KAAKnD,MAAzB,EAhB2B,CAiB3B;;AACA,SAAKwL,CAAL,GAAS0F,IAAI,IAAI,GAAjB;AACA,QAAIo1B,EAAE,GAAG,KAAKJ,CAAL,GAAS,KAAK1iB,UAAL,CAAgB7I,SAAhB,CAA0Bta,KAA5C;AACA,SAAKykB,KAAL,CAAWE,SAAX,CAAqB3kB,KAArB,GAA6BimC,EAA7B;AACA,SAAKD,MAAL,CAAYrgC,IAAZ,CAAiB3F,KAAjB,GAAyB,OAAK,MAAI,KAAK6lC,CAAd,CAAzB,CArB2B,CAuB3B;;AACA,SAAKthB,IAAL,CAAU1hB,UAAV;AACA,SAAK0hB,IAAL,CAAUf,MAAV,CAAiB3gB,UAAjB;AACA,SAAK0hB,IAAL,CAAU1a,GAAV,CAAc,CAAC,CAAf,EA1B2B,CA0BR;;AACnB,SAAK0a,IAAL,CAAU5kB,MAAV,CAAiBmD,OAAjB,CAAyB,KAAK2hB,KAA9B;AACA,SAAKA,KAAL,CAAW3hB,OAAX,CAAmB,KAAKnD,MAAxB;AAEA,SAAKA,MAAL,CAAYgG,IAAZ,CAAiB3F,KAAjB,GAAyB,CAAzB;AACA,SAAKL,MAAL,CAAYmD,OAAZ,CAAoB,KAAK0gB,MAAzB;AACD,GAhCD;;AAkCA1b,IAAE,CAAC89B,KAAH,CAAS/lC,SAAT,GAAqBkC,MAAM,CAACmY,MAAP,CAAcpS,EAAE,CAACkb,UAAH,CAAcnjB,SAA5B,CAArB;AAEA;;;;;;;;;AAQAiI,IAAE,CAAC89B,KAAH,CAAS/lC,SAAT,CAAmB61B,KAAnB,GAA2B,UAASmQ,CAAT,EAAY;AACrC,QAAI,OAAOA,CAAP,KAAa,QAAjB,EAA2B;AACzB,UAAIA,CAAC,IAAI,GAAL,IAAYA,CAAC,IAAI,GAArB,EAA0B;AACxB,aAAKA,CAAL,GAASA,CAAT,CADwB,CAExB;AAEA;;AACA,YAAII,EAAE,GAAG,KAAKJ,CAAL,GAAS,KAAK1iB,UAAL,CAAgB7I,SAAhB,CAA0Bta,KAA5C;AACA,aAAKykB,KAAL,CAAWE,SAAX,CAAqB3kB,KAArB,GAA6BimC,EAA7B;AACD;;AAED,WAAKD,MAAL,CAAYrgC,IAAZ,CAAiB3F,KAAjB,GAAyB,OAAK,MAAI,KAAK6lC,CAAd,CAAzB;AACD,KAXD,MAWO;AACLA,OAAC,CAAC/iC,OAAF,CAAU,KAAK2hB,KAAL,CAAWE,SAArB;AACA,UAAIuhB,GAAG,GAAG,IAAIp+B,EAAE,CAACq+B,SAAP,CAAiB,CAAC,GAAlB,CAAV;AACAD,SAAG,CAACxd,QAAJ,CAAamd,CAAb;AACAK,SAAG,GAAGA,GAAG,CAAC3jB,IAAJ,CAAS,CAAC,CAAV,CAAN;AACA2jB,SAAG,GAAGA,GAAG,CAAC3jB,IAAJ,CAAS,GAAT,CAAN;AACA2jB,SAAG,CAACpjC,OAAJ,CAAY,KAAKkjC,MAAL,CAAYrgC,IAAxB;AACD;AACF,GApBD;;AAsBAmC,IAAE,CAAC89B,KAAH,CAAS/lC,SAAT,CAAmB6U,KAAnB,GAA2B,UAASvJ,CAAT,EAAYuF,IAAZ,EAAkB;AAC3C,QAAI1K,GAAG,GAAG6B,OAAO,CAACZ,YAAR,CAAqBkB,WAA/B;AACA,QAAI+Q,CAAC,GAAGxI,IAAI,IAAI,CAAhB;;AACA,QAAI,CAAC,KAAKuS,OAAV,EAAmB;AACjB,UAAIpS,IAAI,GAAG1F,CAAC,IAAI,KAAKA,CAArB;AACA,UAAIsC,IAAI,GAAG,KAAK0V,UAAL,CAAgB1V,IAA3B;AACA,WAAK0V,UAAL,GAAkBtb,OAAO,CAACZ,YAAR,CAAqBmc,gBAArB,EAAlB;AACA,WAAKD,UAAL,CAAgB7I,SAAhB,CAA0BxD,cAA1B,CAAyCjG,IAAzC,EAA+C7K,GAA/C;AACA,WAAKmd,UAAL,CAAgB1V,IAAhB,GAAuBA,IAAvB;AACA,WAAK0V,UAAL,CAAgBrgB,OAAhB,CAAwB,KAAKnD,MAA7B;AACA,WAAKwjB,UAAL,CAAgBzO,KAAhB,CAAsBwE,CAAC,GAAGlT,GAA1B,EAPiB,CASjB;;AACA,WAAKue,IAAL,CAAUpB,UAAV,GAAuBtb,OAAO,CAACZ,YAAR,CAAqBmc,gBAArB,EAAvB;AACA,WAAKmB,IAAL,CAAUpB,UAAV,CAAqB7I,SAArB,CAA+BxD,cAA/B,CAA8CjG,IAA9C,EAAoDqI,CAAC,GAAGlT,GAAxD;AACA,WAAKue,IAAL,CAAUpB,UAAV,CAAqB1V,IAArB,GAA4BA,IAA5B;AACA,WAAK8W,IAAL,CAAUpB,UAAV,CAAqBrgB,OAArB,CAA6B,KAAKyhB,IAAL,CAAU5kB,MAAvC;AACA,WAAK4kB,IAAL,CAAU7P,KAAV,CAAgBwE,CAAC,GAAGlT,GAApB;AACA,WAAK4d,QAAL,GAAgB,CAAC,KAAKT,UAAL,CAAgB7I,SAAjB,EAA4B,KAAKiK,IAAL,CAAUpB,UAAV,CAAqB7I,SAAjD,CAAhB,CAfiB,CAiBjB;;AACA,WAAKwrB,QAAL,GAAgBC,cAAc,EAA9B;AACA,WAAKD,QAAL,CAAchjC,OAAd,CAAsB,KAAKkjC,MAA3B;AACA,WAAKF,QAAL,CAAcpxB,KAAd,CAAoBwE,CAAC,GAAGlT,GAAxB,EApBiB,CAsBjB;;AACA,UAAI,KAAKogC,IAAL,KAAcl8B,SAAd,IAA2B,KAAKk8B,IAAL,CAAU9rB,SAAV,KAAwBpQ,SAAvD,EAAkE;AAChE,aAAKk8B,IAAL,CAAU9rB,SAAV,CAAoBxX,OAApB,CAA4B,KAAK8gB,QAAL,CAAc,CAAd,CAA5B;AACA,aAAKwiB,IAAL,CAAU9rB,SAAV,CAAoBxX,OAApB,CAA4B,KAAK8gB,QAAL,CAAc,CAAd,CAA5B;AACD;;AACD,WAAKX,OAAL,GAAe,IAAf;AACA,WAAKsB,IAAL,CAAUtB,OAAV,GAAoB,IAApB;AACD;AACF,GAjCD;;AAmCAnb,IAAE,CAAC89B,KAAH,CAAS/lC,SAAT,CAAmB6jB,IAAnB,GAA0B,UAAShT,IAAT,EAAe;AACvC,QAAI,KAAKuS,OAAT,EAAkB;AAChB,UAAI/J,CAAC,GAAGxI,IAAI,IAAI,CAAhB;AACA,UAAI1K,GAAG,GAAG6B,OAAO,CAACZ,YAAR,CAAqBkB,WAA/B;AACA,WAAKgb,UAAL,CAAgBO,IAAhB,CAAqBxK,CAAC,GAAGlT,GAAzB;;AACA,UAAI,KAAKue,IAAL,CAAUpB,UAAd,EAA0B;AACxB,aAAKoB,IAAL,CAAUpB,UAAV,CAAqBO,IAArB,CAA0BxK,CAAC,GAAGlT,GAA9B;AACD;;AACD,WAAK8/B,QAAL,CAAcpiB,IAAd,CAAmBxK,CAAC,GAAGlT,GAAvB;AACA,WAAKid,OAAL,GAAe,KAAf;AACA,WAAKsB,IAAL,CAAUtB,OAAV,GAAoB,KAApB;AACD;AACF,GAZD;;AAcAnb,IAAE,CAAC89B,KAAH,CAAS/lC,SAAT,CAAmBgR,IAAnB,GAA0B,UAAS1M,GAAT,EAAclE,QAAd,EAAwBiI,QAAxB,EAAkC;AAC1D,QAAI,OAAO/D,GAAP,KAAe,QAAnB,EAA6B;AAC3B,WAAKgH,CAAL,GAAShH,GAAT;AACA,UAAI6B,GAAG,GAAG6B,OAAO,CAACZ,YAAR,CAAqBkB,WAA/B;AACA,UAAIlI,QAAQ,GAAGA,QAAQ,IAAI,CAA3B;AACA,UAAIiI,QAAQ,GAAGA,QAAQ,IAAI,CAA3B;AACA,UAAIm+B,WAAW,GAAG,KAAKljB,UAAL,CAAgB7I,SAAhB,CAA0Bta,KAA5C;AACA,WAAKmjB,UAAL,CAAgB7I,SAAhB,CAA0BjS,qBAA1B,CAAgDrC,GAAhD;AACA,WAAKmd,UAAL,CAAgB7I,SAAhB,CAA0BxD,cAA1B,CAAyCuvB,WAAzC,EAAsDrgC,GAAG,GAAGkC,QAA5D;AACA,WAAKib,UAAL,CAAgB7I,SAAhB,CAA0BpD,4BAA1B,CAAuD/S,GAAvD,EAA4D+D,QAAQ,GAAGjI,QAAX,GAAsB+F,GAAlF;AACA,WAAKue,IAAL,CAAUpB,UAAV,CAAqB7I,SAArB,CAA+BjS,qBAA/B,CAAqDrC,GAArD;AACA,WAAKue,IAAL,CAAUpB,UAAV,CAAqB7I,SAArB,CAA+BxD,cAA/B,CAA8CuvB,WAA9C,EAA2DrgC,GAAG,GAAGkC,QAAjE;AACA,WAAKqc,IAAL,CAAUpB,UAAV,CAAqB7I,SAArB,CAA+BpD,4BAA/B,CAA4D/S,GAA5D,EAAiE+D,QAAQ,GAAGjI,QAAX,GAAsB+F,GAAvF;;AAEA,UAAI,KAAKsgC,OAAT,EAAkB;AAChB,aAAKA,OAAL,CAAa3mC,MAAb,CAAoBkD,UAApB;AACA,aAAKyjC,OAAL,GAAe,IAAf;AACD;AAEF,KAlBD,MAkBO,IAAIniC,GAAG,CAACxE,MAAR,EAAgB;AACrBwE,SAAG,CAACxE,MAAJ,CAAWkD,UAAX;AACAsB,SAAG,CAACxE,MAAJ,CAAWmD,OAAX,CAAmB,KAAKqgB,UAAL,CAAgB7I,SAAnC;AACAnW,SAAG,CAACxE,MAAJ,CAAWmD,OAAX,CAAmB,KAAKyhB,IAAL,CAAUpB,UAAV,CAAqB7I,SAAxC;AACA,WAAKgsB,OAAL,GAAeniC,GAAf;AACD;AACF,GAzBD,CA3JwB,CAsLxB;;;AACA,WAAS4hC,cAAT,GAA0B;AACxB,QAAIv8B,EAAE,GAAG3B,OAAO,CAACZ,YAAjB;AACA,QAAIkH,MAAM,GAAC3E,EAAE,CAAC2K,YAAH,CAAgB,CAAhB,EAAkB,IAAlB,EAAuB3K,EAAE,CAAChD,UAA1B,CAAX;AACA,QAAI2wB,IAAI,GAAGhpB,MAAM,CAACJ,cAAP,CAAsB,CAAtB,CAAX;;AACA,SAAK,IAAIpN,CAAC,GAAC,CAAX,EAAcA,CAAC,GAAC,IAAhB,EAAsBA,CAAC,EAAvB;AACEw2B,UAAI,CAACx2B,CAAD,CAAJ,GAAQ,GAAR;AADF;;AAEA,QAAI4lC,YAAY,GAAC/8B,EAAE,CAAC8K,kBAAH,EAAjB;AACAiyB,gBAAY,CAACp4B,MAAb,GAAoBA,MAApB;AACAo4B,gBAAY,CAAC9xB,IAAb,GAAkB,IAAlB;AACA,WAAO8xB,YAAP;AACD;AAEF,CAnMK;AAAA,oGAAN,C;;;;;;;ACFA,kCAAa;;AAEbtnC,mCAAO,UAAUoK,OAAV,EAAmB;AACxB,MAAIxB,OAAO,GAAGwB,mBAAO,CAAC,CAAD,CAArB;AAEA;;;;;;;;;;;AASAvB,IAAE,CAAC29B,KAAH,GAAW,UAASh4B,IAAT,EAAe;AACxB,QAAI+4B,UAAJ;AACA1+B,MAAE,CAACkb,UAAH,CAAc3e,IAAd,CAAmB,IAAnB;AACA,WAAO,KAAK8G,CAAZ;AACA,WAAO,KAAK0F,IAAZ;AACA,WAAO,KAAKsS,UAAZ;;AAEA,QAAI1V,IAAI,KAAK,OAAb,EAAsB;AACpB+4B,gBAAU,GAAGC,WAAb;AACD,KAFD,MAEO,IAAIh5B,IAAI,KAAK,MAAb,EAAqB;AAC1B+4B,gBAAU,GAAGE,UAAb;AACD,KAFM,MAEA;AACLF,gBAAU,GAAGG,WAAb;AACD;;AACD,SAAKx4B,MAAL,GAAcq4B,UAAd;AACD,GAfD;;AAiBA1+B,IAAE,CAAC29B,KAAH,CAAS5lC,SAAT,GAAqBkC,MAAM,CAACmY,MAAP,CAAcpS,EAAE,CAACkb,UAAH,CAAcnjB,SAA5B,CAArB,CA7BwB,CA+BxB;;AACA,MAAI8mC,WAAW,GAAI,YAAW;AAC5B,QAAI1K,UAAU,GAAG,IAAIp0B,OAAO,CAACZ,YAAR,CAAqBT,UAA1C;AACA,QAAIogC,WAAW,GAAG/+B,OAAO,CAACZ,YAAR,CAAqBkN,YAArB,CAAkC,CAAlC,EAAqC8nB,UAArC,EAAiDp0B,OAAO,CAACZ,YAAR,CAAqBT,UAAtE,CAAlB;AACA,QAAIqgC,SAAS,GAAGD,WAAW,CAAC74B,cAAZ,CAA2B,CAA3B,CAAhB;;AACA,SAAK,IAAIpN,CAAC,GAAG,CAAb,EAAgBA,CAAC,GAAGs7B,UAApB,EAAgCt7B,CAAC,EAAjC,EAAqC;AACnCkmC,eAAS,CAAClmC,CAAD,CAAT,GAAeyE,IAAI,CAAC0hC,MAAL,KAAgB,CAAhB,GAAoB,CAAnC;AACD;;AACDF,eAAW,CAACn5B,IAAZ,GAAmB,OAAnB;AACA,WAAOm5B,WAAP;AACD,GATiB,EAAlB;;AAWA,MAAIF,UAAU,GAAI,YAAW;AAC3B,QAAIzK,UAAU,GAAG,IAAIp0B,OAAO,CAACZ,YAAR,CAAqBT,UAA1C;AACA,QAAIugC,UAAU,GAAGl/B,OAAO,CAACZ,YAAR,CAAqBkN,YAArB,CAAkC,CAAlC,EAAqC8nB,UAArC,EAAiDp0B,OAAO,CAACZ,YAAR,CAAqBT,UAAtE,CAAjB;AACA,QAAIqgC,SAAS,GAAGE,UAAU,CAACh5B,cAAX,CAA0B,CAA1B,CAAhB;AACA,QAAIi5B,EAAJ,EAAQC,EAAR,EAAYC,EAAZ,EAAgBC,EAAhB,EAAoBC,EAApB,EAAwBC,EAAxB,EAA4BC,EAA5B;AACAN,MAAE,GAAGC,EAAE,GAAGC,EAAE,GAAGC,EAAE,GAAGC,EAAE,GAAGC,EAAE,GAAGC,EAAE,GAAG,GAAnC;;AACA,SAAK,IAAI3mC,CAAC,GAAG,CAAb,EAAgBA,CAAC,GAAGs7B,UAApB,EAAgCt7B,CAAC,EAAjC,EAAqC;AACnC,UAAI4mC,KAAK,GAAGniC,IAAI,CAAC0hC,MAAL,KAAgB,CAAhB,GAAoB,CAAhC;AACAE,QAAE,GAAG,UAAUA,EAAV,GAAeO,KAAK,GAAG,SAA5B;AACAN,QAAE,GAAG,UAAUA,EAAV,GAAeM,KAAK,GAAG,SAA5B;AACAL,QAAE,GAAG,UAAUA,EAAV,GAAeK,KAAK,GAAG,SAA5B;AACAJ,QAAE,GAAG,UAAUA,EAAV,GAAeI,KAAK,GAAG,SAA5B;AACAH,QAAE,GAAG,UAAUA,EAAV,GAAeG,KAAK,GAAG,SAA5B;AACAF,QAAE,GAAG,CAAC,MAAD,GAAUA,EAAV,GAAeE,KAAK,GAAG,SAA5B;AACAV,eAAS,CAAClmC,CAAD,CAAT,GAAeqmC,EAAE,GAAGC,EAAL,GAAUC,EAAV,GAAeC,EAAf,GAAoBC,EAApB,GAAyBC,EAAzB,GAA8BC,EAA9B,GAAmCC,KAAK,GAAG,MAA1D;AACAV,eAAS,CAAClmC,CAAD,CAAT,IAAgB,IAAhB,CATmC,CASb;;AACtB2mC,QAAE,GAAGC,KAAK,GAAG,QAAb;AACD;;AACDR,cAAU,CAACt5B,IAAX,GAAkB,MAAlB;AACA,WAAOs5B,UAAP;AACD,GApBgB,EAAjB;;AAsBA,MAAIN,WAAW,GAAI,YAAW;AAC5B,QAAIxK,UAAU,GAAG,IAAIp0B,OAAO,CAACZ,YAAR,CAAqBT,UAA1C;AACA,QAAIghC,WAAW,GAAG3/B,OAAO,CAACZ,YAAR,CAAqBkN,YAArB,CAAkC,CAAlC,EAAqC8nB,UAArC,EAAiDp0B,OAAO,CAACZ,YAAR,CAAqBT,UAAtE,CAAlB;AACA,QAAIqgC,SAAS,GAAGW,WAAW,CAACz5B,cAAZ,CAA2B,CAA3B,CAAhB;AACA,QAAI05B,OAAO,GAAG,GAAd;;AACA,SAAK,IAAI9mC,CAAC,GAAG,CAAb,EAAgBA,CAAC,GAAEs7B,UAAnB,EAA+Bt7B,CAAC,EAAhC,EAAoC;AAClC,UAAI4mC,KAAK,GAAGniC,IAAI,CAAC0hC,MAAL,KAAgB,CAAhB,GAAoB,CAAhC;AACAD,eAAS,CAAClmC,CAAD,CAAT,GAAe,CAAC8mC,OAAO,GAAG,OAAKF,KAAhB,IAAyB,IAAxC;AACAE,aAAO,GAAGZ,SAAS,CAAClmC,CAAD,CAAnB;AACAkmC,eAAS,CAAClmC,CAAD,CAAT,IAAgB,GAAhB;AACD;;AACD6mC,eAAW,CAAC/5B,IAAZ,GAAmB,OAAnB;AACA,WAAO+5B,WAAP;AACD,GAbiB,EAAlB;AAeA;;;;;;;;;AAOA1/B,IAAE,CAAC29B,KAAH,CAAS5lC,SAAT,CAAmBka,OAAnB,GAA6B,UAAStM,IAAT,EAAe;AAC1C,YAAOA,IAAP;AACE,WAAK,OAAL;AACE,aAAKU,MAAL,GAAcw4B,WAAd;AACA;;AACF,WAAK,MAAL;AACE,aAAKx4B,MAAL,GAAcu4B,UAAd;AACA;;AACF,WAAK,OAAL;AACE,aAAKv4B,MAAL,GAAcs4B,WAAd;AACA;;AACF;AACE,aAAKt4B,MAAL,GAAcw4B,WAAd;AAXJ;;AAaA,QAAI,KAAK1jB,OAAT,EAAkB;AAChB,UAAIjd,GAAG,GAAG6B,OAAO,CAACZ,YAAR,CAAqBkB,WAA/B;AACA,WAAKub,IAAL,CAAU1d,GAAV;AACA,WAAK0O,KAAL,CAAW1O,GAAG,GAAC,GAAf;AACD;AACF,GAnBD;;AAqBA8B,IAAE,CAAC29B,KAAH,CAAS5lC,SAAT,CAAmBqkB,OAAnB,GAA6B,YAAW;AACtC,WAAO,KAAK/V,MAAL,CAAYV,IAAnB;AACD,GAFD;;AAIA3F,IAAE,CAAC29B,KAAH,CAAS5lC,SAAT,CAAmB6U,KAAnB,GAA2B,YAAW;AACpC,QAAI,KAAKuO,OAAT,EAAkB;AAChB,WAAKS,IAAL;AACD;;AACD,SAAKgkB,KAAL,GAAa7/B,OAAO,CAACZ,YAAR,CAAqBqN,kBAArB,EAAb;AACA,SAAKozB,KAAL,CAAWv5B,MAAX,GAAoB,KAAKA,MAAzB;AACA,SAAKu5B,KAAL,CAAWjzB,IAAX,GAAkB,IAAlB;AACA,SAAKizB,KAAL,CAAW5kC,OAAX,CAAmB,KAAKnD,MAAxB;AACA,QAAIqG,GAAG,GAAG6B,OAAO,CAACZ,YAAR,CAAqBkB,WAA/B;AACA,SAAKu/B,KAAL,CAAWhzB,KAAX,CAAiB1O,GAAjB;AACA,SAAKid,OAAL,GAAe,IAAf;AACD,GAXD;;AAaAnb,IAAE,CAAC29B,KAAH,CAAS5lC,SAAT,CAAmB6jB,IAAnB,GAA0B,YAAW;AACnC,QAAI1d,GAAG,GAAG6B,OAAO,CAACZ,YAAR,CAAqBkB,WAA/B;;AACA,QAAI,KAAKu/B,KAAT,EAAgB;AACd,WAAKA,KAAL,CAAWhkB,IAAX,CAAgB1d,GAAhB;AACA,WAAKid,OAAL,GAAe,KAAf;AACD;AACF,GAND;;AAQAnb,IAAE,CAAC29B,KAAH,CAAS5lC,SAAT,CAAmB8C,OAAnB,GAA6B,YAAW;AACtC,QAAIqD,GAAG,GAAG6B,OAAO,CAACZ,YAAR,CAAqBkB,WAA/B,CADsC,CAGtC;;AACA,QAAI8B,KAAK,GAAGpC,OAAO,CAACH,UAAR,CAAmBlH,OAAnB,CAA2B,IAA3B,CAAZ;AACAqH,WAAO,CAACH,UAAR,CAAmB7G,MAAnB,CAA0BoJ,KAA1B,EAAiC,CAAjC;;AAEA,QAAI,KAAKy9B,KAAT,EAAgB;AACd,WAAKA,KAAL,CAAW7kC,UAAX;AACA,WAAK6gB,IAAL,CAAU1d,GAAV;AACD;;AACD,QAAI,KAAKrG,MAAT,EAAiB;AACf,WAAKA,MAAL,CAAYkD,UAAZ;AACD;;AACD,QAAI,KAAK2gB,MAAT,EAAiB;AACf,WAAKA,MAAL,CAAY3gB,UAAZ;AACD;;AACD,SAAKlD,MAAL,GAAc,IAAd;AACA,SAAK6jB,MAAL,GAAc,IAAd;AACA,SAAKrV,MAAL,GAAc,IAAd;AACA,SAAKu5B,KAAL,GAAa,IAAb;AACD,GArBD;AAuBD,CA5JK;AAAA,oGAAN,C;;;;;;;ACFA,kCAAa;;AAEbzoC,mCAAO,UAAUoK,OAAV,EAAmB;AACxB,MAAIxB,OAAO,GAAGwB,mBAAO,CAAC,CAAD,CAArB,CADwB,CAGxB;;;AACAxB,SAAO,CAAC8/B,YAAR,GAAuB,EAAvB;AAEA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAmCA7/B,IAAE,CAACy9B,OAAH,GAAa,UAAStT,aAAT,EAAwB;AACnC;;AACA;;;AAGA,SAAK1yB,KAAL,GAAasI,OAAO,CAACZ,YAAR,CAAqBxH,UAArB,EAAb;AACA;;;;AAGA,SAAKE,MAAL,GAAckI,OAAO,CAACZ,YAAR,CAAqBxH,UAArB,EAAd;AAEA;;;;AAGA,SAAKmoC,MAAL,GAAc,IAAd;AACA;;;;AAGA,SAAKC,WAAL,GAAmB,IAAnB;AACA;;;;AAGA,SAAKC,aAAL,GAAqB,IAArB;AAEA;;;;;;;AAMA,SAAKC,OAAL,GAAe,KAAf;AAEA;;;;;;AAKA,SAAK1O,SAAL,GAAiB,IAAIvxB,EAAE,CAACi0B,SAAP,EAAjB;AACA,SAAKp8B,MAAL,CAAYmD,OAAZ,CAAoB,KAAKu2B,SAAL,CAAe95B,KAAnC;;AAEA,QAAI,CAACmH,MAAM,CAACshC,gBAAR,IAA4B,CAACthC,MAAM,CAACwmB,SAAP,CAAiB+a,YAA9C,IAA8D,CAACvhC,MAAM,CAACwmB,SAAP,CAAiB+a,YAAjB,CAA8B9a,YAAjG,EAA+G;AAC7G8E,mBAAa,GAAGA,aAAa,EAAhB,GAAqBvrB,MAAM,CAACsrB,KAAP,CAAa,iEAAb,CAAlC;AACD,KA1CkC,CA4CnC;;;AACAnqB,WAAO,CAACH,UAAR,CAAmBvF,IAAnB,CAAwB,IAAxB;AACD,GA9CD;AAgDA;;;;;;;;;;;;;;;;;;;;;;AAoBA2F,IAAE,CAACy9B,OAAH,CAAW1lC,SAAX,CAAqB6U,KAArB,GAA6B,UAASwzB,eAAT,EAA0BjW,aAA1B,EAAyC;AACpE,QAAIpO,IAAI,GAAG,IAAX;;AAEA,QAAI,KAAK+jB,MAAT,EAAiB;AACf,WAAKlkB,IAAL;AACD,KALmE,CAOpE;;;AACA,QAAIykB,WAAW,GAAGtgC,OAAO,CAAC8/B,YAAR,CAAqB9jB,IAAI,CAACikB,aAA1B,CAAlB;AACA,QAAIM,WAAW,GAAG;AAChBC,WAAK,EAAE;AACL7hC,kBAAU,EAAEqB,OAAO,CAACZ,YAAR,CAAqBT,UAD5B;AAEL8hC,wBAAgB,EAAE;AAFb;AADS,KAAlB,CAToE,CAgBpE;;AACA,QAAIzgC,OAAO,CAAC8/B,YAAR,CAAqB,KAAKG,aAA1B,CAAJ,EAA8C;AAC5CM,iBAAW,CAACC,KAAZ,CAAkBE,QAAlB,GAA6BJ,WAAW,CAACI,QAAzC;AACD;;AAED7hC,UAAM,CAACwmB,SAAP,CAAiB+a,YAAjB,CAA8B9a,YAA9B,CAA4Cib,WAA5C,EACGvZ,IADH,CACS,UAAS+Y,MAAT,EAAiB;AACtB/jB,UAAI,CAAC+jB,MAAL,GAAcA,MAAd;AACA/jB,UAAI,CAACkkB,OAAL,GAAe,IAAf,CAFsB,CAGtB;;AACAlkB,UAAI,CAACgkB,WAAL,GAAmBhgC,OAAO,CAACZ,YAAR,CAAqBuhC,uBAArB,CAA6CZ,MAA7C,CAAnB;AACA/jB,UAAI,CAACgkB,WAAL,CAAiB/kC,OAAjB,CAAyB+gB,IAAI,CAAClkB,MAA9B,EALsB,CAMtB;;AACAkkB,UAAI,CAACwV,SAAL,CAAe3Q,QAAf,CAAwB7E,IAAI,CAAClkB,MAA7B;AACA,UAAIuoC,eAAJ,EAAqBA,eAAe;AACrC,KAVH,WAWU,UAASx2B,GAAT,EAAc;AACpB,UAAIugB,aAAJ,EAAmBA,aAAa,CAACvgB,GAAD,CAAb,CAAnB,KACK1K,OAAO,CAAC6rB,KAAR,CAAcnhB,GAAd;AACN,KAdH;AAeD,GApCD;AAsCA;;;;;;;;;AAOA5J,IAAE,CAACy9B,OAAH,CAAW1lC,SAAX,CAAqB6jB,IAArB,GAA4B,YAAW;AACrC,QAAI,KAAKkkB,MAAT,EAAiB;AACf,WAAKA,MAAL,CAAYa,SAAZ,GAAwB9hB,OAAxB,CAAgC,UAAS+hB,KAAT,EAAgB;AAC9CA,aAAK,CAAChlB,IAAN;AACD,OAFD;AAIA,WAAKmkB,WAAL,CAAiBhlC,UAAjB;AAEA,aAAO,KAAKglC,WAAZ;AACA,aAAO,KAAKD,MAAZ;AACD;AACF,GAXD;AAaA;;;;;;;;;;;AASA9/B,IAAE,CAACy9B,OAAH,CAAW1lC,SAAX,CAAqBiD,OAArB,GAA+B,UAASC,IAAT,EAAe;AAC5C,QAAIA,IAAJ,EAAU;AACR,UAAIA,IAAI,CAAC4D,cAAL,CAAoB,OAApB,CAAJ,EAAkC;AAChC,aAAKhH,MAAL,CAAYmD,OAAZ,CAAoBC,IAAI,CAACxD,KAAzB;AACD,OAFD,MAGK,IAAIwD,IAAI,CAAC4D,cAAL,CAAoB,UAApB,CAAJ,EAAqC;AACxC,aAAKhH,MAAL,CAAYmD,OAAZ,CAAoBC,IAAI,CAAC85B,QAAzB;AACD,OAFI,MAGA;AACH,aAAKl9B,MAAL,CAAYmD,OAAZ,CAAoBC,IAApB;AACD;AACF,KAVD,MAWK;AACH,WAAKpD,MAAL,CAAYmD,OAAZ,CAAoB+E,OAAO,CAACtI,KAA5B;AACD;AACF,GAfD;AAiBA;;;;;;;;;;AAQAuI,IAAE,CAACy9B,OAAH,CAAW1lC,SAAX,CAAqBgD,UAArB,GAAkC,YAAW;AAC3C,QAAI,KAAKlD,MAAT,EAAiB;AACf,WAAKA,MAAL,CAAYkD,UAAZ,GADe,CAEf;;AACA,WAAKlD,MAAL,CAAYmD,OAAZ,CAAoB,KAAKu2B,SAAL,CAAe95B,KAAnC;AACD;AACF,GAND;AAQA;;;;;;;;;;;;;;;AAaAuI,IAAE,CAACy9B,OAAH,CAAW1lC,SAAX,CAAqBu2B,QAArB,GAAgC,UAAS4F,SAAT,EAAoB;AAClD,QAAIA,SAAJ,EAAe;AACb,WAAK3C,SAAL,CAAe2C,SAAf,GAA2BA,SAA3B;AACD;;AACD,WAAO,KAAK3C,SAAL,CAAejD,QAAf,EAAP;AACD,GALD;AAOA;;;;;;;;;;AAQAtuB,IAAE,CAACy9B,OAAH,CAAW1lC,SAAX,CAAqBgK,GAArB,GAA2B,UAAS5B,GAAT,EAAciR,CAAd,EAAiB;AAC1C,QAAIA,CAAJ,EAAO;AACL,UAAIjZ,QAAQ,GAAGiZ,CAAC,IAAI,CAApB;AACA,UAAI9Q,UAAU,GAAG,KAAKzI,MAAL,CAAYgG,IAAZ,CAAiB3F,KAAlC;AACA,WAAKL,MAAL,CAAYgG,IAAZ,CAAiB0C,qBAAjB,CAAuCR,OAAO,CAACZ,YAAR,CAAqBkB,WAA5D;AACA,WAAKxI,MAAL,CAAYgG,IAAZ,CAAiBmR,cAAjB,CAAgC1O,UAAhC,EAA4CP,OAAO,CAACZ,YAAR,CAAqBkB,WAAjE;AACA,WAAKxI,MAAL,CAAYgG,IAAZ,CAAiB2C,uBAAjB,CAAyCL,GAAzC,EAA8ChI,QAAQ,GAAG4H,OAAO,CAACZ,YAAR,CAAqBkB,WAA9E;AACD,KAND,MAMO;AACL,WAAKxI,MAAL,CAAYgG,IAAZ,CAAiB0C,qBAAjB,CAAuCR,OAAO,CAACZ,YAAR,CAAqBkB,WAA5D;AACA,WAAKxI,MAAL,CAAYgG,IAAZ,CAAiBmR,cAAjB,CAAgC7O,GAAhC,EAAqCJ,OAAO,CAACZ,YAAR,CAAqBkB,WAA1D;AACD;AACF,GAXD;AAaA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAgCAL,IAAE,CAACy9B,OAAH,CAAW1lC,SAAX,CAAqB8oC,UAArB,GAAkC,UAAUC,SAAV,EAAqBC,OAArB,EAA8B;AAC9D,WAAO,IAAI1a,OAAJ,CAAa,UAAS2a,OAAT,EAAkBC,MAAlB,EAA0B;AAC5CriC,YAAM,CAACwmB,SAAP,CAAiB+a,YAAjB,CAA8Be,gBAA9B,GACGna,IADH,CACS,UAASoa,OAAT,EAAkB;AACvBphC,eAAO,CAAC8/B,YAAR,GAAuBsB,OAAO,CAACj3B,MAAR,CAAe,UAASk3B,MAAT,EAAiB;AACrD,iBAAOA,MAAM,CAACC,IAAP,KAAgB,YAAvB;AACD,SAFsB,CAAvB;AAGAL,eAAO,CAACjhC,OAAO,CAAC8/B,YAAT,CAAP;;AACA,YAAIiB,SAAJ,EAAe;AACbA,mBAAS,CAAC/gC,OAAO,CAAC8/B,YAAT,CAAT;AACD;AACF,OATH,WAUU,UAAS9U,KAAT,EAAgB;AACtBkW,cAAM,CAAClW,KAAD,CAAN;;AACA,YAAIgW,OAAJ,EAAa;AACXA,iBAAO,CAAChW,KAAD,CAAP;AACD,SAFD,MAEO;AACL7rB,iBAAO,CAAC6rB,KAAR,CAAc,6DAAd;AACD;AACF,OAjBH;AAkBD,KAnBM,CAAP;AAoBD,GArBD;AAuBA;;;;;;;;;;;;;;AAYA/qB,IAAE,CAACy9B,OAAH,CAAW1lC,SAAX,CAAqBupC,SAArB,GAAiC,UAASrkB,GAAT,EAAc;AAC7C,QAAIld,OAAO,CAAC8/B,YAAR,CAAqB/mC,MAArB,GAA8B,CAA9B,IAAmCmkB,GAAG,GAAGld,OAAO,CAAC8/B,YAAR,CAAqB/mC,MAAlE,EAA0E;AACxE;AACA,WAAKknC,aAAL,GAAqB/iB,GAArB;AACA/d,aAAO,CAACpB,GAAR,CAAY,gBAAZ,EAA8BiC,OAAO,CAAC8/B,YAAR,CAAqB,KAAKG,aAA1B,CAA9B;AACD,KAJD,MAIO;AACL9gC,aAAO,CAACpB,GAAR,CAAY,4BAAZ;AACD,KAP4C,CAS7C;;;AACA,QAAI,KAAKgiC,MAAL,IAAe,KAAKA,MAAL,CAAYyB,MAA/B,EAAuC;AACrC,WAAK30B,KAAL;AACD;AACF,GAbD,CA7TwB,CA4UxB;;;AACA5M,IAAE,CAACy9B,OAAH,CAAW1lC,SAAX,CAAqB8C,OAArB,GAA+B,YAAW;AACxC;AACA,QAAIsH,KAAK,GAAGpC,OAAO,CAACH,UAAR,CAAmBlH,OAAnB,CAA2B,IAA3B,CAAZ;AACAqH,WAAO,CAACH,UAAR,CAAmB7G,MAAnB,CAA0BoJ,KAA1B,EAAiC,CAAjC;AAEA,SAAKyZ,IAAL;;AAEA,QAAI,KAAK/jB,MAAT,EAAiB;AACf,WAAKA,MAAL,CAAYkD,UAAZ;AACD;;AACD,QAAI,KAAKw2B,SAAT,EAAoB;AAClB,WAAKA,SAAL,CAAex2B,UAAf;AACD;;AACD,WAAO,KAAKw2B,SAAZ;AACA,WAAO,KAAK15B,MAAZ;AACD,GAfD;AAiBD,CA9VK;AAAA,oGAAN,C;;;;;;ACFAV,iGAAO,CAAC,sBAAgB,CAAE,sBAAoB,CAAE,uBAAkB,CACjE,uBAA4B,CAAE,sBAAgB,CAAC,mCAAE,SAASC,GAE1D,aAsGA,OA9EAA,EAAKoK,UAAY,SAASggC,GAEzBjqC,KAAK6J,cAAc,EAAG,GAMtB7J,KAAKsK,EAAItK,KAAKE,MAAM,GAAK,IAAIL,EAAKkK,KAMlC/J,KAAKuK,EAAIvK,KAAKE,MAAM,GAAK,IAAIL,EAAKkK,KASlC/J,KAAK0K,KAAO,IAAI7K,EAAK+B,OAAO5B,KAAK6D,WAAWomC,EAAa,IAAMpqC,EAAK2J,KAAK4G,aAOzEpQ,KAAKkqC,aAAe,IAAIrqC,EAAKsqC,eAO7BnqC,KAAKoqC,aAAe,IAAIvqC,EAAKsqC,eAO7BnqC,KAAKqqC,QAAU,IAAIxqC,EAAKyqC,KAAK,UAG7BtqC,KAAKsK,EAAE7G,QAAQzD,KAAKM,QACpBN,KAAKuK,EAAE9G,QAAQzD,KAAKM,QACpBN,KAAK0K,KAAKrG,MAAMrE,KAAKoqC,aAAcpqC,KAAKuK,EAAEjE,MAC1CtG,KAAK0K,KAAKrG,MAAMrE,KAAKqqC,QAASrqC,KAAKkqC,aAAclqC,KAAKsK,EAAEhE,MACxDtG,KAAKmF,UAAU,SAGhBtF,EAAK+G,OAAO/G,EAAKoK,WAMjBpK,EAAKoK,UAAUzJ,UAAU8C,QAAU,WAelC,OAdAzD,EAAKW,UAAU8C,QAAQ0B,KAAKhF,MAC5BA,KAAKuF,UAAU,QACfvF,KAAKkqC,aAAa5mC,UAClBtD,KAAKkqC,aAAe,KACpBlqC,KAAKoqC,aAAa9mC,UAClBtD,KAAKoqC,aAAe,KACpBpqC,KAAK0K,KAAKpH,UACVtD,KAAK0K,KAAO,KACZ1K,KAAKqqC,QAAQ/mC,UACbtD,KAAKqqC,QAAU,KACfrqC,KAAKsK,EAAEhH,UACPtD,KAAKsK,EAAI,KACTtK,KAAKuK,EAAEjH,UACPtD,KAAKuK,EAAI,KACFvK,MAGDH,EAAKoK;AAAAA,qG;;;;;;ACzGbrK,iGAAO,CAAC,sBAAgB,CAAE,sBAAiB,CAAE,uBAAsB,CAAE,sBAAsB,CAC1F,uBAAyB,CAAE,uBAA6B,CAAE,uBAAiB,CAAE,uBAAoB,CACjG,uBAAoB,CAAE,uBAAiB,CAAE,uBAAyB,CAAC,mCACnE,SAASC,GAET,aA0DA,SAAS0qC,EAAYC,EAAa9tB,EAAM8H,GACvC,IAAIzC,EAAK,IAAIyoB,EAGb,OAFAhmB,EAAKimB,MAAM/tB,EAAK,IAAIjZ,QAAQse,EAAI,EAAG,GACnCyC,EAAKimB,MAAM/tB,EAAK,IAAIjZ,QAAQse,EAAI,EAAG,GAC5BA,EAER,SAAS2oB,EAAWF,EAAa9tB,EAAM8H,GACtC,IAAIzC,EAAK,IAAIyoB,EAEb,OADAhmB,EAAKimB,MAAM/tB,EAAK,IAAIjZ,QAAQse,EAAI,EAAG,GAC5BA,EAER,SAAS4oB,EAAU5lC,GAClB,OAAOA,EAAMwa,WAAWxa,QAAO8F,EAEhC,SAAS+/B,EAAc7lC,GACtB,OAAOA,GAAOA,EAAI2X,KAAO6C,WAAWxa,EAAI2X,WAAQ7R,EAyXjD,OApbAhL,EAAKyqC,KAAO,WAEX,IAAIzsB,EAAO7d,KAAK6qC,cAAcxqC,MAAMG,UAAUuM,MAAM/H,KAAKf,YACrD6mC,EAAa9qC,KAAK+qC,aAAaltB,GAOnC7d,KAAKgrC,OAAS,GAMdhrC,KAAKE,MAAQ,IAAIG,MAAMyqC,GAGvB,IAAK,IAAIxpC,EAAI,EAAGA,EAAIwpC,EAAYxpC,IAC/BtB,KAAKE,MAAMoB,GAAKtB,KAAKG,QAAQC,aAI9B,IAEIoP,EAFAy7B,EAAOjrC,KAAKkrC,WAAWrtB,GAG3B,IACCrO,EAASxP,KAAKyqC,MAAMQ,GACnB,MAAOh4B,GAER,MADAjT,KAAKmrC,gBACC,IAAI74B,MAAM,yCAAyCuL,GAO1D7d,KAAKM,OAASkP,GAGf3P,EAAK+G,OAAO/G,EAAKyqC,KAAMzqC,EAAK8J,YA8B5B9J,EAAKyqC,KAAKc,aAAe,CAExBzqC,MAAU,CACT0qC,OAAW,CACV/tB,OAAS,iBACTC,OAAS,SAASxY,GAEjB,OADU,IAAIlF,EAAK+B,OAAO+oC,EAAU5lC,MAItC7E,MAAU,CACTod,OAAS,QACTC,OAAS,SAASxY,EAAKyf,GACtB,OAAOA,EAAKtkB,MAAMyqC,EAAU5lC,EAAI4c,OAAO,QAK1C2pB,KAAS,CACRnqB,IAAM,CACL7D,OAAS,OAEV8D,IAAM,CACL9D,OAAS,OAEViuB,IAAM,CACLjuB,OAAS,OAIXT,KAAS,CACRyH,IAAS,CACRhH,OAAS,OACTC,OAASmtB,EAAW12B,KAAKhU,KAAMH,EAAK2rC,MAErCC,IAAQ,CACPnuB,OAAS,OACTC,OAAS,SAASb,EAAM8H,GACvB,IAAIknB,EAAUd,EAAcluB,EAAK,IAC7BqF,EAAK,IAAIliB,EAAK8rC,OAAOD,GAEzB,OADAlnB,EAAKimB,MAAM/tB,EAAK,IAAIjZ,QAAQse,GACrBA,IAGT3b,IAAQ,CACPkX,OAAS,OACTC,OAAS,SAASb,EAAM8H,GACvB,IAAI1K,EAAM8wB,EAAcluB,EAAK,IACzBqF,EAAK,IAAIliB,EAAK+rC,IAAI9xB,GAEtB,OADA0K,EAAKimB,MAAM/tB,EAAK,IAAIjZ,QAAQse,GACrBA,IAGT8pB,IAAQ,CACPvuB,OAAS,OACTC,OAAS,SAASb,EAAM8H,GACvB,IAAIzC,EAAK,IAAIliB,EAAKisC,YAElB,OADAtnB,EAAKimB,MAAM/tB,EAAK,IAAIjZ,QAAQse,GACrBA,KAKVgqB,OAAW,CACVnrB,IAAM,CACLtD,OAAS,MACTuD,WAAa,EACbtD,OAASgtB,EAAYv2B,KAAKhU,KAAMH,EAAKiQ,MAEtCgR,IAAM,CACLxD,OAAS,MACTuD,WAAa,EACbtD,OAAS,SAASb,EAAM8H,GAEvB,OAAoB,IAAhB9H,EAAKnb,OACDmpC,EAAW7qC,EAAK4b,OAAQiB,EAAM8H,GAE9B+lB,EAAY1qC,EAAK0b,SAAUmB,EAAM8H,KAI3CzD,IAAM,CACLzD,OAAS,MACTuD,WAAa,EACbtD,OAASgtB,EAAYv2B,KAAKhU,KAAMH,EAAK+J,YAIvCoiC,MAAU,CACTlrB,IAAM,CACLxD,OAAS,MACTC,OAASmtB,EAAW12B,KAAKhU,KAAMH,EAAK4b,SAErCwwB,IAAM,CACL3uB,OAAS,MACTC,OAASmtB,EAAW12B,KAAKhU,KAAMH,EAAKqsC,QAUvCrsC,EAAKyqC,KAAK9pC,UAAUuqC,aAAe,SAASltB,GAC3C,IAAIsuB,EAAatuB,EAAK3a,MAAM,SACxBkpC,EAAW,EACf,GAAmB,OAAfD,EACH,IAAK,IAAI7qC,EAAI,EAAGA,EAAI6qC,EAAW5qC,OAAQD,IAAI,CAC1C,IAAIsC,EAAWoc,SAASmsB,EAAW7qC,GAAGqgB,OAAO,IAAM,EACnDyqB,EAAWrmC,KAAK8O,IAAIu3B,EAAUxoC,GAGhC,OAAOwoC,GAQRvsC,EAAKyqC,KAAK9pC,UAAUqqC,cAAgB,SAASnuB,GAE5C,IADA,IAAImB,EAAOnB,EAAKmK,QACPvlB,EAAI,EAAGA,EAAIob,EAAKnb,OAAQD,IAChCuc,EAAOA,EAAKwuB,QAAQ,MAAO3vB,EAAKpb,IAEjC,OAAOuc,GASRhe,EAAKyqC,KAAK9pC,UAAU6gB,UAAY,SAASxD,GAIxC,IAHA,IAAIyD,GAAY,EACZC,EAAS,GAEO,EAAd1D,EAAKtc,QAAW,CAErB,IAAIigB,EAASC,EADb5D,EAAOA,EAAK6D,QAEZH,EAAOze,KAAK0e,GACZ3D,EAAOA,EAAK8D,OAAOH,EAAM7gB,MAAMY,QAGhC,SAASkgB,EAAa5D,GACrB,IAAK,IAAIzP,KAAQvO,EAAKyqC,KAAKc,aAAa,CACvC,IAAIvpB,EAAQhiB,EAAKyqC,KAAKc,aAAah9B,GACnC,IAAK,IAAI0T,KAAUD,EAAM,CACxB,IAAIE,EAAKF,EAAMC,GACXE,EAAMD,EAAGzE,OACTpa,EAAQ2a,EAAK3a,MAAM8e,GACvB,GAAc,OAAV9e,EACH,MAAO,CACNkL,KAAOA,EACPzN,MAAQuC,EAAM,GACdqa,OAASwE,EAAGxE,SAKhB,MAAM,IAAI0E,YAAY,+BAA+BpE,GAGtD,MAAO,CACNqE,KAAO,WACN,OAAOX,IAASD,IAEjBa,KAAO,WACN,OAAOZ,EAAOD,EAAW,MAY5BzhB,EAAKyqC,KAAK9pC,UAAU0qC,WAAa,SAASrtB,GACzC,IAAI2E,EAAQxiB,KAAKqhB,UAAUxD,GACvB5d,EAAUD,KAAKC,QAAQ+T,KAAKhU,MAEhC,SAASssC,EAAY9qB,EAAO+qB,GAC3B,OAAQtsC,EAAQuhB,IACA,SAAfA,EAAMpT,MACNoT,EAAM7gB,QAAU4rC,EAGlB,SAASC,EAAWhrB,EAAOirB,EAAWpqB,GACrC,IACIR,EAAQhiB,EAAKyqC,KAAKc,aAAaqB,GACnC,IAAKxsC,EAAQuhB,GACZ,IAAK,IAAIM,KAAUD,EAAM,CACxB,IAAIE,EAAKF,EAAMC,GACf,GAAIC,EAAGzE,OAAOgF,KAAKd,EAAM7gB,OAAO,CAC/B,GAAKV,EAAQoiB,GAKZ,OAAO,EAJP,GAAGN,EAAGlB,aAAewB,EACpB,OAAO,GAQZ,OAhBU,EAmBX,SAASqqB,EAAgB7rB,GAIxB,IAAIhD,EAHA5d,EAAQ4gB,KACXA,EAAa,GAIbhD,EADGgD,EAAa,EAqBlB,SAAS8rB,IACR,IAAInrB,EAAO3D,EACX2D,EAAQgB,EAAML,OACd,GAAIqqB,EAAWhrB,EAAO,SAGrB,OAFAA,EAAQgB,EAAMN,OACdrE,EAAO8uB,IACA,CACNC,SAAUprB,EAAM7gB,MAChB4c,OAASiE,EAAMjE,OACfb,KAAO,CAACmB,IAGV,OAAOgvB,IAhCCF,GAEAD,EAAgB7rB,EAAW,GAGnC,IADA,IAAIW,EAAQgB,EAAML,OACXqqB,EAAWhrB,EAAO,SAAUX,IAElChD,EAAO,CACN+uB,UAFDprB,EAAQgB,EAAMN,QAEGvhB,MAChB4c,OAASiE,EAAMjE,OACfb,KAAO,CACNmB,EACA6uB,EAAgB7rB,EAAW,KAG7BW,EAAQgB,EAAML,OAEf,OAAOtE,EAkBR,SAASgvB,IACR,IAAIrrB,EAAO3D,EAEX,GADA2D,EAAQgB,EAAML,OACVliB,EAAQuhB,GACX,MAAM,IAAIS,YAAY,mDAEvB,GAAmB,SAAfT,EAAMpT,KAET,OAqBF,SAA2ByO,GAC1B,IAAWH,EAAO,GAElB,IAAK4vB,EADG9pB,EAAMN,OACU,KACvB,MAAM,IAAID,YAAY,6CAAgDpF,EAAKlc,MAAQ,KAG/E2rC,EADG9pB,EAAML,OACU,OACvBzF,EAaF,WACC,IAAWmB,EAAMnB,EAAO,GACxB,KACCmB,EAAO6uB,KACHzsC,EAAQ4d,KAIZnB,EAAK5Z,KAAK+a,GAELyuB,EADG9pB,EAAML,OACU,OAGxBK,EAAMN,OAEP,OAAOxF,EA5BCowB,IAGR,GAAKR,EADG9pB,EAAMN,OACU,KAGxB,MAAO,CACN3E,OAASV,EAAKU,OACdb,KAAOA,EACPxK,KAAOA,MALP,MAAM,IAAI+P,YAAY,6CAAgDpF,EAAKlc,MAAQ,KAjC5EosC,CADPvrB,EAAQgB,EAAMN,QAGf,GAAmB,UAAfV,EAAMpT,KAET,MAAO,CACNmP,QAFDiE,EAAQgB,EAAMN,QAEE3E,OACfb,KAAO8E,EAAM7gB,OAGf,GAAI2rC,EAAY9qB,EAAO,KAAM,CAI5B,GAHAgB,EAAMN,OACNrE,EAAO6uB,KAEFJ,EADL9qB,EAAQgB,EAAMN,OACU,KACvB,MAAM,IAAID,YAAY,cAEvB,OAAOpE,EAER,MAAM,IAAIoE,YAAY,gDAAkDT,EAAM7gB,OA0C/E,OAAO+rC,KASR7sC,EAAKyqC,KAAK9pC,UAAUiqC,MAAQ,SAASQ,GACpC,IAAKjrC,KAAKC,QAAQgrC,GAAM,CACvB,IAAIluB,EAAOkuB,EAAK1tB,OAAO0tB,EAAKvuB,KAAM1c,MAElC,OADAA,KAAKgrC,OAAOloC,KAAKia,GACVA,IAQTld,EAAKyqC,KAAK9pC,UAAU2qC,cAAgB,WACnC,IAAK,IAAI7pC,EAAI,EAAGA,EAAItB,KAAKgrC,OAAOzpC,OAAQD,IAAI,CAC3C,IAAIyb,EAAO/c,KAAKgrC,OAAO1pC,GACnBtB,KAAKuC,WAAWwa,EAAKzZ,SACxByZ,EAAKzZ,UACKtD,KAAKuC,WAAWwa,EAAKvZ,aAC/BuZ,EAAKvZ,aAENuZ,EAAO,KACP/c,KAAKgrC,OAAO1pC,GAAK,KAElBtB,KAAKgrC,OAAS,MAMfnrC,EAAKyqC,KAAK9pC,UAAU8C,QAAU,WAC7BzD,EAAKW,UAAU8C,QAAQ0B,KAAKhF,MAC5BA,KAAKmrC,iBAGCtrC,EAAKyqC;AAAAA,qG;;;;;;ACvcb1qC,iGAAO,CAAC,sBAAgB,CAAE,uBAA6B,CAAE,uBAAsB,CAAE,sBAAoB,CAAC,mCACrG,SAASC,GAET,aAoDA,OAtCAA,EAAKmtC,YAAc,SAASrsC,GAE3BX,KAAK6J,cAAc,EAAG,GAOtB7J,KAAKqJ,OAASrJ,KAAKE,MAAM,GAAK,IAAIL,EAAK0b,SAAS5a,GAChDX,KAAKE,MAAM,GAAKF,KAAKqJ,OAAOnJ,MAAM,GAOlCF,KAAKitC,KAAOjtC,KAAKM,OAAS,IAAIT,EAAK+nB,gBAGnC5nB,KAAKqJ,OAAO5F,QAAQzD,KAAKitC,OAG1BptC,EAAK+G,OAAO/G,EAAKmtC,YAAantC,EAAK+B,QAMnC/B,EAAKmtC,YAAYxsC,UAAU8C,QAAU,WAMpC,OALAzD,EAAKW,UAAU8C,QAAQ0B,KAAKhF,MAC5BA,KAAKqJ,OAAO/F,UACZtD,KAAKqJ,OAAS,KACdrJ,KAAKitC,KAAK3pC,UACVtD,KAAKitC,KAAO,KACLjtC,MAGDH,EAAKmtC;AAAAA,qG;;;;;;ACvDbptC,iGAAO,CAAC,sBAAgB,CAAE,sBAAwB,CAAE,uBAAwB,CAAC,mCAC7E,SAASC,GAER,aAwCA,OA3BAA,EAAK2rC,IAAM,WAKVxrC,KAAKktC,KAAOltC,KAAKE,MAAQF,KAAKM,OAAS,IAAIT,EAAKiL,WAAW,SAAShG,GACnE,OAAY,IAARA,EACI,EAEAiB,KAAKue,IAAIxf,IAEf,MAGJjF,EAAK+G,OAAO/G,EAAK2rC,IAAK3rC,EAAK8J,YAM3B9J,EAAK2rC,IAAIhrC,UAAU8C,QAAU,WAI5B,OAHAzD,EAAKW,UAAU8C,QAAQ0B,KAAKhF,MAC5BA,KAAKktC,KAAK5pC,UACVtD,KAAKktC,KAAO,KACLltC,MAGDH,EAAK2rC;AAAAA,qG;;;;;;AC3Cb5rC,iGAAO,CAAC,sBAAgB,CAAE,sBAAwB,CAAE,sBAAsB,CAAE,uBAAsB,CAAC,mCACnG,SAASC,GAER,aAqGA,OAvFAA,EAAK8rC,OAAS,SAASD,GAEtB1rC,KAAK6J,cAAc,EAAG,GAQtB7J,KAAKiL,QAAU,IAAIpL,EAAKiL,WAAW/E,KAAKK,IAAI,EAAG,KAO/CpG,KAAK2nB,UAAY,IAAI9nB,EAAK+J,SAO1B5J,KAAKmtC,UAAYntC,KAAKM,OAAS,IAAIT,EAAK0b,SAOxCvb,KAAKotC,WAAa,IAAIvtC,EAAK+B,OAAO8pC,GAGlC1rC,KAAKE,MAAMoE,IAAItE,KAAKiL,QAASjL,KAAKmtC,WAClCntC,KAAKotC,WAAW3pC,QAAQzD,KAAK2nB,UAAW,EAAG,GAC3C3nB,KAAKiL,QAAQxH,QAAQzD,KAAK2nB,UAAW,EAAG,GACxC3nB,KAAK2nB,UAAUlkB,QAAQzD,KAAKmtC,UAAW,EAAG,GAC1CntC,KAAKqtC,eAAe3B,IAGrB7rC,EAAK+G,OAAO/G,EAAK8rC,OAAQ9rC,EAAK8J,YAM9B9J,EAAK8rC,OAAOnrC,UAAU6sC,eAAiB,SAAS5B,GAC/CzrC,KAAKiL,QAAQM,OAAO,SAASzG,GAE5B,OADeiB,KAAKmU,OAAOpV,EAAM,MAAU2mC,MAW7C/oC,OAAOU,eAAevD,EAAK8rC,OAAOnrC,UAAW,QAAS,CACrDwB,IAAM,WACL,OAAOhC,KAAKotC,WAAWzsC,OAExBF,IAAM,SAASgrC,GACdzrC,KAAKotC,WAAWzsC,MAAQ8qC,EACxBzrC,KAAKqtC,eAAe5B,MAQtB5rC,EAAK8rC,OAAOnrC,UAAU8C,QAAU,WAU/B,OATAzD,EAAKW,UAAU8C,QAAQ0B,KAAKhF,MAC5BA,KAAKiL,QAAQ3H,UACbtD,KAAKiL,QAAU,KACfjL,KAAK2nB,UAAUrkB,UACftD,KAAK2nB,UAAY,KACjB3nB,KAAKmtC,UAAU7pC,UACftD,KAAKmtC,UAAY,KACjBntC,KAAKotC,WAAW9pC,UAChBtD,KAAKotC,WAAa,KACXptC,MAGDH,EAAK8rC;AAAAA,qG;;;;;;ACxGb/rC,iGAAO,CAAC,sBAAgB,CAAE,sBAAwB,CAAC,mCAAE,SAASC,GAE7D,aAwEA,OA1DAA,EAAK+rC,IAAM,SAAS9xB,GAOnB9Z,KAAKstC,KAAOttC,KAAK6D,WAAWiW,EAAK,GAMjC9Z,KAAKutC,WAAavtC,KAAKE,MAAQF,KAAKM,OAAS,IAAIT,EAAKiL,WAAW9K,KAAKwtC,SAASxtC,KAAKstC,MAAO,OAG5FztC,EAAK+G,OAAO/G,EAAK+rC,IAAK/rC,EAAK8J,YAQ3BjH,OAAOU,eAAevD,EAAK+rC,IAAIprC,UAAW,QAAS,CAClDwB,IAAM,WACL,OAAOhC,KAAKstC,MAEb7sC,IAAM,SAASqZ,GACd9Z,KAAKstC,KAAOxzB,EACZ9Z,KAAKutC,WAAWhiC,OAAOvL,KAAKwtC,SAASxtC,KAAKstC,UAW5CztC,EAAK+rC,IAAIprC,UAAUgtC,SAAW,SAAS1zB,GACtC,OAAO,SAAShV,GACf,OAAOiB,KAAKK,IAAIL,KAAKue,IAAIxf,GAAMgV,KAQjCja,EAAK+rC,IAAIprC,UAAU8C,QAAU,WAI5B,OAHAzD,EAAKW,UAAU8C,QAAQ0B,KAAKhF,MAC5BA,KAAKutC,WAAWjqC,UAChBtD,KAAKutC,WAAa,KACXvtC,MAGDH,EAAK+rC;AAAAA,qG;;;;;;AC1EbhsC,iGAAO,CAAC,sBAAgB,CAAE,sBAAwB,CAAE,sBAAoB,CAAC,mCAAE,SAASC,GAEnF,aAmCA,OAxBAA,EAAKisC,YAAc,WAMlB9rC,KAAKytC,MAAQztC,KAAKE,MAAQF,KAAKM,OAAS,IAAIT,EAAKiL,WAAW,SAASg1B,GACpE,OAAQA,EAAI,GAAK,KAInBjgC,EAAK+G,OAAO/G,EAAKisC,YAAajsC,EAAK8J,YAMnC9J,EAAKisC,YAAYtrC,UAAU8C,QAAU,WAIpC,OAHAzD,EAAKW,UAAU8C,QAAQ0B,KAAKhF,MAC5BA,KAAKytC,MAAMnqC,UACXtD,KAAKytC,MAAQ,KACNztC,MAGDH,EAAKisC;AAAAA,qG;;;;;;ACrCblsC,iGAAO,CAAC,sBAAgB,CAAE,sBAAwB,CAAC,mCAAE,SAASC,GAE7D,aAuCA,OA7BAA,EAAKsqC,eAAiB,WAMrBnqC,KAAK0tC,SAAW1tC,KAAKE,MAAQF,KAAKM,OAAS,IAAIT,EAAKiL,WAAW,SAAShG,GACvE,OAAIiB,KAAKue,IAAIxf,GAAO,KAEZ,EAEA9E,KAAK4F,gBAAgBd,IAE5BkP,KAAKhU,MAAO,OAGfH,EAAK+G,OAAO/G,EAAKsqC,eAAgBtqC,EAAK8J,YAMtC9J,EAAKsqC,eAAe3pC,UAAU8C,QAAU,WAIvC,OAHAzD,EAAKW,UAAU8C,QAAQ0B,KAAKhF,MAC5BA,KAAK0tC,SAASpqC,UACdtD,KAAK0tC,SAAW,KACT1tC,MAGDH,EAAKsqC;AAAAA,qG;;;;;;;ACzCb,kCAAa;;AAEbvqC,mCAAO,UAAUoK,OAAV,EAAmB;AAExB,MAAIE,MAAM,GAAGF,mBAAO,CAAC,CAAD,CAApB;;AACA,MAAI2jC,QAAQ,GAAG3jC,mBAAO,CAAC,EAAD,CAAtB;AAEA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAiFAvB,IAAE,CAACmlC,EAAH,GAAQ,UAASC,OAAT,EAAkB;AACxB3jC,UAAM,CAAClF,IAAP,CAAY,IAAZ,EADwB,CAGxB;;AACA6oC,WAAO,GAAGA,OAAO,KAAK,CAAZ,IAAiBA,OAAO,KAAK,CAA7B,GAAiCA,OAAjC,GAA2C,CAArD;AAEA,QAAIC,MAAJ;AACAD,WAAO,KAAK,CAAZ,GAAgBC,MAAM,GAAG/nC,IAAI,CAACK,GAAL,CAAS,CAAT,EAAW,CAAX,CAAzB,GAAyC0nC,MAAM,GAAG,CAAlD;AAEA;;;;;;;;;;AASA,SAAKC,KAAL,GAAa,EAAb;AAGA,QAAIv8B,IAAJ,EAAUwJ,GAAV;;AACA,SAAK,IAAI1Z,CAAC,GAAG,CAAb,EAAgBA,CAAC,GAAGusC,OAApB,EAA6BvsC,CAAC,EAA9B,EAAkC;AAChC,UAAIA,CAAC,KAAKusC,OAAO,GAAG,CAApB,EAAuB;AACrBr8B,YAAI,GAAG,KAAP;AACAwJ,WAAG,GAAG,GAAN;AACD,OAHD,MAGO,IAAI1Z,CAAC,KAAK,CAAV,EAAa;AAClBkQ,YAAI,GAAG,GAAP;AACAwJ,WAAG,GAAG,EAAN;AACD,OAHM,MAIF,IAAI1Z,CAAC,KAAG,CAAR,EAAW;AACdkQ,YAAI,GAAGq8B,OAAO,KAAK,CAAZ,GAAgB,MAAMC,MAAtB,GAA+B,GAAtC;AACA9yB,WAAG,GAAG,CAAN;AACD,OAHI,MAGC;AACJxJ,YAAI,GAAG,KAAKu8B,KAAL,CAAWzsC,CAAC,GAAC,CAAb,EAAgBkQ,IAAhB,KAAyBs8B,MAAhC;AACA9yB,WAAG,GAAG,CAAN;AACD;;AACD,WAAK+yB,KAAL,CAAWzsC,CAAX,IAAgB,KAAK0sC,QAAL,CAAcx8B,IAAd,EAAoBwJ,GAApB,CAAhB;;AAEA,UAAI1Z,CAAC,GAAC,CAAN,EAAS;AACP,aAAKysC,KAAL,CAAWzsC,CAAC,GAAC,CAAb,EAAgBmC,OAAhB,CAAwB,KAAKsqC,KAAL,CAAWzsC,CAAX,EAAckZ,MAAtC;AACD,OAFD,MAEO;AACL,aAAKta,KAAL,CAAWuD,OAAX,CAAmB,KAAKsqC,KAAL,CAAWzsC,CAAX,EAAckZ,MAAjC;AACD;AACF;;AACD,SAAKuzB,KAAL,CAAWF,OAAO,GAAC,CAAnB,EAAsBpqC,OAAtB,CAA8B,KAAKnD,MAAnC;AACD,GA9CD;;AA+CAmI,IAAE,CAACmlC,EAAH,CAAMptC,SAAN,GAAkBkC,MAAM,CAACmY,MAAP,CAAc3Q,MAAM,CAAC1J,SAArB,CAAlB;AAEA;;;;;;AAKAiI,IAAE,CAACmlC,EAAH,CAAMptC,SAAN,CAAgBsa,OAAhB,GAA0B,UAAUC,GAAV,EAAe;AACvCA,OAAG,CAACtX,OAAJ,CAAY,KAAKvD,KAAjB;AACD,GAFD,CA5IwB,CAgJxB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;AACAuI,IAAE,CAACmlC,EAAH,CAAMptC,SAAN,CAAgBC,GAAhB,GAAsB,YAAW;AAC/B,QAAIwD,SAAS,CAAC1C,MAAV,KAAqB,KAAKwsC,KAAL,CAAWxsC,MAAX,GAAoB,CAA7C,EAAgD;AAC9C,WAAK,IAAID,CAAC,GAAG,CAAb,EAAgBA,CAAC,GAAG2C,SAAS,CAAC1C,MAA9B,EAAsCD,CAAC,IAAE,CAAzC,EAA4C;AAC1C,aAAKysC,KAAL,CAAWzsC,CAAC,GAAC,CAAb,EAAgBkQ,IAAhB,CAAqBvN,SAAS,CAAC3C,CAAD,CAA9B;AACA,aAAKysC,KAAL,CAAWzsC,CAAC,GAAC,CAAb,EAAgBgF,IAAhB,CAAqBrC,SAAS,CAAC3C,CAAC,GAAC,CAAH,CAA9B;AACD;AACF,KALD,MAMK;AACHqG,aAAO,CAAC6rB,KAAR,CAAc,qDAAqD,KAAKua,KAAL,CAAWxsC,MAAX,GAAkB,CAAvE,GACZ,yEADF;AAED;AACF,GAXD;AAaA;;;;;;;;;;;;;AAWAkH,IAAE,CAACmlC,EAAH,CAAMptC,SAAN,CAAgBwtC,QAAhB,GAA2B,UAASx8B,IAAT,EAAewJ,GAAf,EAAoB;AAC7C,WAAO,IAAI2yB,QAAJ,CAAan8B,IAAb,EAAmBwJ,GAAnB,CAAP;AACD,GAFD;;AAIAvS,IAAE,CAACmlC,EAAH,CAAMptC,SAAN,CAAgB8C,OAAhB,GAA0B,YAAY;AACpC4G,UAAM,CAAC1J,SAAP,CAAiB8C,OAAjB,CAAyBU,KAAzB,CAA+B,IAA/B;;AAEA,QAAI,KAAK+pC,KAAT,EAAgB;AACd,aAAO,KAAKA,KAAL,CAAWxsC,MAAX,GAAoB,CAA3B,EAA8B;AAC5B,eAAO,KAAKwsC,KAAL,CAAWvgC,GAAX,GAAiBlK,OAAjB,EAAP;AACD;;AACD,aAAO,KAAKyqC,KAAZ;AACD;AACF,GATD;;AAWA,SAAOtlC,EAAE,CAACmlC,EAAV;AACD,CAhNK;AAAA,oGAAN,C;;;;;;;ACFA,kCAAa;;AAEbhuC,mCAAO,UAAUoK,OAAV,EAAmB;AACxB,MAAIuQ,MAAM,GAAGvQ,mBAAO,CAAC,EAAD,CAApB;;AACA,MAAIxB,OAAO,GAAGwB,mBAAO,CAAC,CAAD,CAArB;AAEA;;;;;;;;AAMA,MAAI2jC,QAAQ,GAAG,SAAXA,QAAW,CAASn8B,IAAT,EAAewJ,GAAf,EAAoB;AACjCT,UAAM,CAACvV,IAAP,CAAY,IAAZ,EAAkB,SAAlB;AACA,SAAKxB,UAAL;AACA,SAAK/C,GAAL,CAAS+Q,IAAT,EAAewJ,GAAf;AACA,SAAKR,MAAL,CAAYlU,IAAZ,CAAiB3F,KAAjB,GAAyB,CAAzB;AACA,WAAO,KAAKT,KAAZ;AACA,WAAO,KAAKI,MAAZ;AACA,WAAO,KAAK8J,OAAZ;AACA,WAAO,KAAKC,GAAZ;AAED,GAVD;;AAWAsjC,UAAQ,CAACntC,SAAT,GAAqBkC,MAAM,CAACmY,MAAP,CAAcN,MAAM,CAAC/Z,SAArB,CAArB;;AAEAmtC,UAAQ,CAACntC,SAAT,CAAmBgK,GAAnB,GAAyB,YAAW;AAClC7C,WAAO,CAACkO,IAAR,CAAa,yDAAb;AACD,GAFD;;AAGA83B,UAAQ,CAACntC,SAAT,CAAmBiK,MAAnB,GAA4B,YAAW;AACrC9C,WAAO,CAACkO,IAAR,CAAa,8CAAb;AACD,GAFD;;AAGA83B,UAAQ,CAACntC,SAAT,CAAmBiD,OAAnB,GAA6B,UAASC,IAAT,EAAe;AAC1C,QAAIiH,CAAC,GAAGjH,IAAI,IAAI+E,EAAE,CAACS,QAAH,CAAYhJ,KAA5B;;AACA,QAAI,KAAKsa,MAAT,EAAiB;AACf,WAAKA,MAAL,CAAY/W,OAAZ,CAAoBkH,CAAC,CAACzK,KAAF,GAAUyK,CAAC,CAACzK,KAAZ,GAAoByK,CAAxC;AACD,KAFD,MAEO;AACL,WAAKrK,MAAL,CAAYmD,OAAZ,CAAoBkH,CAAC,CAACzK,KAAF,GAAUyK,CAAC,CAACzK,KAAZ,GAAoByK,CAAxC;AACD;AACF,GAPD;;AASAgjC,UAAQ,CAACntC,SAAT,CAAmBgD,UAAnB,GAAgC,YAAW;AACzC,QAAI,KAAKgX,MAAT,EAAiB;AACf,WAAKA,MAAL,CAAYhX,UAAZ;AACD;AACF,GAJD;;AAKAmqC,UAAQ,CAACntC,SAAT,CAAmB8C,OAAnB,GAA6B,YAAW;AACtC;AACA,QAAIsH,KAAK,GAAGpC,OAAO,CAACH,UAAR,CAAmBlH,OAAnB,CAA2B,IAA3B,CAAZ;AACAqH,WAAO,CAACH,UAAR,CAAmB7G,MAAnB,CAA0BoJ,KAA1B,EAAiC,CAAjC;AACA,SAAKpH,UAAL;AACA,WAAO,KAAKgX,MAAZ;AACD,GAND;;AAQA,SAAOmzB,QAAP;AACD,CApDK;AAAA,oGAAN,C;;;;;;;ACFA;;AAEA/tC,mCAAO,UAAUoK,OAAV,EAAmB;AACxB,MAAIxB,OAAO,GAAGwB,mBAAO,CAAC,CAAD,CAArB;;AACA,MAAIE,MAAM,GAAGF,mBAAO,CAAC,CAAD,CAApB;AAEA;;;;;;;;;;;;;;;;;;AAgBDvB,IAAE,CAACwlC,QAAH,GAAc,YAAW;AACpB/jC,UAAM,CAAClF,IAAP,CAAY,IAAZ;AAEA;;;;;;;;;;;;;;;;;AAgBA,SAAKmf,MAAL,GAAc,KAAKha,EAAL,CAAQ+jC,YAAR,EAAd;AACA,SAAK/pB,MAAL,CAAYgqB,YAAZ,GAA2B,MAA3B;AACA,SAAKhqB,MAAL,CAAYiqB,aAAZ,GAA4B,QAA5B;AACA,SAAKjqB,MAAL,CAAY1gB,OAAZ,CAAoB,KAAKnD,MAAzB;AACA,SAAKJ,KAAL,CAAWuD,OAAX,CAAmB,KAAK0gB,MAAxB;AACJ,GAxBD;;AA0BC1b,IAAE,CAACwlC,QAAH,CAAYztC,SAAZ,GAAwBkC,MAAM,CAACmY,MAAP,CAAc3Q,MAAM,CAAC1J,SAArB,CAAxB;AAGA;;;;;;;;AAOAiI,IAAE,CAACwlC,QAAH,CAAYztC,SAAZ,CAAsBsa,OAAtB,GAAgC,UAASC,GAAT,EAAc;AAC5CA,OAAG,CAACtX,OAAJ,CAAY,KAAKvD,KAAjB;AACD,GAFD;AAGA;;;;;;;;;;;;AAUAuI,IAAE,CAACwlC,QAAH,CAAYztC,SAAZ,CAAsBC,GAAtB,GAA4B,UAAS4tC,IAAT,EAAeC,IAAf,EAAqBC,IAArB,EAA2Bl9B,IAA3B,EAAiC;AAC3D,SAAKm9B,SAAL,CAAeH,IAAf,EAAoBh9B,IAApB;AACA,SAAKo9B,SAAL,CAAeH,IAAf,EAAoBj9B,IAApB;AACA,SAAKq9B,SAAL,CAAeH,IAAf,EAAoBl9B,IAApB;AACA,WAAO,CAAC,KAAK8S,MAAL,CAAYqqB,SAAZ,CAAsB7tC,KAAvB,EACG,KAAKwjB,MAAL,CAAYsqB,SAAZ,CAAsB9tC,KADzB,EAEG,KAAKwjB,MAAL,CAAYuqB,SAAZ,CAAsB/tC,KAFzB,CAAP;AAGD,GAPD;AASA;;;;;;;AAMA;;;;;;;AAMA;;;;;;;;AAMA8H,IAAE,CAACwlC,QAAH,CAAYztC,SAAZ,CAAsBguC,SAAtB,GAAkC,UAASH,IAAT,EAAeh9B,IAAf,EAAqB;AACrD,QAAIwI,CAAC,GAAGxI,IAAI,IAAI,CAAhB;;AACA,QAAI,OAAOg9B,IAAP,KAAgB,QAApB,EAA8B;AAC5B,WAAKlqB,MAAL,CAAYqqB,SAAZ,CAAsB7tC,KAAtB,GAA8B0tC,IAA9B;AACA,WAAKlqB,MAAL,CAAYqqB,SAAZ,CAAsBxlC,qBAAtB,CAA4C,KAAKmB,EAAL,CAAQrB,WAAR,GAAsB,IAAtB,GAA6B+Q,CAAzE;AACA,WAAKsK,MAAL,CAAYqqB,SAAZ,CAAsBvlC,uBAAtB,CAA8ColC,IAA9C,EAAoD,KAAKlkC,EAAL,CAAQrB,WAAR,GAAsB,IAAtB,GAA6B+Q,CAAjF;AACD,KAJD,MAIO,IAAIw0B,IAAJ,EAAU;AACfA,UAAI,CAAC5qC,OAAL,CAAa,KAAK0gB,MAAL,CAAYqqB,SAAzB;AACD;;AACD,WAAO,KAAKrqB,MAAL,CAAYqqB,SAAZ,CAAsB7tC,KAA7B;AACD,GAVD;;AAWA8H,IAAE,CAACwlC,QAAH,CAAYztC,SAAZ,CAAsBiuC,SAAtB,GAAkC,UAASH,IAAT,EAAej9B,IAAf,EAAqB;AACrD,QAAIwI,CAAC,GAAGxI,IAAI,IAAI,CAAhB;;AACA,QAAI,OAAOi9B,IAAP,KAAgB,QAApB,EAA8B;AAC5B,WAAKnqB,MAAL,CAAYsqB,SAAZ,CAAsB9tC,KAAtB,GAA8B2tC,IAA9B;AACA,WAAKnqB,MAAL,CAAYsqB,SAAZ,CAAsBzlC,qBAAtB,CAA4C,KAAKmB,EAAL,CAAQrB,WAAR,GAAsB,IAAtB,GAA6B+Q,CAAzE;AACA,WAAKsK,MAAL,CAAYsqB,SAAZ,CAAsBxlC,uBAAtB,CAA8CqlC,IAA9C,EAAoD,KAAKnkC,EAAL,CAAQrB,WAAR,GAAsB,IAAtB,GAA6B+Q,CAAjF;AACD,KAJD,MAIO,IAAIy0B,IAAJ,EAAU;AACfA,UAAI,CAAC7qC,OAAL,CAAa,KAAK0gB,MAAL,CAAYsqB,SAAzB;AACD;;AACD,WAAO,KAAKtqB,MAAL,CAAYsqB,SAAZ,CAAsB9tC,KAA7B;AACD,GAVD;;AAWA8H,IAAE,CAACwlC,QAAH,CAAYztC,SAAZ,CAAsBkuC,SAAtB,GAAkC,UAASH,IAAT,EAAel9B,IAAf,EAAqB;AACrD,QAAIwI,CAAC,GAAGxI,IAAI,IAAI,CAAhB;;AACA,QAAI,OAAOk9B,IAAP,KAAgB,QAApB,EAA8B;AAC5B,WAAKpqB,MAAL,CAAYuqB,SAAZ,CAAsB/tC,KAAtB,GAA8B4tC,IAA9B;AACA,WAAKpqB,MAAL,CAAYuqB,SAAZ,CAAsB1lC,qBAAtB,CAA4C,KAAKmB,EAAL,CAAQrB,WAAR,GAAsB,IAAtB,GAA6B+Q,CAAzE;AACA,WAAKsK,MAAL,CAAYuqB,SAAZ,CAAsBzlC,uBAAtB,CAA8CslC,IAA9C,EAAoD,KAAKpkC,EAAL,CAAQrB,WAAR,GAAsB,IAAtB,GAA6B+Q,CAAjF;AACD,KAJD,MAIO,IAAI00B,IAAJ,EAAU;AACfA,UAAI,CAAC9qC,OAAL,CAAa,KAAK0gB,MAAL,CAAYuqB,SAAzB;AACD;;AACD,WAAO,KAAKvqB,MAAL,CAAYuqB,SAAZ,CAAsB/tC,KAA7B;AACD,GAVD;AAYA;;;;;;;;;;;;AAUA8H,IAAE,CAACwlC,QAAH,CAAYztC,SAAZ,CAAsBmuC,MAAtB,GAA+B,UAASN,IAAT,EAAeC,IAAf,EAAqBC,IAArB,EAA2Bl9B,IAA3B,EAAiC;AAChE,SAAKu9B,OAAL,CAAaP,IAAb,EAAkBh9B,IAAlB;AACA,SAAKw9B,OAAL,CAAaP,IAAb,EAAkBj9B,IAAlB;AACA,SAAKy9B,OAAL,CAAaP,IAAb,EAAkBl9B,IAAlB;AACA,WAAO,CAAC,KAAK8S,MAAL,CAAY4qB,YAAZ,CAAyBpuC,KAA1B,EACC,KAAKwjB,MAAL,CAAY6qB,YAAZ,CAAyBruC,KAD1B,EAEC,KAAKwjB,MAAL,CAAY8qB,YAAZ,CAAyBtuC,KAF1B,CAAP;AAGC,GAPD;AASA;;;;;;;AAMA;;;;;;;AAMA;;;;;;;;AAMA8H,IAAE,CAACwlC,QAAH,CAAYztC,SAAZ,CAAsBouC,OAAtB,GAAgC,UAASP,IAAT,EAAeh9B,IAAf,EAAqB;AACnD,QAAIwI,CAAC,GAAGxI,IAAI,IAAI,CAAhB;;AACA,QAAI,OAAOg9B,IAAP,KAAgB,QAApB,EAA8B;AAC5B,WAAKlqB,MAAL,CAAY4qB,YAAZ,CAAyBpuC,KAAzB,GAAiC0tC,IAAjC;AACA,WAAKlqB,MAAL,CAAY4qB,YAAZ,CAAyB/lC,qBAAzB,CAA+C,KAAKmB,EAAL,CAAQrB,WAAR,GAAsB,IAAtB,GAA6B+Q,CAA5E;AACA,WAAKsK,MAAL,CAAY4qB,YAAZ,CAAyB9lC,uBAAzB,CAAiDolC,IAAjD,EAAuD,KAAKlkC,EAAL,CAAQrB,WAAR,GAAsB,IAAtB,GAA6B+Q,CAApF;AACD,KAJD,MAIO,IAAIw0B,IAAJ,EAAU;AACfA,UAAI,CAAC5qC,OAAL,CAAa,KAAK0gB,MAAL,CAAY4qB,YAAzB;AACD;;AACD,WAAO,KAAK5qB,MAAL,CAAY4qB,YAAZ,CAAyBpuC,KAAhC;AACD,GAVD;;AAWA8H,IAAE,CAACwlC,QAAH,CAAYztC,SAAZ,CAAsBquC,OAAtB,GAAgC,UAASP,IAAT,EAAej9B,IAAf,EAAqB;AACnD,QAAIwI,CAAC,GAAGxI,IAAI,IAAI,CAAhB;;AACA,QAAI,OAAOi9B,IAAP,KAAgB,QAApB,EAA8B;AAC5B,WAAKnqB,MAAL,CAAY6qB,YAAZ,CAAyBruC,KAAzB,GAAiC2tC,IAAjC;AACA,WAAKnqB,MAAL,CAAY6qB,YAAZ,CAAyBhmC,qBAAzB,CAA+C,KAAKmB,EAAL,CAAQrB,WAAR,GAAsB,IAAtB,GAA6B+Q,CAA5E;AACA,WAAKsK,MAAL,CAAY6qB,YAAZ,CAAyB/lC,uBAAzB,CAAiDqlC,IAAjD,EAAuD,KAAKnkC,EAAL,CAAQrB,WAAR,GAAsB,IAAtB,GAA6B+Q,CAApF;AACD,KAJD,MAIO,IAAIy0B,IAAJ,EAAU;AACfA,UAAI,CAAC7qC,OAAL,CAAa,KAAK0gB,MAAL,CAAY6qB,YAAzB;AACD;;AACD,WAAO,KAAK7qB,MAAL,CAAY6qB,YAAZ,CAAyBruC,KAAhC;AACD,GAVD;;AAWA8H,IAAE,CAACwlC,QAAH,CAAYztC,SAAZ,CAAsBsuC,OAAtB,GAAgC,UAASP,IAAT,EAAel9B,IAAf,EAAqB;AACnD,QAAIwI,CAAC,GAAGxI,IAAI,IAAI,CAAhB;;AACA,QAAI,OAAOk9B,IAAP,KAAgB,QAApB,EAA8B;AAC5B,WAAKpqB,MAAL,CAAY8qB,YAAZ,CAAyBtuC,KAAzB,GAAiC4tC,IAAjC;AACA,WAAKpqB,MAAL,CAAY8qB,YAAZ,CAAyBjmC,qBAAzB,CAA+C,KAAKmB,EAAL,CAAQrB,WAAR,GAAsB,IAAtB,GAA6B+Q,CAA5E;AACA,WAAKsK,MAAL,CAAY8qB,YAAZ,CAAyBhmC,uBAAzB,CAAiDslC,IAAjD,EAAuD,KAAKpkC,EAAL,CAAQrB,WAAR,GAAsB,IAAtB,GAA6B+Q,CAApF;AACD,KAJD,MAIO,IAAI00B,IAAJ,EAAU;AACfA,UAAI,CAAC9qC,OAAL,CAAa,KAAK0gB,MAAL,CAAY8qB,YAAzB;AACD;;AACD,WAAO,KAAK9qB,MAAL,CAAY8qB,YAAZ,CAAyBtuC,KAAhC;AACD,GAVD;AAYA;;;;;;;;;AAOA8H,IAAE,CAACwlC,QAAH,CAAYztC,SAAZ,CAAsB0uC,UAAtB,GAAmC,UAASC,WAAT,EAAsBC,aAAtB,EAAqC;AACtE,SAAKC,OAAL,CAAaF,WAAb;AACA,SAAKG,OAAL,CAAaF,aAAb;AACD,GAHD;AAIA;;;;;;;;;AAOA3mC,IAAE,CAACwlC,QAAH,CAAYztC,SAAZ,CAAsB6uC,OAAtB,GAAgC,UAASF,WAAT,EAAqB;AACnD,QAAI,OAAOA,WAAP,KAAuB,QAA3B,EAAqC;AACnC,WAAKhrB,MAAL,CAAYgrB,WAAZ,GAA0BA,WAA1B;AACD;;AACD,WAAO,KAAKhrB,MAAL,CAAYgrB,WAAnB;AACD,GALD;AAOA;;;;;;;;;AAOA1mC,IAAE,CAACwlC,QAAH,CAAYztC,SAAZ,CAAsB8uC,OAAtB,GAAgC,UAASF,aAAT,EAAuB;AACrD,QAAI,OAAOA,aAAP,KAAyB,QAA7B,EAAuC;AACrC,WAAKjrB,MAAL,CAAYirB,aAAZ,GAA4BA,aAA5B;AACD;;AACD,WAAO,KAAKjrB,MAAL,CAAYirB,aAAnB;AACD,GALD;;AAOA3mC,IAAE,CAACwlC,QAAH,CAAY3qC,OAAZ,GAAsB,YAAW;AAC/B4G,UAAM,CAAC1J,SAAP,CAAiB8C,OAAjB,CAAyBU,KAAzB,CAA+B,IAA/B;;AACA,QAAI,KAAKmgB,MAAT,EAAiB;AACf,WAAKA,MAAL,CAAY3gB,UAAZ;AACA,aAAO,KAAK2gB,MAAZ;AACD;AACF,GAND;;AAQA,SAAO1b,EAAE,CAACwlC,QAAV;AAED,CA1PK;AAAA,oGAAN,C;;;;;;;ACFA;;AAEAruC,mCAAO,UAAUoK,OAAV,EAAmB;AACxB,MAAIxB,OAAO,GAAGwB,mBAAO,CAAC,CAAD,CAArB;;AACA,MAAIE,MAAM,GAAGF,mBAAO,CAAC,CAAD,CAApB,CAFwB,CAI1B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;AAECvB,IAAE,CAAC8mC,UAAH,GAAgB,UAASnhC,IAAT,EAAe;AAC1B,SAAKjE,EAAL,GAAU3B,OAAO,CAACZ,YAAlB;AACA,SAAK4nC,QAAL,GAAgB,KAAKrlC,EAAL,CAAQqlC,QAAxB;AACJ,GAHD,CA5ByB,CAiC1B;AACA;AACA;AACA;;;AACE/mC,IAAE,CAAC8mC,UAAH,CAAc/uC,SAAd,CAAwBsa,OAAxB,GAAkC,UAASC,GAAT,EAAc;AAC9CA,OAAG,CAACtX,OAAJ,CAAY,KAAKvD,KAAjB;AACD,GAFD,CArCwB,CAwC1B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;AACEuI,IAAE,CAAC8mC,UAAH,CAAc/uC,SAAd,CAAwB8gB,QAAxB,GAAmC,UAAS+sB,IAAT,EAAeC,IAAf,EAAqBC,IAArB,EAA2Bl9B,IAA3B,EAAiC;AAClE,SAAKm9B,SAAL,CAAeH,IAAf,EAAoBh9B,IAApB;AACA,SAAKo9B,SAAL,CAAeH,IAAf,EAAoBj9B,IAApB;AACA,SAAKq9B,SAAL,CAAeH,IAAf,EAAoBl9B,IAApB;AACA,WAAO,CAAC,KAAKm+B,QAAL,CAAchB,SAAd,CAAwB7tC,KAAzB,EACG,KAAK6uC,QAAL,CAAcf,SAAd,CAAwB9tC,KAD3B,EAEG,KAAK6uC,QAAL,CAAcd,SAAd,CAAwB/tC,KAF3B,CAAP;AAGD,GAPD,CAhDwB,CAyD1B;AACA;AACA;AACA;;;AACE8H,IAAE,CAAC8mC,UAAH,CAAc/uC,SAAd,CAAwBguC,SAAxB,GAAoC,UAASH,IAAT,EAAeh9B,IAAf,EAAqB;AACvD,QAAIwI,CAAC,GAAGxI,IAAI,IAAI,CAAhB;;AACA,QAAI,OAAOg9B,IAAP,KAAgB,QAApB,EAA8B;AAC5B,WAAKmB,QAAL,CAAchB,SAAd,CAAwB7tC,KAAxB,GAAgC0tC,IAAhC;AACA,WAAKmB,QAAL,CAAchB,SAAd,CAAwBxlC,qBAAxB,CAA8C,KAAKmB,EAAL,CAAQrB,WAAR,GAAsB,IAAtB,GAA6B+Q,CAA3E;AACA,WAAK21B,QAAL,CAAchB,SAAd,CAAwBvlC,uBAAxB,CAAgDolC,IAAhD,EAAsD,KAAKlkC,EAAL,CAAQrB,WAAR,GAAsB,IAAtB,GAA6B+Q,CAAnF;AACD,KAJD,MAIO,IAAIw0B,IAAJ,EAAU;AACfA,UAAI,CAAC5qC,OAAL,CAAa,KAAK+rC,QAAL,CAAchB,SAA3B;AACD;;AACD,WAAO,KAAKgB,QAAL,CAAchB,SAAd,CAAwB7tC,KAA/B;AACD,GAVD;;AAWA8H,IAAE,CAAC8mC,UAAH,CAAc/uC,SAAd,CAAwBiuC,SAAxB,GAAoC,UAASH,IAAT,EAAej9B,IAAf,EAAqB;AACvD,QAAIwI,CAAC,GAAGxI,IAAI,IAAI,CAAhB;;AACA,QAAI,OAAOi9B,IAAP,KAAgB,QAApB,EAA8B;AAC5B,WAAKkB,QAAL,CAAcf,SAAd,CAAwB9tC,KAAxB,GAAgC2tC,IAAhC;AACA,WAAKkB,QAAL,CAAcf,SAAd,CAAwBzlC,qBAAxB,CAA8C,KAAKmB,EAAL,CAAQrB,WAAR,GAAsB,IAAtB,GAA6B+Q,CAA3E;AACA,WAAK21B,QAAL,CAAcf,SAAd,CAAwBxlC,uBAAxB,CAAgDqlC,IAAhD,EAAsD,KAAKnkC,EAAL,CAAQrB,WAAR,GAAsB,IAAtB,GAA6B+Q,CAAnF;AACD,KAJD,MAIO,IAAIy0B,IAAJ,EAAU;AACfA,UAAI,CAAC7qC,OAAL,CAAa,KAAK+rC,QAAL,CAAcf,SAA3B;AACD;;AACD,WAAO,KAAKe,QAAL,CAAcf,SAAd,CAAwB9tC,KAA/B;AACD,GAVD;;AAWA8H,IAAE,CAAC8mC,UAAH,CAAc/uC,SAAd,CAAwBkuC,SAAxB,GAAoC,UAASH,IAAT,EAAel9B,IAAf,EAAqB;AACvD,QAAIwI,CAAC,GAAGxI,IAAI,IAAI,CAAhB;;AACA,QAAI,OAAOk9B,IAAP,KAAgB,QAApB,EAA8B;AAC5B,WAAKiB,QAAL,CAAcd,SAAd,CAAwB/tC,KAAxB,GAAgC4tC,IAAhC;AACA,WAAKiB,QAAL,CAAcd,SAAd,CAAwB1lC,qBAAxB,CAA8C,KAAKmB,EAAL,CAAQrB,WAAR,GAAsB,IAAtB,GAA6B+Q,CAA3E;AACA,WAAK21B,QAAL,CAAcd,SAAd,CAAwBzlC,uBAAxB,CAAgDslC,IAAhD,EAAsD,KAAKpkC,EAAL,CAAQrB,WAAR,GAAsB,IAAtB,GAA6B+Q,CAAnF;AACD,KAJD,MAIO,IAAI00B,IAAJ,EAAU;AACfA,UAAI,CAAC9qC,OAAL,CAAa,KAAK+rC,QAAL,CAAcd,SAA3B;AACD;;AACD,WAAO,KAAKc,QAAL,CAAcd,SAAd,CAAwB/tC,KAA/B;AACD,GAVD,CAnFwB,CA+F1B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;AACE8H,IAAE,CAAC8mC,UAAH,CAAc/uC,SAAd,CAAwBmuC,MAAxB,GAAiC,UAASc,KAAT,EAAgBC,KAAhB,EAAuBC,KAAvB,EACWC,KADX,EACkBC,KADlB,EACyBC,KADzB,EACgCz+B,IADhC,EACsC;AAEvE,QAAIpN,SAAS,CAAC1C,MAAV,KAAqB,CAArB,IAA0B0C,SAAS,CAAC1C,MAAV,KAAqB,CAAnD,EAAsD;AACpD8P,UAAI,GAAGpN,SAAS,CAAC,CAAD,CAAhB;AACA,WAAK8rC,aAAL,CAAmBN,KAAnB,EAA0BC,KAA1B,EAAiCC,KAAjC,EAAwCt+B,IAAxC;AACD,KAHD,MAGO,IAAIpN,SAAS,CAAC1C,MAAV,KAAqB,CAArB,IAA0B0C,SAAS,KAAK,CAA5C,EAA+C;AACpD,WAAK8rC,aAAL,CAAmBN,KAAnB,EAA0BC,KAA1B,EAAiCC,KAAjC;AACA,WAAKK,QAAL,CAAcJ,KAAd,EAAqBC,KAArB,EAA4BC,KAA5B,EAAmCz+B,IAAnC;AACD;;AAED,WAAO,CAAC,KAAKm+B,QAAL,CAAcS,QAAd,CAAuBtvC,KAAxB,EACC,KAAK6uC,QAAL,CAAcU,QAAd,CAAuBvvC,KADxB,EAEC,KAAK6uC,QAAL,CAAcW,QAAd,CAAuBxvC,KAFxB,EAGC,KAAK6uC,QAAL,CAAcY,GAAd,CAAkBzvC,KAHnB,EAIC,KAAK6uC,QAAL,CAAca,GAAd,CAAkB1vC,KAJnB,EAKC,KAAK6uC,QAAL,CAAcc,GAAd,CAAkB3vC,KALnB,CAAP;AAMC,GAjBD;;AAoBA8H,IAAE,CAAC8mC,UAAH,CAAc/uC,SAAd,CAAwBuvC,aAAxB,GAAwC,UAASN,KAAT,EAAgBC,KAAhB,EAAuBC,KAAvB,EAA8Bt+B,IAA9B,EAAoC;AAC1E,SAAK4+B,QAAL,CAAcR,KAAd,EAAoBp+B,IAApB;AACA,SAAK6+B,QAAL,CAAcR,KAAd,EAAoBr+B,IAApB;AACA,SAAK8+B,QAAL,CAAcR,KAAd,EAAoBt+B,IAApB;AAEA,WAAO,CAAC,KAAKm+B,QAAL,CAAcS,QAAf,EACC,KAAKT,QAAL,CAAcU,QADf,EAEC,KAAKV,QAAL,CAAcW,QAFf,CAAP;AAGD,GARD;;AAUA1nC,IAAE,CAAC8mC,UAAH,CAAc/uC,SAAd,CAAwBwvC,QAAxB,GAAmC,UAASJ,KAAT,EAAgBC,KAAhB,EAAuBC,KAAvB,EAA8Bz+B,IAA9B,EAAoC;AACrE,SAAK++B,GAAL,CAASR,KAAT,EAAev+B,IAAf;AACA,SAAKg/B,GAAL,CAASR,KAAT,EAAex+B,IAAf;AACA,SAAKi/B,GAAL,CAASR,KAAT,EAAez+B,IAAf;AAEA,WAAO,CAAC,KAAKm+B,QAAL,CAAcY,GAAf,EACC,KAAKZ,QAAL,CAAca,GADf,EAEC,KAAKb,QAAL,CAAcc,GAFf,CAAP;AAGD,GARD,CA7IwB,CAsJ1B;AACA;AACA;AACA;;;AACE7nC,IAAE,CAAC8mC,UAAH,CAAc/uC,SAAd,CAAwByvC,QAAxB,GAAmC,UAAS5B,IAAT,EAAeh9B,IAAf,EAAqB;AACtD,QAAIwI,CAAC,GAAGxI,IAAI,IAAI,CAAhB;;AACA,QAAI,OAAOg9B,IAAP,KAAgB,QAApB,EAA8B;AAC5B,WAAKmB,QAAL,CAAcS,QAAd,CAAuBtvC,KAAvB,GAA+B0tC,IAA/B;AACA,WAAKmB,QAAL,CAAcS,QAAd,CAAuBjnC,qBAAvB,CAA6C,KAAKmB,EAAL,CAAQrB,WAAR,GAAsB,IAAtB,GAA6B+Q,CAA1E;AACA,WAAK21B,QAAL,CAAcS,QAAd,CAAuBhnC,uBAAvB,CAA+ColC,IAA/C,EAAqD,KAAKlkC,EAAL,CAAQrB,WAAR,GAAsB,IAAtB,GAA6B+Q,CAAlF;AACD,KAJD,MAIO,IAAIw0B,IAAJ,EAAU;AACfA,UAAI,CAAC5qC,OAAL,CAAa,KAAK+rC,QAAL,CAAcS,QAA3B;AACD;;AACD,WAAO,KAAKT,QAAL,CAAcS,QAAd,CAAuBtvC,KAA9B;AACD,GAVD;;AAWA8H,IAAE,CAAC8mC,UAAH,CAAc/uC,SAAd,CAAwB0vC,QAAxB,GAAmC,UAAS5B,IAAT,EAAej9B,IAAf,EAAqB;AACtD,QAAIwI,CAAC,GAAGxI,IAAI,IAAI,CAAhB;;AACA,QAAI,OAAOi9B,IAAP,KAAgB,QAApB,EAA8B;AAC5B,WAAKkB,QAAL,CAAcU,QAAd,CAAuBvvC,KAAvB,GAA+B2tC,IAA/B;AACA,WAAKkB,QAAL,CAAcU,QAAd,CAAuBlnC,qBAAvB,CAA6C,KAAKmB,EAAL,CAAQrB,WAAR,GAAsB,IAAtB,GAA6B+Q,CAA1E;AACA,WAAK21B,QAAL,CAAcU,QAAd,CAAuBjnC,uBAAvB,CAA+CqlC,IAA/C,EAAqD,KAAKnkC,EAAL,CAAQrB,WAAR,GAAsB,IAAtB,GAA6B+Q,CAAlF;AACD,KAJD,MAIO,IAAIy0B,IAAJ,EAAU;AACfA,UAAI,CAAC7qC,OAAL,CAAa,KAAK+rC,QAAL,CAAcU,QAA3B;AACD;;AACD,WAAO,KAAKV,QAAL,CAAcU,QAAd,CAAuBvvC,KAA9B;AACD,GAVD;;AAWA8H,IAAE,CAAC8mC,UAAH,CAAc/uC,SAAd,CAAwB2vC,QAAxB,GAAmC,UAAS5B,IAAT,EAAel9B,IAAf,EAAqB;AACtD,QAAIwI,CAAC,GAAGxI,IAAI,IAAI,CAAhB;;AACA,QAAI,OAAOk9B,IAAP,KAAgB,QAApB,EAA8B;AAC5B,WAAKiB,QAAL,CAAcW,QAAd,CAAuBxvC,KAAvB,GAA+B4tC,IAA/B;AACA,WAAKiB,QAAL,CAAcW,QAAd,CAAuBnnC,qBAAvB,CAA6C,KAAKmB,EAAL,CAAQrB,WAAR,GAAsB,IAAtB,GAA6B+Q,CAA1E;AACA,WAAK21B,QAAL,CAAcW,QAAd,CAAuBlnC,uBAAvB,CAA+CslC,IAA/C,EAAqD,KAAKpkC,EAAL,CAAQrB,WAAR,GAAsB,IAAtB,GAA6B+Q,CAAlF;AACD,KAJD,MAIO,IAAI00B,IAAJ,EAAU;AACfA,UAAI,CAAC9qC,OAAL,CAAa,KAAK+rC,QAAL,CAAcW,QAA3B;AACD;;AACD,WAAO,KAAKX,QAAL,CAAcW,QAAd,CAAuBxvC,KAA9B;AACD,GAVD;;AAWA8H,IAAE,CAAC8mC,UAAH,CAAc/uC,SAAd,CAAwB4vC,GAAxB,GAA8B,UAAS/B,IAAT,EAAeh9B,IAAf,EAAqB;AACjD,QAAIwI,CAAC,GAAGxI,IAAI,IAAI,CAAhB;;AACA,QAAI,OAAOg9B,IAAP,KAAgB,QAApB,EAA8B;AAC5B,WAAKmB,QAAL,CAAcY,GAAd,CAAkBzvC,KAAlB,GAA0B0tC,IAA1B;AACA,WAAKmB,QAAL,CAAcY,GAAd,CAAkBpnC,qBAAlB,CAAwC,KAAKmB,EAAL,CAAQrB,WAAR,GAAsB,IAAtB,GAA6B+Q,CAArE;AACA,WAAK21B,QAAL,CAAcY,GAAd,CAAkBnnC,uBAAlB,CAA0ColC,IAA1C,EAAgD,KAAKlkC,EAAL,CAAQrB,WAAR,GAAsB,IAAtB,GAA6B+Q,CAA7E;AACD,KAJD,MAIO,IAAIw0B,IAAJ,EAAU;AACfA,UAAI,CAAC5qC,OAAL,CAAa,KAAK+rC,QAAL,CAAcY,GAA3B;AACD;;AACD,WAAO,KAAKZ,QAAL,CAAcY,GAAd,CAAkBzvC,KAAzB;AACD,GAVD;;AAWA8H,IAAE,CAAC8mC,UAAH,CAAc/uC,SAAd,CAAwB6vC,GAAxB,GAA8B,UAAS/B,IAAT,EAAej9B,IAAf,EAAqB;AACjD,QAAIwI,CAAC,GAAGxI,IAAI,IAAI,CAAhB;;AACA,QAAI,OAAOi9B,IAAP,KAAgB,QAApB,EAA8B;AAC5B,WAAKkB,QAAL,CAAca,GAAd,CAAkB1vC,KAAlB,GAA0B2tC,IAA1B;AACA,WAAKkB,QAAL,CAAca,GAAd,CAAkBrnC,qBAAlB,CAAwC,KAAKmB,EAAL,CAAQrB,WAAR,GAAsB,IAAtB,GAA6B+Q,CAArE;AACA,WAAK21B,QAAL,CAAca,GAAd,CAAkBpnC,uBAAlB,CAA0CqlC,IAA1C,EAAgD,KAAKnkC,EAAL,CAAQrB,WAAR,GAAsB,IAAtB,GAA6B+Q,CAA7E;AACD,KAJD,MAIO,IAAIy0B,IAAJ,EAAU;AACfA,UAAI,CAAC7qC,OAAL,CAAa,KAAK+rC,QAAL,CAAca,GAA3B;AACD;;AACD,WAAO,KAAKb,QAAL,CAAca,GAAd,CAAkB1vC,KAAzB;AACD,GAVD;;AAWA8H,IAAE,CAAC8mC,UAAH,CAAc/uC,SAAd,CAAwB8vC,GAAxB,GAA8B,UAAS/B,IAAT,EAAel9B,IAAf,EAAqB;AACjD,QAAIwI,CAAC,GAAGxI,IAAI,IAAI,CAAhB;;AACA,QAAI,OAAOk9B,IAAP,KAAgB,QAApB,EAA8B;AAC5B,WAAKiB,QAAL,CAAcc,GAAd,CAAkB3vC,KAAlB,GAA0B4tC,IAA1B;AACA,WAAKiB,QAAL,CAAcc,GAAd,CAAkBtnC,qBAAlB,CAAwC,KAAKmB,EAAL,CAAQrB,WAAR,GAAsB,IAAtB,GAA6B+Q,CAArE;AACA,WAAK21B,QAAL,CAAcc,GAAd,CAAkBrnC,uBAAlB,CAA0CslC,IAA1C,EAAgD,KAAKpkC,EAAL,CAAQrB,WAAR,GAAsB,IAAtB,GAA6B+Q,CAA7E;AACD,KAJD,MAIO,IAAI00B,IAAJ,EAAU;AACfA,UAAI,CAAC9qC,OAAL,CAAa,KAAK+rC,QAAL,CAAcc,GAA3B;AACD;;AACD,WAAO,KAAKd,QAAL,CAAcc,GAAd,CAAkB3vC,KAAzB;AACD,GAVD;;AAYA,SAAO8H,EAAE,CAAC8mC,UAAV;AAED,CA/NK;AAAA,oGAAN,C;;;;;;;ACFA,kCAAa;;AAEb3vC,mCAAO,UAAUoK,OAAV,EAAmB;AACxB,MAAIuQ,MAAM,GAAGvQ,mBAAO,CAAC,EAAD,CAApB;;AACA,MAAIE,MAAM,GAAGF,mBAAO,CAAC,CAAD,CAApB;AAEA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAsDAvB,IAAE,CAAC49B,KAAH,GAAW,YAAW;AACrBn8B,UAAM,CAAClF,IAAP,CAAY,IAAZ;AAEC,SAAKurC,MAAL,GAAc,KAAKpmC,EAAL,CAAQ+lB,qBAAR,CAA8B,CAA9B,CAAd;AACA,SAAKsgB,MAAL,GAAc,KAAKrmC,EAAL,CAAQgmB,mBAAR,CAA4B,CAA5B,CAAd;AAEA,SAAKsgB,SAAL,GAAiB,KAAKtmC,EAAL,CAAQ/J,UAAR,EAAjB;AACA,SAAKswC,UAAL,GAAkB,KAAKvmC,EAAL,CAAQ/J,UAAR,EAAlB;AAEA;;;;;;;;AAOA,SAAKuwC,SAAL,GAAiB,KAAKxmC,EAAL,CAAQkb,WAAR,EAAjB;AACA;;;;;;;;AAOA,SAAKurB,UAAL,GAAkB,KAAKzmC,EAAL,CAAQkb,WAAR,EAAlB;AAEA,SAAKwrB,WAAL,GAAmB,IAAIt2B,MAAJ,EAAnB;AACA,SAAKu2B,YAAL,GAAoB,IAAIv2B,MAAJ,EAApB;;AACA,SAAKs2B,WAAL,CAAiBrtC,UAAjB;;AACA,SAAKstC,YAAL,CAAkBttC,UAAlB;;AAEA,SAAKqtC,WAAL,CAAiBr2B,MAAjB,CAAwBS,SAAxB,CAAkCxD,cAAlC,CAAiD,IAAjD,EAAuD,KAAKtN,EAAL,CAAQrB,WAA/D;;AACA,SAAKgoC,YAAL,CAAkBt2B,MAAlB,CAAyBS,SAAzB,CAAmCxD,cAAnC,CAAkD,IAAlD,EAAwD,KAAKtN,EAAL,CAAQrB,WAAhE;;AACA,SAAK+nC,WAAL,CAAiBr2B,MAAjB,CAAwBU,CAAxB,CAA0BzD,cAA1B,CAAyC,GAAzC,EAA8C,KAAKtN,EAAL,CAAQrB,WAAtD;;AACA,SAAKgoC,YAAL,CAAkBt2B,MAAlB,CAAyBU,CAAzB,CAA2BzD,cAA3B,CAA0C,GAA1C,EAA+C,KAAKtN,EAAL,CAAQrB,WAAvD,EAlCoB,CAoCpB;;;AACA,SAAK5I,KAAL,CAAWuD,OAAX,CAAmB,KAAK8sC,MAAxB;AACA,SAAKI,SAAL,CAAeltC,OAAf,CAAuB,KAAKgtC,SAA5B;AACA,SAAKG,UAAL,CAAgBntC,OAAhB,CAAwB,KAAKitC,UAA7B;;AACA,SAAKD,SAAL,CAAehtC,OAAf,CAAuB,KAAKotC,WAAL,CAAiB3wC,KAAxC;;AACA,SAAKwwC,UAAL,CAAgBjtC,OAAhB,CAAwB,KAAKqtC,YAAL,CAAkB5wC,KAA1C;;AACA,SAAKswC,MAAL,CAAY/sC,OAAZ,CAAoB,KAAK4G,GAAzB;;AAGA,SAAKwmC,WAAL,CAAiBr2B,MAAjB,CAAwBlU,IAAxB,CAA6BmR,cAA7B,CAA4C,CAA5C,EAA+C,KAAKtN,EAAL,CAAQrB,WAAvD;;AACA,SAAKgoC,YAAL,CAAkBt2B,MAAlB,CAAyBlU,IAAzB,CAA8BmR,cAA9B,CAA6C,CAA7C,EAAgD,KAAKtN,EAAL,CAAQrB,WAAxD,EA9CoB,CAgDpB;;;AACA,SAAK4R,OAAL,CAAa,CAAb;AAEA,SAAKq2B,SAAL,GAAiB,KAAKJ,SAAL,CAAerrB,SAAf,CAAyB0rB,QAA1C,CAnDoB,CAqDpB;;AACA,SAAKC,QAAL,CAAc,GAAd;AAGD,GAzDD;;AA2DAxoC,IAAE,CAAC49B,KAAH,CAAS7lC,SAAT,GAAqBkC,MAAM,CAACmY,MAAP,CAAc3Q,MAAM,CAAC1J,SAArB,CAArB;AACA;;;;;;;;;;;;;;;;;;AAiBAiI,IAAE,CAAC49B,KAAH,CAAS7lC,SAAT,CAAmBsa,OAAnB,GAA6B,UAASC,GAAT,EAAcm2B,UAAd,EAA0BC,SAA1B,EAAqCC,OAArC,EAA8C;AACzE,QAAIH,QAAQ,GAAGE,SAAS,IAAI,CAA5B;AACA,QAAI7rB,SAAS,GAAG4rB,UAAU,IAAI,CAA9B;;AACA,QAAID,QAAQ,IAAI,GAAhB,EAAqB;AACnB,YAAM,IAAI3+B,KAAJ,CAAU,qDAAV,CAAN;AACD;;AACD,QAAIgT,SAAS,IAAI,KAAKyrB,SAAtB,EAAiC;AAC/B,YAAM,IAAIz+B,KAAJ,CAAU,8CAA8C,KAAKy+B,SAAnD,GAA+D,UAAzE,CAAN;AACD;;AAEDh2B,OAAG,CAACtX,OAAJ,CAAY,KAAKvD,KAAjB;AACA,SAAKywC,SAAL,CAAerrB,SAAf,CAAyB7N,cAAzB,CAAwC6N,SAAxC,EAAmD,KAAKnb,EAAL,CAAQrB,WAA3D;AACA,SAAK8nC,UAAL,CAAgBtrB,SAAhB,CAA0B7N,cAA1B,CAAyC6N,SAAzC,EAAoD,KAAKnb,EAAL,CAAQrB,WAA5D;AACA,SAAK2nC,SAAL,CAAenqC,IAAf,CAAoB3F,KAApB,GAA4BswC,QAA5B;AACA,SAAKP,UAAL,CAAgBpqC,IAAhB,CAAqB3F,KAArB,GAA6BswC,QAA7B;;AAEA,QAAIG,OAAJ,EAAa;AACX,WAAKP,WAAL,CAAiBr/B,IAAjB,CAAsB4/B,OAAtB;;AACA,WAAKN,YAAL,CAAkBt/B,IAAlB,CAAuB4/B,OAAvB;AACD;AACF,GApBD;AAsBA;;;;;;;;;;AAQA3oC,IAAE,CAAC49B,KAAH,CAAS7lC,SAAT,CAAmB8kB,SAAnB,GAA+B,UAASzL,CAAT,EAAY;AACzC;AACA,QAAI,OAAOA,CAAP,KAAa,QAAjB,EAA2B;AACzBA,OAAC,CAACpW,OAAF,CAAU,KAAKktC,SAAL,CAAerrB,SAAzB;AACAzL,OAAC,CAACpW,OAAF,CAAU,KAAKmtC,UAAL,CAAgBtrB,SAA1B;AACD,KAHD,MAKK;AACH,WAAKqrB,SAAL,CAAerrB,SAAf,CAAyBtc,qBAAzB,CAA+C,KAAKmB,EAAL,CAAQrB,WAAvD;AACA,WAAK8nC,UAAL,CAAgBtrB,SAAhB,CAA0Btc,qBAA1B,CAAgD,KAAKmB,EAAL,CAAQrB,WAAxD;AACA,WAAK6nC,SAAL,CAAerrB,SAAf,CAAyBrc,uBAAzB,CAAiD4Q,CAAjD,EAAoD,KAAK1P,EAAL,CAAQrB,WAA5D;AACA,WAAK8nC,UAAL,CAAgBtrB,SAAhB,CAA0Brc,uBAA1B,CAAkD4Q,CAAlD,EAAqD,KAAK1P,EAAL,CAAQrB,WAA7D;AACD;AACF,GAbD;AAeA;;;;;;;;;;;;;;;;;AAeAL,IAAE,CAAC49B,KAAH,CAAS7lC,SAAT,CAAmBywC,QAAnB,GAA8B,UAASnlC,CAAT,EAAY;AACxC;AACA,QAAIA,CAAC,IAAI,OAAOA,CAAP,KAAa,QAAtB,EAAgC;AAC9BA,OAAC,CAACrI,OAAF,CAAU,KAAKgtC,SAAL,CAAenqC,IAAzB;AACAwF,OAAC,CAACrI,OAAF,CAAU,KAAKitC,UAAL,CAAgBpqC,IAA1B;AACD,KAHD,MAIK,IAAIwF,CAAC,IAAI,GAAT,EAAc;AACjB,YAAM,IAAIwG,KAAJ,CAAU,qDAAV,CAAN;AACD,KAFI,MAGA,IAAI,OAAOxG,CAAP,KAAa,QAAjB,EAA2B;AAC9B,WAAK2kC,SAAL,CAAenqC,IAAf,CAAoB3F,KAApB,GAA4BmL,CAA5B;AACA,WAAK4kC,UAAL,CAAgBpqC,IAAhB,CAAqB3F,KAArB,GAA6BmL,CAA7B;AACD,KAZuC,CAcxC;;;AACA,WAAO,KAAK2kC,SAAL,CAAenqC,IAAf,CAAoB3F,KAA3B;AACD,GAhBD;AAkBA;;;;;;;;;;;;;;;;AAcA8H,IAAE,CAAC49B,KAAH,CAAS7lC,SAAT,CAAmBmS,MAAnB,GAA4B,UAASnB,IAAT,EAAe6O,CAAf,EAAkB;AAC5C,SAAKwwB,WAAL,CAAiBpwC,GAAjB,CAAqB+Q,IAArB,EAA2B6O,CAA3B;;AACA,SAAKywB,YAAL,CAAkBrwC,GAAlB,CAAsB+Q,IAAtB,EAA4B6O,CAA5B;AACD,GAHD;AAMA;;;;;;;;;;;AASA5X,IAAE,CAAC49B,KAAH,CAAS7lC,SAAT,CAAmBka,OAAnB,GAA6B,UAASb,CAAT,EAAY;AACvC,QAAIA,CAAC,KAAK,CAAV,EAAa;AACXA,OAAC,GAAG,UAAJ;AACD;;AACD,SAAK02B,MAAL,CAAY/sC,UAAZ;;AACA,SAAKqtC,WAAL,CAAiBrtC,UAAjB;;AACA,SAAKstC,YAAL,CAAkBttC,UAAlB;;AACA,SAAK+sC,MAAL,CAAY9sC,OAAZ,CAAoB,KAAKktC,SAAzB,EAAoC,CAApC;;AACA,SAAKJ,MAAL,CAAY9sC,OAAZ,CAAoB,KAAKmtC,UAAzB,EAAqC,CAArC;;AACA,YAAO/2B,CAAP;AACE,WAAK,UAAL;AACE,aAAKi3B,YAAL,CAAkBp2B,OAAlB,CAA2B,KAAKm2B,WAAL,CAAiBr2B,MAAjB,CAAwBpM,IAAnD;;AACA,aAAKyiC,WAAL,CAAiBvwC,MAAjB,CAAwBmD,OAAxB,CAAgC,KAAK+sC,MAArC,EAA6C,CAA7C,EAAgD,CAAhD;;AACA,aAAKM,YAAL,CAAkBxwC,MAAlB,CAAyBmD,OAAzB,CAAiC,KAAK+sC,MAAtC,EAA8C,CAA9C,EAAiD,CAAjD;;AACA,aAAKK,WAAL,CAAiBvwC,MAAjB,CAAwBmD,OAAxB,CAAgC,KAAKmtC,UAArC;;AACA,aAAKE,YAAL,CAAkBxwC,MAAlB,CAAyBmD,OAAzB,CAAiC,KAAKktC,SAAtC;;AACA;;AACF;AACE,aAAKE,WAAL,CAAiBvwC,MAAjB,CAAwBmD,OAAxB,CAAgC,KAAK+sC,MAArC,EAA6C,CAA7C,EAAgD,CAAhD;;AACA,aAAKM,YAAL,CAAkBxwC,MAAlB,CAAyBmD,OAAzB,CAAiC,KAAK+sC,MAAtC,EAA8C,CAA9C,EAAiD,CAAjD;;AACA,aAAKK,WAAL,CAAiBvwC,MAAjB,CAAwBmD,OAAxB,CAAgC,KAAKktC,SAArC;;AACA,aAAKG,YAAL,CAAkBxwC,MAAlB,CAAyBmD,OAAzB,CAAiC,KAAKmtC,UAAtC;;AAZJ;AAcD,GAvBD,CAlPwB,CA2QxB;;AACA;;;;;;;;;;;AAUA;;;;;;;;AAOA;;;;;;;;AAOAnoC,IAAE,CAAC49B,KAAH,CAAS7lC,SAAT,CAAmB8C,OAAnB,GAA6B,YAAW;AAEtC4G,UAAM,CAAC1J,SAAP,CAAiB8C,OAAjB,CAAyBU,KAAzB,CAA+B,IAA/B;;AAEA,SAAKusC,MAAL,CAAY/sC,UAAZ;;AACA,SAAKqtC,WAAL,CAAiBvtC,OAAjB;;AACA,SAAKwtC,YAAL,CAAkBxtC,OAAlB;;AACA,SAAKktC,MAAL,CAAYhtC,UAAZ;;AACA,SAAKitC,SAAL,CAAejtC,UAAf;;AACA,SAAKktC,UAAL,CAAgBltC,UAAhB;;AACA,SAAKmtC,SAAL,CAAentC,UAAf;AACA,SAAKotC,UAAL,CAAgBptC,UAAhB;AAEA,SAAK+sC,MAAL,GAAc1lC,SAAd;AACA,SAAKgmC,WAAL,GAAmBhmC,SAAnB;AACA,SAAKimC,YAAL,GAAoBjmC,SAApB;AACA,SAAK2lC,MAAL,GAAc3lC,SAAd;AACA,SAAK4lC,SAAL,GAAiB5lC,SAAjB;AACA,SAAK6lC,UAAL,GAAkB7lC,SAAlB;AACA,SAAK8lC,SAAL,GAAiB9lC,SAAjB;AACA,SAAK+lC,UAAL,GAAkB/lC,SAAlB;AACD,GArBD;AAuBD,CA3TK;AAAA,oGAAN,C;;;;;;;ACFA,kCAAa;;AAEbjL,mCAAO,UAAUoK,OAAV,EAAmB;AACxB,MAAIiI,WAAW,GAAGjI,mBAAO,CAAC,EAAD,CAAzB;;AACA,MAAIE,MAAM,GAAGF,mBAAO,CAAC,CAAD,CAApB;AAEA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAqCAvB,IAAE,CAAC09B,MAAH,GAAY,YAAW;AACrBj8B,UAAM,CAAClF,IAAP,CAAY,IAAZ;;AAEA,SAAKqsC,kBAAL,GAHqB,CAKrB;;;AACA,SAAKnxC,KAAL,CAAWoG,IAAX,CAAgB3F,KAAhB,GAAwB,GAAxB,CANqB,CAQrB;;AACA,SAAK2wC,QAAL,GAAgB,CAAhB;AACA,SAAKC,MAAL,GAAc,CAAd;AACA,SAAKC,QAAL,GAAgB,KAAhB;;AAEA,SAAKC,aAAL;AAED,GAfD;;AAiBAhpC,IAAE,CAAC09B,MAAH,CAAU3lC,SAAV,GAAsBkC,MAAM,CAACmY,MAAP,CAAc3Q,MAAM,CAAC1J,SAArB,CAAtB;;AAEAiI,IAAE,CAAC09B,MAAH,CAAU3lC,SAAV,CAAoB6wC,kBAApB,GAAyC,YAAW;AAClD,SAAKK,aAAL,GAAqB,KAAKvnC,EAAL,CAAQwnC,eAAR,EAArB;AACA,SAAKzxC,KAAL,CAAWuD,OAAX,CAAmB,KAAKiuC,aAAxB;AACA,SAAKA,aAAL,CAAmBjuC,OAAnB,CAA2B,KAAK4G,GAAhC;AACD,GAJD;;AAMA5B,IAAE,CAAC09B,MAAH,CAAU3lC,SAAV,CAAoBoxC,sBAApB,GAA6C,YAAW;AACtD,QAAI,KAAKF,aAAT,EAAwB;AACtB,WAAKA,aAAL,CAAmBluC,UAAnB;AACA,aAAO,KAAKkuC,aAAZ;AACD;AACF,GALD;;AAOAjpC,IAAE,CAAC09B,MAAH,CAAU3lC,SAAV,CAAoBqxC,UAApB,GAAiC,UAAStjC,WAAT,EAAsB;AACrD,SAAKqjC,sBAAL;;AACA,SAAKP,kBAAL;;AACA,SAAKK,aAAL,CAAmB5iC,MAAnB,GAA4BP,WAA5B;AACD,GAJD;AAKA;;;;;;;;;;;;;;;AAaA9F,IAAE,CAAC09B,MAAH,CAAU3lC,SAAV,CAAoBsa,OAApB,GAA8B,UAASC,GAAT,EAAc+H,OAAd,EAAuBgvB,SAAvB,EAAkCrc,OAAlC,EAA2C;AACvE1a,OAAG,CAACtX,OAAJ,CAAY,KAAKvD,KAAjB;AACA,QAAI6xC,OAAO,GAAG,KAAd;;AACA,QAAIjvB,OAAJ,EAAa;AACX,WAAKwuB,QAAL,GAAgBxuB,OAAhB;AACAivB,aAAO,GAAG,IAAV;AACD;;AACD,QAAID,SAAJ,EAAe;AACb,WAAKP,MAAL,GAAcO,SAAd;AACD;;AACD,QAAIrc,OAAJ,EAAa;AACX,WAAK+b,QAAL,GAAgB/b,OAAhB;AACD;;AACD,QAAIsc,OAAJ,EAAa;AACX,WAAKN,aAAL;AACD;AACF,GAhBD;AAkBA;;;;;;;;;;;;;;AAYAhpC,IAAE,CAAC09B,MAAH,CAAU3lC,SAAV,CAAoBC,GAApB,GAA0B,UAASqiB,OAAT,EAAkBgvB,SAAlB,EAA6Brc,OAA7B,EAAsC;AAC9D,QAAIsc,OAAO,GAAG,KAAd;;AACA,QAAIjvB,OAAJ,EAAa;AACX,WAAKwuB,QAAL,GAAgBxuB,OAAhB;AACAivB,aAAO,GAAG,IAAV;AACD;;AACD,QAAID,SAAJ,EAAe;AACb,WAAKP,MAAL,GAAcO,SAAd;AACD;;AACD,QAAIrc,OAAJ,EAAa;AACX,WAAK+b,QAAL,GAAgB/b,OAAhB;AACD;;AACD,QAAIsc,OAAJ,EAAa;AACX,WAAKN,aAAL;AACD;AACF,GAfD,CAzHwB,CA0IxB;;AACA;;;;;;;;;;;AAUA;;;;;;;;AAOA;;;;;;;AAOA;;;;;;;;;;;AASAhpC,IAAE,CAAC09B,MAAH,CAAU3lC,SAAV,CAAoBixC,aAApB,GAAoC,YAAW;AAC7C,QAAIvd,IAAI,GAAG,KAAK/pB,EAAL,CAAQhD,UAAnB;AACA,QAAI5F,MAAM,GAAG2yB,IAAI,GAAC,KAAKod,QAAvB;AACA,QAAIvnB,KAAK,GAAG,KAAKwnB,MAAjB;AACA,QAAIS,OAAO,GAAG,KAAK7nC,EAAL,CAAQ2K,YAAR,CAAqB,CAArB,EAAwBvT,MAAxB,EAAgC2yB,IAAhC,CAAd;AACA,QAAI+d,QAAQ,GAAGD,OAAO,CAACtjC,cAAR,CAAuB,CAAvB,CAAf;AACA,QAAIwjC,QAAQ,GAAGF,OAAO,CAACtjC,cAAR,CAAuB,CAAvB,CAAf;AACA,QAAIqQ,CAAJ,EAAOzd,CAAP;;AACA,SAAKA,CAAC,GAAG,CAAT,EAAYA,CAAC,GAAGC,MAAhB,EAAwBD,CAAC,EAAzB,EAA6B;AAC3Byd,OAAC,GAAG,KAAKyyB,QAAL,GAAgBjwC,MAAM,GAAGD,CAAzB,GAA6BA,CAAjC;AACA2wC,cAAQ,CAAC3wC,CAAD,CAAR,GAAc,CAACyE,IAAI,CAAC0hC,MAAL,KAAgB,CAAhB,GAAoB,CAArB,IAA0B1hC,IAAI,CAACK,GAAL,CAAS,IAAI2Y,CAAC,GAAGxd,MAAjB,EAAyBwoB,KAAzB,CAAxC;AACAmoB,cAAQ,CAAC5wC,CAAD,CAAR,GAAc,CAACyE,IAAI,CAAC0hC,MAAL,KAAgB,CAAhB,GAAoB,CAArB,IAA0B1hC,IAAI,CAACK,GAAL,CAAS,IAAI2Y,CAAC,GAAGxd,MAAjB,EAAyBwoB,KAAzB,CAAxC;AACD;;AACD,SAAK8nB,UAAL,CAAgBG,OAAhB;AACD,GAdD;;AAgBAvpC,IAAE,CAAC09B,MAAH,CAAU3lC,SAAV,CAAoB8C,OAApB,GAA8B,YAAW;AACvC4G,UAAM,CAAC1J,SAAP,CAAiB8C,OAAjB,CAAyBU,KAAzB,CAA+B,IAA/B;;AACA,SAAK4tC,sBAAL;AACD,GAHD,CA5LwB,CAiMxB;AACA;AACA;;AAEA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAqDAnpC,IAAE,CAAC0pC,SAAH,GAAe,UAAS7kC,IAAT,EAAeyO,QAAf,EAAyB6W,aAAzB,EAAwC;AACrDnqB,MAAE,CAAC09B,MAAH,CAAUnhC,IAAV,CAAe,IAAf;AAEA;;;;;;;;AAOA,SAAKqsC,kBAAL,GAVqD,CAYrD;;;AACA,SAAKnxC,KAAL,CAAWoG,IAAX,CAAgB3F,KAAhB,GAAwB,GAAxB;;AAEA,QAAI2M,IAAJ,EAAU;AACR,WAAK8kC,QAAL,GAAgB,EAAhB;;AACA,WAAKC,WAAL,CAAiB/kC,IAAjB,EAAuByO,QAAvB,EAAiC6W,aAAjC;AACD,KAHD,MAIK;AACH;AACA,WAAK0e,QAAL,GAAgB,CAAhB;AACA,WAAKC,MAAL,GAAc,CAAd;AACA,WAAKC,QAAL,GAAgB,KAAhB;;AAEA,WAAKC,aAAL;AACD;AAEF,GA5BD;;AA8BAhpC,IAAE,CAAC0pC,SAAH,CAAa3xC,SAAb,GAAyBkC,MAAM,CAACmY,MAAP,CAAcpS,EAAE,CAAC09B,MAAH,CAAU3lC,SAAxB,CAAzB;AAEAiI,IAAE,CAACjI,SAAH,CAAa8xB,qBAAb,CAAmC,iBAAnC,EAAsD7pB,EAAE,CAACjI,SAAzD;AAEA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA0CAiI,IAAE,CAACjI,SAAH,CAAamxC,eAAb,GAA+B,UAASrkC,IAAT,EAAeyO,QAAf,EAAyB6W,aAAzB,EAAwC;AACrE;AACA,QAAIvrB,MAAM,CAACmrB,QAAP,CAAgBC,MAAhB,CAAuBtxB,OAAvB,CAA+B,SAA/B,IAA4C,CAAC,CAA7C,IAAkDkG,MAAM,CAACqrB,OAAP,KAAmB,WAAzE,EAAsF;AACpFC,WAAK,CAAC,2FAAD,CAAL;AACD;;AACD,QAAInO,IAAI,GAAG,IAAX;AACA,QAAI8tB,OAAO,GAAG,IAAI7pC,EAAE,CAAC0pC,SAAP,CAAiB7kC,IAAjB,EAAuB,UAASwB,MAAT,EAAiB;AACpD,UAAI,OAAOiN,QAAP,KAAoB,UAAxB,EAAoC;AAClCA,gBAAQ,CAACjN,MAAD,CAAR;AACD;;AAED,UAAI,OAAO0V,IAAI,CAAC+K,iBAAZ,KAAkC,UAAtC,EAAkD;AAChD/K,YAAI,CAAC+K,iBAAL;AACD;AACF,KARa,EAQXqD,aARW,CAAd;AASA0f,WAAO,CAACF,QAAR,GAAmB,EAAnB;AACA,WAAOE,OAAP;AACD,GAjBD;AAmBA;;;;;;;;;;;AASA7pC,IAAE,CAAC0pC,SAAH,CAAa3xC,SAAb,CAAuB6xC,WAAvB,GAAqC,UAAS/kC,IAAT,EAAeyO,QAAf,EAAyB6W,aAAzB,EAAwC;AAC3E,QAAItlB,IAAI,GAAG7E,EAAE,CAACjI,SAAH,CAAa4M,iBAAb,CAA+BE,IAA/B,CAAX;;AACA,QAAIkX,IAAI,GAAG,IAAX;AACA,QAAIrS,UAAU,GAAG,IAAIG,KAAJ,GAAYI,KAA7B;AACA,QAAIvI,EAAE,GAAG1B,EAAE,CAACjI,SAAH,CAAaob,eAAb,EAAT;AAEA,QAAIiX,OAAO,GAAG,IAAIC,cAAJ,EAAd;AACAD,WAAO,CAACI,IAAR,CAAa,KAAb,EAAoB3lB,IAApB,EAA0B,IAA1B;AACAulB,WAAO,CAACK,YAAR,GAAuB,aAAvB;;AAEAL,WAAO,CAAClC,MAAR,GAAiB,YAAW;AAC1B,UAAIkC,OAAO,CAACM,MAAR,KAAmB,GAAvB,EAA4B;AAC1B;AACAhpB,UAAE,CAACipB,eAAH,CAAmBP,OAAO,CAACQ,QAA3B,EACE,UAASC,IAAT,EAAe;AACb,cAAIxkB,MAAM,GAAG,EAAb;AACA,cAAIyjC,MAAM,GAAGjlC,IAAI,CAACjM,KAAL,CAAW,GAAX,CAAb;AACAyN,gBAAM,CAACoD,IAAP,GAAcqgC,MAAM,CAACA,MAAM,CAAChxC,MAAP,GAAgB,CAAjB,CAApB;AACAuN,gBAAM,CAACP,WAAP,GAAqB+kB,IAArB;AACA9O,cAAI,CAAC4tB,QAAL,CAActvC,IAAd,CAAmBgM,MAAnB;;AACA0V,cAAI,CAACqtB,UAAL,CAAgB/iC,MAAM,CAACP,WAAvB;;AACA,cAAIwN,QAAJ,EAAc;AACZA,oBAAQ,CAACjN,MAAD,CAAR;AACD;AACF,SAXH,EAYE;AACA,oBAAW;AACT,cAAIuD,GAAG,GAAG,IAAIJ,WAAJ,CAAgB,iBAAhB,EAAmCE,UAAnC,EAA+CqS,IAAI,CAACsM,GAApD,CAAV;AACA,cAAIyC,GAAG,GAAG,+CAA+C/O,IAAI,CAACsM,GAA9D;;AACA,cAAI8B,aAAJ,EAAmB;AACjBvgB,eAAG,CAACkhB,GAAJ,GAAUA,GAAV;AACAX,yBAAa,CAACvgB,GAAD,CAAb;AACD,WAHD,MAGO;AACL1K,mBAAO,CAAC6rB,KAAR,CAAcD,GAAG,GAAE,uCAAL,GAA+ClhB,GAAG,CAACK,KAAjE;AACD;AACF,SAtBH;AAwBD,OA1BD,CA2BA;AA3BA,WA4BK;AACH,cAAIL,GAAG,GAAG,IAAIJ,WAAJ,CAAgB,eAAhB,EAAiCE,UAAjC,EAA6CqS,IAAI,CAACsM,GAAlD,CAAV;AACA,cAAIyC,GAAG,GAAG,oBAAoB/O,IAAI,CAACsM,GAAzB,GACR,4BADQ,GACuB+B,OAAO,CAACM,MAD/B,GACwC,IADxC,GAC+CN,OAAO,CAACY,UADvD,GACoE,GAD9E;;AAGA,cAAIb,aAAJ,EAAmB;AACjBvgB,eAAG,CAACqhB,OAAJ,GAAcH,GAAd;AACAX,yBAAa,CAACvgB,GAAD,CAAb;AACD,WAHD,MAGO;AACL1K,mBAAO,CAAC6rB,KAAR,CAAcD,GAAG,GAAE,uCAAL,GAA+ClhB,GAAG,CAACK,KAAjE;AACD;AACF;AACF,KAzCD,CAV2E,CAqD3E;;;AACAmgB,WAAO,CAACjC,OAAR,GAAkB,YAAW;AAC3B,UAAIve,GAAG,GAAG,IAAIJ,WAAJ,CAAgB,eAAhB,EAAiCE,UAAjC,EAA6CqS,IAAI,CAACsM,GAAlD,CAAV;AACA,UAAIyC,GAAG,GAAG,8CAA8C/O,IAAI,CAACsM,GAAnD,GAAyD,4CAAnE;;AAEA,UAAI8B,aAAJ,EAAmB;AACjBvgB,WAAG,CAACqhB,OAAJ,GAAcH,GAAd;AACAX,qBAAa,CAACvgB,GAAD,CAAb;AACD,OAHD,MAGO;AACL1K,eAAO,CAAC6rB,KAAR,CAAcD,GAAG,GAAE,uCAAL,GAA+ClhB,GAAG,CAACK,KAAjE;AACD;AACF,KAVD;;AAWAmgB,WAAO,CAACc,IAAR;AACD,GAlED;;AAoEAlrB,IAAE,CAAC0pC,SAAH,CAAa3xC,SAAb,CAAuBC,GAAvB,GAA6B,IAA7B;AAEA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA8BAgI,IAAE,CAAC0pC,SAAH,CAAa3xC,SAAb,CAAuBsa,OAAvB,GAAiC,UAASC,GAAT,EAAc;AAC7CA,OAAG,CAACtX,OAAJ,CAAY,KAAKvD,KAAjB;AACD,GAFD;AAIA;;;;;;;;;;AAQAuI,IAAE,CAAC0pC,SAAH,CAAa3xC,SAAb,CAAuB4xC,QAAvB,GAAkC,EAAlC;AAEA;;;;;;;;;;;;;AAYA3pC,IAAE,CAAC0pC,SAAH,CAAa3xC,SAAb,CAAuBgyC,UAAvB,GAAoC,UAASllC,IAAT,EAAeyO,QAAf,EAAyB6W,aAAzB,EAAwC;AAC1E;AACA,QAAIvrB,MAAM,CAACmrB,QAAP,CAAgBC,MAAhB,CAAuBtxB,OAAvB,CAA+B,SAA/B,IAA4C,CAAC,CAA7C,IAAkDkG,MAAM,CAACqrB,OAAP,KAAmB,WAAzE,EAAsF;AACpFC,WAAK,CAAC,2FAAD,CAAL;AACD;;AACD,SAAK0f,WAAL,CAAiB/kC,IAAjB,EAAuByO,QAAvB,EAAiC6W,aAAjC;AACD,GAND;AAQA;;;;;;;;;;;;;AAWAnqB,IAAE,CAAC0pC,SAAH,CAAa3xC,SAAb,CAAuBiyC,YAAvB,GAAsC,UAASnlC,IAAT,EAAeyO,QAAf,EAAyB6W,aAAzB,EAAwC;AAC5E;AACA,QAAIvrB,MAAM,CAACmrB,QAAP,CAAgBC,MAAhB,CAAuBtxB,OAAvB,CAA+B,SAA/B,IAA4C,CAAC,CAA7C,IAAkDkG,MAAM,CAACqrB,OAAP,KAAmB,WAAzE,EAAsF;AACpFC,WAAK,CAAC,2FAAD,CAAL;AACD;;AACD,SAAKyf,QAAL,GAAgB,EAAhB;;AACA,SAAKC,WAAL,CAAiB/kC,IAAjB,EAAuByO,QAAvB,EAAiC6W,aAAjC;AACD,GAPD;AASA;;;;;;;;;;;;;;;;;;;;;;AAoBAnqB,IAAE,CAAC0pC,SAAH,CAAa3xC,SAAb,CAAuBkyC,aAAvB,GAAuC,UAASlX,EAAT,EAAa;AAClD,QAAI,OAAOA,EAAP,KAAc,QAAd,IAA0BA,EAAE,GAAG,KAAK4W,QAAL,CAAc7wC,MAAjD,EAAyD;AACvD,WAAKswC,UAAL,CAAgB,KAAKO,QAAL,CAAc5W,EAAd,EAAkBjtB,WAAlC;AACD;;AACD,QAAI,OAAOitB,EAAP,KAAc,QAAlB,EAA4B;AAC1B,WAAK,IAAIl6B,CAAC,GAAG,CAAb,EAAgBA,CAAC,GAAG,KAAK8wC,QAAL,CAAc7wC,MAAlC,EAA0CD,CAAC,EAA3C,EAA+C;AAC7C,YAAI,KAAK8wC,QAAL,CAAc9wC,CAAd,EAAiB4Q,IAAjB,KAA0BspB,EAA9B,EAAkC;AAChC,eAAKqW,UAAL,CAAgB,KAAKO,QAAL,CAAc9wC,CAAd,EAAiBiN,WAAjC;;AACA;AACD;AACF;AACF;AACF,GAZD;;AAcA9F,IAAE,CAAC0pC,SAAH,CAAa3xC,SAAb,CAAuB8C,OAAvB,GAAiC,YAAW;AAC1CmF,MAAE,CAAC09B,MAAH,CAAU3lC,SAAV,CAAoB8C,OAApB,CAA4BU,KAA5B,CAAkC,IAAlC,EAD0C,CAG1C;;AACA,SAAK,IAAI1C,CAAT,IAAc,KAAK8wC,QAAnB,EAA6B;AAC3B,UAAI,KAAKA,QAAL,CAAc9wC,CAAd,CAAJ,EAAsB;AACpB,aAAK8wC,QAAL,CAAc9wC,CAAd,IAAmB,IAAnB;AACD;AACF;AACF,GATD;AAWD,CAziBK;AAAA,oGAAN,C;;;;;;;ACFA,kCAAa;;AAEb1B,mCAAO,UAAUoK,OAAV,EAAmB;AACxB,MAAIxB,OAAO,GAAGwB,mBAAO,CAAC,CAAD,CAArB,CADwB,CAGxB;AACA;;;AACA,MAAI8d,KAAK,GAAG9d,mBAAO,CAAC,EAAD,CAAnB;;AAEAvB,IAAE,CAACkqC,KAAH,GAAW,YAAW;AACpB,SAAKC,KAAL,GAAa,IAAI9qB,KAAJ,CAAU;AACrB,kBAAY,KAAK+qB,MAAL,CAAY7+B,IAAZ,CAAiB,IAAjB;AADS,KAAV,CAAb;AAGA,SAAK8+B,WAAL,GAAmB,EAAnB;AACA,SAAKjwB,GAAL,GAAW,GAAX,CALoB,CAKJ;;AAChB,SAAKiiB,KAAL;;AAEA,SAAKiO,QAAL,GAAgB,CAAhB;AACA,SAAKC,SAAL,GAAiB,CAAjB;;AAEA,SAAKC,YAAL,GAAoB,YAAW,CAAE,CAAjC;AACD,GAZD;;AAcAxqC,IAAE,CAACkqC,KAAH,CAASnyC,SAAT,CAAmBqyC,MAAnB,GAA4B,UAASlqB,QAAT,EAAmB;AAC7C,QAAIuqB,WAAW,GAAGvqB,QAAQ,GAAG,KAAKoqB,QAAlC;AACA,QAAIvpB,cAAc,GAAGb,QAAQ,GAAGngB,OAAO,CAACZ,YAAR,CAAqBkB,WAArD;;AACA,QAAIoqC,WAAW,GAAG,KAAKF,SAAnB,IAAgC,CAAC,IAArC,EAA2C;AACzC;AACD,KAFD,MAEO;AACL;AACA,WAAKD,QAAL,GAAgBpqB,QAAhB,CAFK,CAIL;;AACA,UAAInE,IAAI,GAAG,IAAX;AACA,WAAKsuB,WAAL,CAAiBxrB,OAAjB,CAAyB,UAAS6rB,QAAT,EAAmB;AAC1C,YAAI,CAACA,QAAQ,CAAC5e,SAAd,EAAyB;AACzB4e,gBAAQ,CAACC,aAAT,CAAuB5pB,cAAvB,EAF0C,CAG1C;;AACA2pB,gBAAQ,CAACE,OAAT,CAAiB/rB,OAAjB,CAAyB,UAASgsB,UAAT,EAAqB;AAC5C,cAAIC,WAAW,GAAGD,UAAU,CAACE,QAA7B;AACA,cAAIC,IAAI,GAAGjvB,IAAI,CAACkvB,UAAL,GAAkBH,WAAW,CAAChyC,MAAzC;;AACA,cAAIgyC,WAAW,CAACE,IAAD,CAAX,KAAsB,CAAtB,KAA4BjvB,IAAI,CAACkvB,UAAL,GAAkBH,WAAW,CAAChyC,MAA9B,IAAwC,CAAC+xC,UAAU,CAACK,OAAhF,CAAJ,EAA+F;AAC7FL,sBAAU,CAACv3B,QAAX,CAAoByN,cAApB,EAAoC+pB,WAAW,CAACE,IAAD,CAA/C;AACD;AACF,SAND;AAOD,OAXD;AAYA,WAAKC,UAAL,IAAmB,CAAnB;AACA,WAAKT,YAAL,CAAkBzpB,cAAlB;AACD;AACF,GA1BD;;AA4BA/gB,IAAE,CAACkqC,KAAH,CAASnyC,SAAT,CAAmBozC,MAAnB,GAA4B,UAAS/wB,GAAT,EAAcjiB,QAAd,EAAwB;AAClD,QAAIizC,QAAQ,GAAI,MAAMhxB,GAAG,GAAC,KAAKixB,MAAf,CAAhB;AACA,QAAIntC,GAAG,GAAG6B,OAAO,CAACZ,YAAR,CAAqBkB,WAA/B;AACA,SAAKkqC,SAAL,GAAiBa,QAAjB;AAEA,QAAIjzC,QAAQ,GAAGA,QAAQ,IAAI,CAA3B;AACA,SAAKgyC,KAAL,CAAW33B,SAAX,CAAqBxD,cAArB,CAAoC,KAAKm7B,KAAL,CAAW33B,SAAX,CAAqBta,KAAzD,EAAgEgG,GAAhE;AACA,SAAKisC,KAAL,CAAW33B,SAAX,CAAqBhS,uBAArB,CAA6C4Z,GAA7C,EAAkDlc,GAAG,GAAG/F,QAAxD;AACA,SAAKiiB,GAAL,GAAWA,GAAX;AACD,GATD;;AAWApa,IAAE,CAACkqC,KAAH,CAASnyC,SAAT,CAAmBuzC,MAAnB,GAA4B,YAAW;AACrC,WAAO,KAAKnB,KAAL,CAAWoB,OAAX,KAAuB,KAAKF,MAA5B,GAAqC,EAA5C;AACD,GAFD;;AAIArrC,IAAE,CAACkqC,KAAH,CAASnyC,SAAT,CAAmBskC,KAAnB,GAA2B,YAAW;AACpC,SAAK4O,UAAL,GAAkB,CAAlB,CADoC,CAEpC;AACD,GAHD,CAhEwB,CAqExB;;;AACAjrC,IAAE,CAACkqC,KAAH,CAASnyC,SAAT,CAAmByzC,SAAnB,GAA+B,UAASC,IAAT,EAAe;AAC5C,SAAKpB,WAAL,GAAmB,CAACoB,IAAD,CAAnB;AACD,GAFD,CAtEwB,CA0ExB;;;AACAzrC,IAAE,CAACkqC,KAAH,CAASnyC,SAAT,CAAmB2zC,QAAnB,GAA8B,UAASD,IAAT,EAAe;AAC3C,SAAKpB,WAAL,CAAiBhwC,IAAjB,CAAsBoxC,IAAtB;AACD,GAFD;;AAIAzrC,IAAE,CAACkqC,KAAH,CAASnyC,SAAT,CAAmB6U,KAAnB,GAA2B,UAASiW,WAAT,EAAsB;AAC/C,QAAIzR,CAAC,GAAGyR,WAAW,IAAI,CAAvB;AACA,QAAI3kB,GAAG,GAAG6B,OAAO,CAACZ,YAAR,CAAqBkB,WAA/B;AACA,SAAK8pC,KAAL,CAAWv9B,KAAX,CAAiB1O,GAAG,GAAGkT,CAAvB;AACA,SAAK+5B,MAAL,CAAY,KAAK/wB,GAAjB;AACD,GALD;;AAOApa,IAAE,CAACkqC,KAAH,CAASnyC,SAAT,CAAmB6jB,IAAnB,GAA0B,UAASiH,WAAT,EAAsB;AAC9C,QAAIzR,CAAC,GAAGyR,WAAW,IAAI,CAAvB;AACA,QAAI3kB,GAAG,GAAG6B,OAAO,CAACZ,YAAR,CAAqBkB,WAA/B;AACA,SAAK8pC,KAAL,CAAWvuB,IAAX,CAAgB1d,GAAG,GAAGkT,CAAtB;AACD,GAJD;;AAMApR,IAAE,CAACkqC,KAAH,CAASnyC,SAAT,CAAmB4zC,UAAnB,GAAgC,UAASN,MAAT,EAAiB;AAC/C,SAAKA,MAAL,GAAc,IAAEA,MAAF,GAAW,CAAzB,CAD+C,CACnB;AAC7B,GAFD;AAID,CAhGK;AAAA,oGAAN,C;;;;;;ACFAl0C,iGAAO,CAAC,sBAAgB,CAAE,uBAAoB,CAAE,sBAAgB,CAAC,mCAAE,SAAUC,GAE5E,aAoDA,OA1CAA,EAAKqoB,cAAgB,SAASmsB,GAE7Bx0C,EAAKiX,SAAS9R,KAAKhF,MAOnBA,KAAK+W,SAAWs9B,GAGjBx0C,EAAK+G,OAAO/G,EAAKqoB,cAAeroB,EAAKiX,UAQrCjX,EAAKqoB,cAAc1nB,UAAU8W,eAAiB,SAASjG,GACtD,IAAI+K,EAAQpc,KAAKgC,IAAIqP,GACrB,OAAc,OAAV+K,EACIA,EAAMiM,MAENroB,KAAK+W,UAUdlX,EAAKqoB,cAAc1nB,UAAU8nB,eAAiB,SAASD,EAAOhX,GAC7DrR,KAAK2X,IAAI,CACR0Q,MAAUA,EACVhX,KAASA,KAIJxR,EAAKqoB;AAAAA,qG;;;;;;;ACtDb,kCAAa;;AAEbtoB,mCAAO,UAASoK,OAAT,EAAkB;AACvB,MAAIxB,OAAO,GAAGwB,mBAAO,CAAC,CAAD,CAArB;;AAEA,MAAIwG,GAAG,GAAG,GAAV;AAEA;;;;;;;;;;AASA/H,IAAE,CAACjI,SAAH,CAAaozC,MAAb,GAAsB,UAAS/wB,GAAT,EAAcjiB,QAAd,EAAwB;AAC5C4P,OAAG,GAAGqS,GAAN;;AACA,SAAK,IAAIvhB,CAAT,IAAckH,OAAO,CAACF,KAAtB,EAA6B;AAC3B,UAAIE,OAAO,CAACF,KAAR,CAAchH,CAAd,CAAJ,EAAsB;AACpBkH,eAAO,CAACF,KAAR,CAAchH,CAAd,EAAiBsyC,MAAjB,CAAwB/wB,GAAxB,EAA6BjiB,QAA7B;AACD;AACF;AACF,GAPD;AASA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAsEA6H,IAAE,CAAC6rC,MAAH,GAAY,UAASpiC,IAAT,EAAe6J,QAAf,EAAyBy3B,QAAzB,EAAmC;AAC7C,SAAKe,UAAL,GAAkB,CAAlB;AACA,SAAKriC,IAAL,GAAYA,IAAZ;AACA,SAAK6J,QAAL,GAAgBA,QAAhB;AACA;;;;;;;;;;AASA,SAAKy3B,QAAL,GAAgBA,QAAhB;AACD,GAdD;AAgBA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA4DA/qC,IAAE,CAAC+rC,IAAH,GAAU,UAASC,KAAT,EAAgBC,OAAhB,EAAyB;AACjC,SAAKnzC,MAAL,GAAckzC,KAAK,IAAI,CAAvB,CADiC,CACP;;AAC1B,SAAKE,QAAL,GAAgB,CAAhB;AACA,SAAKtB,OAAL,GAAe,EAAf;AACA,SAAK9e,SAAL,GAAiB,KAAjB;AACA,SAAKqgB,MAAL;AACA,SAAKd,MAAL,GAAcY,OAAO,IAAI,MAAzB,CANiC,CAMA;;AAEjC,SAAKG,KAAL,GAAa,IAAIpsC,EAAE,CAACkqC,KAAP,EAAb;;AACA,SAAKkC,KAAL,CAAW/P,KAAX;;AACA,SAAK+P,KAAL,CAAWT,UAAX,CAAsB,KAAKN,MAA3B;AACA,SAAKe,KAAL,CAAWjB,MAAX,CAAkBpjC,GAAlB;AACAhI,WAAO,CAACF,KAAR,CAAcxF,IAAd,CAAmB,IAAnB;;AACA,SAAKiZ,QAAL,GAAgB,YAAW,CAAE,CAA7B;AACD,GAdD;AAgBA;;;;;;;;;;AAQAtT,IAAE,CAAC+rC,IAAH,CAAQh0C,SAAR,CAAkBozC,MAAlB,GAA2B,UAASla,KAAT,EAAgB94B,QAAhB,EAA0B;AACnD,SAAKi0C,KAAL,CAAWjB,MAAX,CAAkBla,KAAlB,EAAyB94B,QAAzB;AACD,GAFD;AAIA;;;;;;;;;AAOA6H,IAAE,CAAC+rC,IAAH,CAAQh0C,SAAR,CAAkBuzC,MAAlB,GAA2B,YAAW;AACpC,WAAO,KAAKc,KAAL,CAAWd,MAAX,EAAP;AACD,GAFD;AAIA;;;;;;;;;;;AASAtrC,IAAE,CAAC+rC,IAAH,CAAQh0C,SAAR,CAAkB6U,KAAlB,GAA0B,UAAShE,IAAT,EAAe;AACvC,QAAI,CAAC,KAAKkjB,SAAV,EAAqB;AACnB,WAAKA,SAAL,GAAiB,IAAjB;AACA,WAAKsgB,KAAL,CAAWZ,SAAX,CAAqB,IAArB;AACA,UAAIp6B,CAAC,GAAGxI,IAAI,IAAI,CAAhB;AACA,WAAKwjC,KAAL,CAAWx/B,KAAX,CAAiBwE,CAAjB;AACD;AACF,GAPD;AASA;;;;;;;;;;;AASApR,IAAE,CAAC+rC,IAAH,CAAQh0C,SAAR,CAAkB4U,IAAlB,GAAyB,UAAS/D,IAAT,EAAe;AACtC,SAAKsiC,OAAL,GAAe,IAAf,CADsC,CAEtC;;AACA,SAAK9c,OAAL,GAAe,YAAW;AACxB,WAAK8d,QAAL,GAAgB,CAAhB;AACD,KAFD;;AAGA,QAAI96B,CAAC,GAAGxI,IAAI,IAAI,CAAhB;AACA,SAAKgE,KAAL,CAAWwE,CAAX;AACD,GARD;AAUA;;;;;;;;AAMApR,IAAE,CAAC+rC,IAAH,CAAQh0C,SAAR,CAAkBo0C,MAAlB,GAA2B,YAAW;AACpC,SAAKjB,OAAL,GAAe,KAAf,CADoC,CAEpC;;AACA,SAAK9c,OAAL,GAAe,YAAW;AACxB,WAAKxS,IAAL;AACD,KAFD;AAGD,GAND;AAQA;;;;;;;;;AAOA5b,IAAE,CAAC+rC,IAAH,CAAQh0C,SAAR,CAAkB6jB,IAAlB,GAAyB,UAAShT,IAAT,EAAe;AACtC,SAAKsjC,QAAL,GAAgB,CAAhB;AACA,SAAKpsB,KAAL,CAAWlX,IAAX;AACD,GAHD;AAKA;;;;;;;;;;AAQA5I,IAAE,CAAC+rC,IAAH,CAAQh0C,SAAR,CAAkB+nB,KAAlB,GAA0B,UAASlX,IAAT,EAAe;AACvC,SAAKkjB,SAAL,GAAiB,KAAjB;AACA,QAAI1a,CAAC,GAAGxI,IAAI,IAAI,CAAhB;AACA,SAAKwjC,KAAL,CAAWxwB,IAAX,CAAgBxK,CAAhB;AACD,GAJD;AAMA;;;;;;;;;AAOApR,IAAE,CAAC+rC,IAAH,CAAQh0C,SAAR,CAAkBs0C,SAAlB,GAA8B,UAAS5iC,IAAT,EAAe6J,QAAf,EAAyBg5B,KAAzB,EAAgC;AAC5D,QAAIjnC,CAAJ;;AACA,QAAI7J,SAAS,CAAC1C,MAAV,KAAqB,CAAzB,EAA4B;AAC1BuM,OAAC,GAAG,IAAIrF,EAAE,CAAC6rC,MAAP,CAAcpiC,IAAd,EAAoB6J,QAApB,EAA8Bg5B,KAA9B,CAAJ;AACD,KAFD,MAEO,IAAI9wC,SAAS,CAAC,CAAD,CAAT,YAAwBwE,EAAE,CAAC6rC,MAA/B,EAAuC;AAC5CxmC,OAAC,GAAG7J,SAAS,CAAC,CAAD,CAAb;AACD,KAFM,MAEA;AACL,YAAM,uEAAN;AACD;;AACD,SAAKovC,OAAL,CAAavwC,IAAb,CAAkBgL,CAAlB,EAT4D,CAU5D;;AACA,QAAIA,CAAC,CAAC0lC,QAAF,CAAWjyC,MAAX,GAAoB,KAAKA,MAA7B,EAAqC;AACnC,WAAKA,MAAL,GAAcuM,CAAC,CAAC0lC,QAAF,CAAWjyC,MAAzB;AACD;AACF,GAdD;AAgBA;;;;;;;;;;AAQAkH,IAAE,CAAC+rC,IAAH,CAAQh0C,SAAR,CAAkBw0C,YAAlB,GAAiC,UAAS9iC,IAAT,EAAe;AAC9C,SAAK,IAAI5Q,CAAT,IAAc,KAAK+xC,OAAnB,EAA4B;AAC1B,UAAI,KAAKA,OAAL,CAAa/xC,CAAb,EAAgB4Q,IAAhB,KAAyBA,IAA7B,EAAmC;AACjC,aAAKmhC,OAAL,CAAa7xC,MAAb,CAAoBF,CAApB,EAAuB,CAAvB;AACD;AACF;AACF,GAND;AAQA;;;;;;;;;;AAQAmH,IAAE,CAAC+rC,IAAH,CAAQh0C,SAAR,CAAkBy0C,SAAlB,GAA8B,UAAS/iC,IAAT,EAAe;AAC3C,SAAK,IAAI5Q,CAAT,IAAc,KAAK+xC,OAAnB,EAA4B;AAC1B,UAAI,KAAKA,OAAL,CAAa/xC,CAAb,EAAgB4Q,IAAhB,KAAyBA,IAA7B,EAAmC;AACjC,eAAO,KAAKmhC,OAAL,CAAa/xC,CAAb,CAAP;AACD;AACF;AACF,GAND;AAQA;;;;;;;;;;;AASAmH,IAAE,CAAC+rC,IAAH,CAAQh0C,SAAR,CAAkB00C,eAAlB,GAAoC,UAAShjC,IAAT,EAAe6iC,KAAf,EAAsB;AACxD,SAAK,IAAIzzC,CAAT,IAAc,KAAK+xC,OAAnB,EAA4B;AAC1B,UAAI,KAAKA,OAAL,CAAa/xC,CAAb,EAAgB4Q,IAAhB,KAAyBA,IAA7B,EAAmC;AACjC,aAAKmhC,OAAL,CAAa/xC,CAAb,EAAgBkyC,QAAhB,GAA2BuB,KAA3B;AACD;AACF;AACF,GAND;;AAQAtsC,IAAE,CAAC+rC,IAAH,CAAQh0C,SAAR,CAAkB4yC,aAAlB,GAAkC,UAAS/hC,IAAT,EAAe;AAC/C,QAAI,KAAKsjC,QAAL,GAAgB,KAAKpzC,MAAL,GAAc,CAAlC,EAAqC;AACnC,WAAKwa,QAAL,CAAc1K,IAAd;AACA,WAAKsjC,QAAL,IAAiB,CAAjB;AACD,KAHD,MAGO;AACL,UAAI,CAAC,KAAKhB,OAAN,IAAiB,KAAKgB,QAAL,KAAkB,KAAKpzC,MAAL,GAAc,CAArD,EAAwD;AACtDoG,eAAO,CAACpB,GAAR,CAAY,MAAZ,EADsD,CAEtD;;AACA,aAAKswB,OAAL;AACD;AACF;AACF,GAXD;AAaA;;;;;;;;;;;AASApuB,IAAE,CAAC+rC,IAAH,CAAQh0C,SAAR,CAAkB20C,MAAlB,GAA2B,UAASp5B,QAAT,EAAmB;AAC5C,SAAKA,QAAL,GAAgBA,QAAhB;AACD,GAFD,CA3XuB,CAgYvB;AACA;AACA;;AAEA;;;;;;;;;;;;AAUAtT,IAAE,CAAC2sC,KAAH,GAAW,YAAW;AACpB;AACA,SAAK9sC,KAAL,GAAa,EAAb;AACA,SAAK+sC,WAAL,GAAmB,CAAnB;AAEA,QAAIC,SAAS,GAAG,IAAhB;;AACA,SAAK,IAAIh0C,CAAT,IAAc2C,SAAd,EAAyB;AACvB,UAAIA,SAAS,CAAC3C,CAAD,CAAT,IAAgB,KAAKgH,KAAL,CAAWhH,CAAX,CAApB,EAAmC;AACjC,aAAKgH,KAAL,CAAWhH,CAAX,IAAgB2C,SAAS,CAAC3C,CAAD,CAAzB;AACA,aAAKgH,KAAL,CAAWhH,CAAX,EAAci0C,QAAd,GAAyB,KAAKjtC,KAAL,CAAWhH,CAAC,GAAG,CAAf,CAAzB;;AACA,aAAKgH,KAAL,CAAWhH,CAAX,EAAcu1B,OAAd,GAAwB,YAAW;AACjCye,mBAAS,CAACE,SAAV,CAAoBl0C,CAApB;AACAm0C,sBAAY,CAACH,SAAD,CAAZ;AACD,SAHD;AAID;AACF;;AACD,SAAK3B,OAAL,GAAe,KAAf;AACD,GAjBD;;AAmBAlrC,IAAE,CAAC2sC,KAAH,CAAS50C,SAAT,CAAmBq2B,OAAnB,GAA6B,YAAW;AACtC,QAAI,KAAK8c,OAAT,EAAkB;AAChB;AACA,WAAKrrC,KAAL,CAAW,CAAX,EAAc+M,KAAd;AACD,KAHD,MAGO;AACL,WAAK/M,KAAL,CAAW,KAAKA,KAAL,CAAW/G,MAAX,GAAoB,CAA/B,EAAkCs1B,OAAlC,GAA4C,YAAW;AACrD,aAAKxS,IAAL;AACA,aAAKqxB,UAAL;AACD,OAHD;AAID;;AACD,SAAKL,WAAL,GAAmB,CAAnB;AACD,GAXD;AAaA;;;;;;;;AAMA5sC,IAAE,CAAC2sC,KAAH,CAAS50C,SAAT,CAAmB6U,KAAnB,GAA2B,YAAW;AACpC,SAAK/M,KAAL,CAAW,KAAK+sC,WAAhB,EAA6BhgC,KAA7B;AACA,SAAKsgC,SAAL,GAAiB,CAAjB;AACD,GAHD;AAKA;;;;;;;;AAMAltC,IAAE,CAAC2sC,KAAH,CAAS50C,SAAT,CAAmB6jB,IAAnB,GAA0B,YAAW;AACnC,SAAK/b,KAAL,CAAW,KAAK+sC,WAAhB,EAA6BhxB,IAA7B;AACA,SAAKgxB,WAAL,GAAmB,CAAnB;AACA,SAAKM,SAAL,GAAiB,CAAjB;AACD,GAJD;AAMA;;;;;;;;AAMAltC,IAAE,CAAC2sC,KAAH,CAAS50C,SAAT,CAAmB+nB,KAAnB,GAA2B,YAAW;AACpC,SAAKjgB,KAAL,CAAW,KAAK+sC,WAAhB,EAA6BhxB,IAA7B;AACD,GAFD;AAIA;;;;;;;;AAMA5b,IAAE,CAAC2sC,KAAH,CAAS50C,SAAT,CAAmB4U,IAAnB,GAA0B,YAAW;AACnC,SAAKu+B,OAAL,GAAe,IAAf;AACA,SAAKt+B,KAAL;AACD,GAHD;AAKA;;;;;;;;;;AAQA5M,IAAE,CAAC2sC,KAAH,CAAS50C,SAAT,CAAmBo0C,MAAnB,GAA4B,YAAW;AACrC,SAAKjB,OAAL,GAAe,KAAf;AACD,GAFD;;AAIAlrC,IAAE,CAAC2sC,KAAH,CAAS50C,SAAT,CAAmBk1C,UAAnB,GAAgC,YAAW;AACzC,QAAIlxB,IAAI,GAAG,IAAX;AACA,SAAKlc,KAAL,CAAWgf,OAAX,CAAmB,UAAS4sB,IAAT,EAAe;AAChC1vB,UAAI,CAACkxB,UAAL,CAAgBxB,IAAhB;AACD,KAFD;AAGD,GALD;;AAOAzrC,IAAE,CAAC2sC,KAAH,CAAS50C,SAAT,CAAmBg1C,SAAnB,GAA+B,UAASl0C,CAAT,EAAY;AACzC,SAAKgH,KAAL,CAAWhH,CAAX,EAAc+iB,IAAd;AACA,SAAK/b,KAAL,CAAWhH,CAAX,EAAcqzC,QAAd,GAAyB,CAAzB;;AACA,SAAK,IAAI7mC,CAAT,IAAc,KAAKxF,KAAL,CAAWhH,CAAX,EAAc+xC,OAA5B,EAAqC;AACnC,UAAI,KAAK/qC,KAAL,CAAWhH,CAAX,CAAJ,EAAmB;AACjB,aAAKgH,KAAL,CAAWhH,CAAX,EAAc+xC,OAAd,CAAsBvlC,CAAtB,EAAyBymC,UAAzB,GAAsC,CAAtC;AACD;AACF;AACF,GARD;AAUA;;;;;;;;;;AAQA9rC,IAAE,CAAC2sC,KAAH,CAAS50C,SAAT,CAAmBozC,MAAnB,GAA4B,UAAS/wB,GAAT,EAAcjiB,QAAd,EAAwB;AAClD,SAAK,IAAIU,CAAT,IAAc,KAAKgH,KAAnB,EAA0B;AACxB,UAAI,KAAKA,KAAL,CAAWhH,CAAX,CAAJ,EAAmB;AACjB,aAAKgH,KAAL,CAAWhH,CAAX,EAAcsyC,MAAd,CAAqB/wB,GAArB,EAA0BjiB,QAA1B;AACD;AACF;AACF,GAND;;AAQA,WAAS60C,YAAT,CAAsBG,MAAtB,EAA8B;AAC5BA,UAAM,CAACP,WAAP;;AACA,QAAIO,MAAM,CAACP,WAAP,IAAsBO,MAAM,CAACttC,KAAP,CAAa/G,MAAvC,EAA+C;AAC7Cq0C,YAAM,CAACD,SAAP,GAAmB,CAAnB;AACAC,YAAM,CAAC/e,OAAP;AACD,KAHD,MAGO;AACL+e,YAAM,CAACD,SAAP,GAAmB,CAAnB;AACAC,YAAM,CAACttC,KAAP,CAAastC,MAAM,CAACP,WAAP,GAAqB,CAAlC,EAAqChxB,IAArC;AACAuxB,YAAM,CAACttC,KAAP,CAAastC,MAAM,CAACP,WAApB,EAAiChgC,KAAjC;AACD;AACF;AAEF,CAnhBK;AAAA,oGAAN,C;;;;;;;ACFA,kCAAa;;AAEbzV,mCAAO,UAAUoK,OAAV,EAAmB;AACxB,MAAIxB,OAAO,GAAGwB,mBAAO,CAAC,CAAD,CAArB;;AACA,MAAI8d,KAAK,GAAG9d,mBAAO,CAAC,EAAD,CAAnB;AAEA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAmCAvB,IAAE,CAACotC,SAAH,GAAe,UAAS95B,QAAT,EAAmBrV,QAAnB,EAA6B;AAC1C,SAAKqV,QAAL,GAAgBA,QAAhB;AACA;;;;;;AAKA,SAAK+5B,eAAL,GAAuB,OAAO,KAAKC,SAAZ,KAA0B,QAA1B,GAAqC,KAArC,GAA6C,IAApE;AAEA,SAAKA,SAAL,GAAiBrvC,QAAQ,IAAI,CAA7B;AAEA;;;;;AAIA,SAAK2Y,cAAL,GAAsB,CAAtB;AACA,SAAK22B,IAAL,GAAY,EAAZ;AAEA,SAAKzhB,SAAL,GAAiB,KAAjB;AAEA;;;;;AAIA,SAAK0hB,aAAL,GAAqBvvB,QAArB;AACA,QAAIlC,IAAI,GAAG,IAAX;AAEA,SAAKouB,KAAL,GAAa,IAAI9qB,KAAJ,CAAU;AACrB,kBAAa,kBAASzW,IAAT,EAAe;AAC1B,YAAIia,WAAW,GAAGja,IAAI,GAAG7I,OAAO,CAACZ,YAAR,CAAqBkB,WAA9C;AACA;;;;;;;;AAOA,YAAIwiB,WAAW,GAAG,CAAd,IAAmB9G,IAAI,CAAC0xB,UAAL,IAAmB1xB,IAAI,CAACyxB,aAA/C,EAA8D;AAC5DzxB,cAAI,CAACzI,QAAL,CAAcuP,WAAd;AAA4B;AAC/B,OAZoB;AAarB,mBAAc,KAAK6qB,SAAL;AAbO,KAAV,CAAb;AAeD,GA1CD;AA4CA;;;;;;;;AAMA1tC,IAAE,CAACotC,SAAH,CAAar1C,SAAb,CAAuB6U,KAAvB,GAA+B,UAASiW,WAAT,EAAsB;AACnD,QAAIzR,CAAC,GAAGyR,WAAW,IAAI,CAAvB;AACA,QAAI3kB,GAAG,GAAG6B,OAAO,CAACZ,YAAR,CAAqBkB,WAA/B;;AACA,QAAI,CAAC,KAAKyrB,SAAV,EAAqB;AACnB,WAAKqe,KAAL,CAAWv9B,KAAX,CAAiB1O,GAAG,GAAGkT,CAAvB;AACA,WAAK0a,SAAL,GAAiB,IAAjB;AACD;AACF,GAPD;AASA;;;;;;;;AAMA9rB,IAAE,CAACotC,SAAH,CAAar1C,SAAb,CAAuB6jB,IAAvB,GAA8B,UAASiH,WAAT,EAAsB;AAClD,QAAIzR,CAAC,GAAGyR,WAAW,IAAI,CAAvB;AACA,QAAI3kB,GAAG,GAAG6B,OAAO,CAACZ,YAAR,CAAqBkB,WAA/B;;AACA,QAAI,KAAKyrB,SAAT,EAAoB;AAClB,WAAKqe,KAAL,CAAWvuB,IAAX,CAAgB1d,GAAG,GAAGkT,CAAtB;AACA,WAAK0a,SAAL,GAAiB,KAAjB;AACD;AACF,GAPD;AAQA;;;;;;;;AAMA9rB,IAAE,CAACotC,SAAH,CAAar1C,SAAb,CAAuB+nB,KAAvB,GAAgC,UAAS+C,WAAT,EAAsB;AACpD,QAAIzR,CAAC,GAAGyR,WAAW,IAAI,CAAvB;AACA,QAAI3kB,GAAG,GAAG6B,OAAO,CAACZ,YAAR,CAAqBkB,WAA/B;;AACA,QAAI,KAAKyrB,SAAT,EAAoB;AAClB,WAAKqe,KAAL,CAAWrqB,KAAX,CAAiB5hB,GAAG,GAAGkT,CAAvB;AACA,WAAK0a,SAAL,GAAiB,KAAjB;AACD;AACF,GAPD;AAUA;;;;;;;;;;;;;AAWA9rB,IAAE,CAACotC,SAAH,CAAar1C,SAAb,CAAuB41C,WAAvB,GAAqC,UAASC,SAAT,EAAoB/qB,WAApB,EAAiC;AACpE,QAAIzR,CAAC,GAAGyR,WAAW,IAAI,CAAvB;AACA,QAAI3kB,GAAG,GAAG6B,OAAO,CAACZ,YAAR,CAAqBkB,WAA/B;;AAEA,QAAI,CAACutC,SAAS,CAAC9hB,SAAf,EAA0B;AACxB8hB,eAAS,CAACzD,KAAV,CAAgBv9B,KAAhB,CAAsB1O,GAAG,GAAGkT,CAA5B;AACAw8B,eAAS,CAAC9hB,SAAV,GAAsB,IAAtB;AACA,WAAKqe,KAAL,CAAWv9B,KAAX,CAAiB1O,GAAG,GAAGkT,CAAvB;AACA,WAAK0a,SAAL,GAAiB,IAAjB;AACD,KALD,MAKO,IAAI8hB,SAAS,CAAC9hB,SAAd,EAAyB;AAC9B,UAAIljB,IAAI,GAAGglC,SAAS,CAACzD,KAAV,CAAgB7qB,SAAhB,GAA4Bvf,OAAO,CAACZ,YAAR,CAAqBkB,WAA5D;AACA,WAAK8pC,KAAL,CAAWv9B,KAAX,CAAiB1O,GAAG,GAAG0K,IAAvB;AACA,WAAKkjB,SAAL,GAAiB,IAAjB;AACD;AACF,GAdD;AAiBA;;;;;;;;AAMA9rB,IAAE,CAACotC,SAAH,CAAar1C,SAAb,CAAuB81C,OAAvB,GAAiC,YAAW;AAC1C,SAAK1D,KAAL,CAAW33B,SAAX,CAAqBta,KAArB,GAA6B,KAAKw1C,SAAL,EAA7B;AACD,GAFD;AAIA;;;;;;;;;AAOA1tC,IAAE,CAACotC,SAAH,CAAar1C,SAAb,CAAuB21C,SAAvB,GAAmC,YAAW;AAC5C;AACA,QAAI,OAAO,KAAKJ,SAAZ,KAA0B,QAA9B,EAAwC;AACtC,WAAKD,eAAL,GAAuB,KAAvB;AACA,aAAO,IAAI,KAAKC,SAAhB;AACD,KAHD,CAIA;AAJA,SAKK,IAAI,OAAO,KAAKA,SAAZ,KAA0B,QAA9B,EAAwC;AAC3C,aAAKD,eAAL,GAAuB,IAAvB;AACA,eAAO,KAAKE,IAAL,GAAY,EAAZ,GAAiB,KAAKO,gBAAL,CAAsB,KAAKR,SAA3B,CAAjB,IAA0D,KAAK12B,cAAL,GAAsB,CAAhF,CAAP;AACD;AACF,GAXD;AAaA;;;;;;;;;;;AASA5W,IAAE,CAACotC,SAAH,CAAar1C,SAAb,CAAuB+1C,gBAAvB,GAA0C,UAAS51C,KAAT,EAAgB;AACxD,QAAIyN,IAAI,GAAGzN,KAAK,CAACoM,KAAN,CAAY,CAAC,CAAb,CAAX;AACApM,SAAK,GAAG61C,MAAM,CAAC71C,KAAK,CAACoM,KAAN,CAAY,CAAZ,EAAc,CAAC,CAAf,CAAD,CAAd;;AACA,YAAQqB,IAAR;AACE,WAAK,GAAL;AACE,eAAO,KAAKqoC,QAAL,CAAc91C,KAAd,CAAP;;AACF,WAAK,GAAL;AACE,eAAO,KAAK6qB,KAAL,CAAW7qB,KAAX,CAAP;;AACF;AACEgH,eAAO,CAACkO,IAAR,CAAa,gEACb,6EADA;AANJ;AASD,GAZD;AAcA;;;;;;;;AAMApN,IAAE,CAACotC,SAAH,CAAar1C,SAAb,CAAuBi2C,QAAvB,GAAkC,UAAS91C,KAAT,EAAgB;AAChD,WAAOA,KAAK,GAAG,KAAK0e,cAApB;AACD,GAFD;AAIA;;;;;;;AAKA5W,IAAE,CAACotC,SAAH,CAAar1C,SAAb,CAAuBgrB,KAAvB,GAA+B,UAAS7qB,KAAT,EAAgB;AAC7C,WAAO,KAAK0e,cAAL,GAAsB1e,KAA7B;AACD,GAFD;AAKA;;;;;;;;;AAOA+B,QAAM,CAACU,cAAP,CAAsBqF,EAAE,CAACotC,SAAH,CAAar1C,SAAnC,EAA8C,KAA9C,EAAqD;AACnDwB,OAAG,EAAG,eAAW;AACf,aAAO,KAAKg0C,IAAZ;AACD,KAHkD;AAInDv1C,OAAG,EAAG,aAASoiB,GAAT,EAAc;AAClB,UAAI,CAAC,KAAKizB,eAAV,EAA2B;AACzBnuC,eAAO,CAACkO,IAAR,CAAa,uDACO,0CADP,GAEO,6CAFP,GAGO,0BAHpB;AAID;;AACD,WAAKmgC,IAAL,GAAYnzB,GAAZ;;AACA,WAAKyzB,OAAL;AACD;AAbkD,GAArD;AAgBA;;;;;;AAKA5zC,QAAM,CAACU,cAAP,CAAsBqF,EAAE,CAACotC,SAAH,CAAar1C,SAAnC,EAA8C,eAA9C,EAA+D;AAC7DwB,OAAG,EAAG,eAAW;AACf,aAAO,KAAKqd,cAAZ;AACD,KAH4D;AAI7D5e,OAAG,EAAG,aAASi2C,OAAT,EAAkB;AACtB,UAAI,CAAC,KAAKZ,eAAV,EAA2B;AACzBnuC,eAAO,CAACkO,IAAR,CAAa,iEACO,0CADP,GAEO,6CAFP,GAGO,0BAHpB;AAID;;AACD,WAAKwJ,cAAL,GAAsBq3B,OAAtB;;AACA,WAAKJ,OAAL;AACD;AAb4D,GAA/D;AAgBA;;;;;;AAKA5zC,QAAM,CAACU,cAAP,CAAsBqF,EAAE,CAACotC,SAAH,CAAar1C,SAAnC,EAA8C,UAA9C,EAA0D;AACxDwB,OAAG,EAAG,eAAW;AACf,aAAO,KAAK+zC,SAAZ;AACD,KAHuD;AAIxDt1C,OAAG,EAAG,aAASiG,QAAT,EAAmB;AACvB,WAAKovC,eAAL,GAAuB,OAAOpvC,QAAP,KAAoB,QAApB,GAA8B,KAA9B,GAAsC,IAA7D;AACA,WAAKqvC,SAAL,GAAiBrvC,QAAjB;;AACA,WAAK4vC,OAAL;AACD;AARuD,GAA1D;AAWA;;;;;;;AAMA5zC,QAAM,CAACU,cAAP,CAAsBqF,EAAE,CAACotC,SAAH,CAAar1C,SAAnC,EAA8C,YAA9C,EAA4D;AAC1DwB,OAAG,EAAG,eAAW;AACf,aAAO,KAAK4wC,KAAL,CAAWhhC,KAAlB;AACD;AAHyD,GAA5D;AAMA,SAAOnJ,EAAE,CAACotC,SAAV;AACD,CA9SK;AAAA,oGAAN,C;;;;;;ACFAj2C,qEAAO,UAAUoK,OAAV,EAAmB;AACzB;;AAEA,MAAIxB,OAAO,GAAGwB,mBAAO,CAAC,CAAD,CAArB;;AACA,MAAIE,MAAM,GAAGF,mBAAO,CAAC,CAAD,CAApB;;AACC,MAAIiI,WAAW,GAAGjI,mBAAO,CAAC,EAAD,CAAzB;AAEA;;;;;;;;;;;;;;;;;;;;;;;AAqBDvB,IAAE,CAACkuC,UAAH,GAAgB,YAAW;AAC1BzsC,UAAM,CAAClF,IAAP,CAAY,IAAZ;AAEE;;;;;;;AAQF,SAAK4xC,UAAL,GAAkB,KAAKzsC,EAAL,CAAQpC,wBAAR,EAAlB;AAEE,SAAK7H,KAAL,CAAWuD,OAAX,CAAmB,KAAKmzC,UAAxB;AACA,SAAKA,UAAL,CAAgBnzC,OAAhB,CAAwB,KAAK4G,GAA7B;AACF,GAfD;;AAiBA5B,IAAE,CAACkuC,UAAH,CAAcn2C,SAAd,GAA0BkC,MAAM,CAACmY,MAAP,CAAc3Q,MAAM,CAAC1J,SAArB,CAA1B;AAEA;;;;;;;;;;;;;;;;;;;;;AAoBAiI,IAAE,CAACkuC,UAAH,CAAcn2C,SAAd,CAAwBsa,OAAxB,GAAkC,UAASC,GAAT,EAAc+O,MAAd,EAAsB5hB,IAAtB,EACGD,KADH,EACUD,SADV,EACqBiiB,OADrB,EAC8B;AAC/DlP,OAAG,CAACtX,OAAJ,CAAY,KAAKvD,KAAjB;AACA,SAAKO,GAAL,CAASqpB,MAAT,EAAiB5hB,IAAjB,EAAuBD,KAAvB,EAA8BD,SAA9B,EAAyCiiB,OAAzC;AACA,GAJD;AAMC;;;;;;;;;;;;;;;;;;AAgBAxhB,IAAE,CAACkuC,UAAH,CAAcn2C,SAAd,CAAwBC,GAAxB,GAA8B,UAAUqpB,MAAV,EAAkB5hB,IAAlB,EACAD,KADA,EACOD,SADP,EACkBiiB,OADlB,EAC2B;AAEvD,QAAI,OAAOH,MAAP,KAAkB,WAAtB,EAAmC;AAAC,WAAKA,MAAL,CAAYA,MAAZ;AAAqB;;AACzD,QAAI,OAAO5hB,IAAP,KAAgB,WAApB,EAAiC;AAAC,WAAKA,IAAL,CAAUA,IAAV;AAAiB;;AACnD,QAAI,OAAOD,KAAP,KAAiB,WAArB,EAAkC;AAAC,WAAKA,KAAL,CAAWA,KAAX;AAAmB;;AACtD,QAAI,OAAOD,SAAP,KAAqB,WAAzB,EAAsC;AAAC,WAAKA,SAAL,CAAeA,SAAf;AAA2B;;AAClE,QAAI,OAAOiiB,OAAP,KAAmB,WAAvB,EAAoC;AAAC,WAAKA,OAAL,CAAaA,OAAb;AAAuB;AAC7D,GARD;AAWA;;;;;;;;;;;;AAUAxhB,IAAE,CAACkuC,UAAH,CAAcn2C,SAAd,CAAwBspB,MAAxB,GAAiC,UAAUA,MAAV,EAAkBzY,IAAlB,EAAuB;AACtD,QAAIwI,CAAC,GAAGxI,IAAI,IAAI,CAAhB;;AACA,QAAI,OAAOyY,MAAP,IAAiB,QAArB,EAA8B;AAC5B,WAAK8sB,UAAL,CAAgB9sB,MAAhB,CAAuBnpB,KAAvB,GAA+BmpB,MAA/B;AACA,WAAK8sB,UAAL,CAAgB9sB,MAAhB,CAAuB9gB,qBAAvB,CAA6C,KAAKmB,EAAL,CAAQrB,WAAR,GAAsB,IAAtB,GAA6B+Q,CAA1E;AACA,WAAK+8B,UAAL,CAAgB9sB,MAAhB,CAAuB7gB,uBAAvB,CAA+C6gB,MAA/C,EAAuD,KAAK3f,EAAL,CAAQrB,WAAR,GAAsB,IAAtB,GAA6B+Q,CAApF;AACD,KAJD,MAIO,IAAI,OAAOiQ,MAAP,KAAkB,WAAtB,EAAmC;AACtCA,YAAM,CAACrmB,OAAP,CAAe,KAAKmzC,UAAL,CAAgB9sB,MAA/B;AACH;;AACD,WAAO,KAAK8sB,UAAL,CAAgB9sB,MAAhB,CAAuBnpB,KAA9B;AACD,GAVD;AAaD;;;;;;;;;;;;AAUC8H,IAAE,CAACkuC,UAAH,CAAcn2C,SAAd,CAAwB0H,IAAxB,GAA+B,UAAUA,IAAV,EAAgBmJ,IAAhB,EAAqB;AAClD,QAAIwI,CAAC,GAAGxI,IAAI,IAAI,CAAhB;;AACA,QAAI,OAAOnJ,IAAP,IAAe,QAAnB,EAA4B;AAC1B,WAAK0uC,UAAL,CAAgB1uC,IAAhB,CAAqBvH,KAArB,GAA6BuH,IAA7B;AACA,WAAK0uC,UAAL,CAAgB1uC,IAAhB,CAAqBc,qBAArB,CAA2C,KAAKmB,EAAL,CAAQrB,WAAR,GAAsB,IAAtB,GAA6B+Q,CAAxE;AACA,WAAK+8B,UAAL,CAAgB1uC,IAAhB,CAAqBe,uBAArB,CAA6Cf,IAA7C,EAAmD,KAAKiC,EAAL,CAAQrB,WAAR,GAAsB,IAAtB,GAA6B+Q,CAAhF;AACD,KAJD,MAIO,IAAI,OAAO3R,IAAP,KAAgB,WAApB,EAAiC;AACpCA,UAAI,CAACzE,OAAL,CAAa,KAAKmzC,UAAL,CAAgB1uC,IAA7B;AACH;;AACD,WAAO,KAAK0uC,UAAL,CAAgB1uC,IAAhB,CAAqBvH,KAA5B;AACD,GAVD;AAaA;;;;;;;;;;AAQA8H,IAAE,CAACkuC,UAAH,CAAcn2C,SAAd,CAAwByH,KAAxB,GAAgC,UAAUA,KAAV,EAAiBoJ,IAAjB,EAAsB;AACpD,QAAIwI,CAAC,GAAGxI,IAAI,IAAI,CAAhB;;AACA,QAAI,OAAOpJ,KAAP,IAAgB,QAApB,EAA6B;AAC3B,WAAK2uC,UAAL,CAAgB3uC,KAAhB,CAAsBtH,KAAtB,GAA8BsH,KAA9B;AACA,WAAK2uC,UAAL,CAAgB3uC,KAAhB,CAAsBe,qBAAtB,CAA4C,KAAKmB,EAAL,CAAQrB,WAAR,GAAsB,IAAtB,GAA6B+Q,CAAzE;AACA,WAAK+8B,UAAL,CAAgB3uC,KAAhB,CAAsBgB,uBAAtB,CAA8ChB,KAA9C,EAAqD,KAAKkC,EAAL,CAAQrB,WAAR,GAAsB,IAAtB,GAA6B+Q,CAAlF;AACD,KAJD,MAIO,IAAI,OAAO5R,KAAP,KAAiB,WAArB,EAAkC;AACrCA,WAAK,CAACxE,OAAN,CAAc,KAAKmzC,UAAL,CAAgB3uC,KAA9B;AACH;;AACD,WAAO,KAAK2uC,UAAL,CAAgB3uC,KAAhB,CAAsBtH,KAA7B;AACD,GAVD;AAaA;;;;;;;;;;AAQA8H,IAAE,CAACkuC,UAAH,CAAcn2C,SAAd,CAAwBwH,SAAxB,GAAoC,UAAUA,SAAV,EAAqBqJ,IAArB,EAA0B;AAC5D,QAAIwI,CAAC,GAAGxI,IAAI,IAAI,CAAhB;;AACA,QAAI,OAAOrJ,SAAP,IAAoB,QAAxB,EAAiC;AAC/B,WAAK4uC,UAAL,CAAgB5uC,SAAhB,CAA0BrH,KAA1B,GAAkCqH,SAAlC;AACA,WAAK4uC,UAAL,CAAgB5uC,SAAhB,CAA0BgB,qBAA1B,CAAgD,KAAKmB,EAAL,CAAQrB,WAAR,GAAsB,IAAtB,GAA6B+Q,CAA7E;AACA,WAAK+8B,UAAL,CAAgB5uC,SAAhB,CAA0BiB,uBAA1B,CAAkDjB,SAAlD,EAA6D,KAAKmC,EAAL,CAAQrB,WAAR,GAAsB,IAAtB,GAA6B+Q,CAA1F;AACD,KAJD,MAIO,IAAI,OAAO7R,SAAP,KAAqB,WAAzB,EAAsC;AACzCA,eAAS,CAACvE,OAAV,CAAkB,KAAKmzC,UAAL,CAAgB5uC,SAAlC;AACH;;AACD,WAAO,KAAK4uC,UAAL,CAAgB5uC,SAAhB,CAA0BrH,KAAjC;AACD,GAVD;AAaA;;;;;;;;;;;AASA8H,IAAE,CAACkuC,UAAH,CAAcn2C,SAAd,CAAwBypB,OAAxB,GAAkC,UAAUA,OAAV,EAAmB5Y,IAAnB,EAAwB;AACxD,QAAIwI,CAAC,GAAGxI,IAAI,IAAI,CAAhB;;AACA,QAAI,OAAO4Y,OAAP,IAAkB,QAAtB,EAA+B;AAC7B,WAAK2sB,UAAL,CAAgB3sB,OAAhB,CAAwBtpB,KAAxB,GAAgCspB,OAAhC;AACA,WAAK2sB,UAAL,CAAgB3sB,OAAhB,CAAwBjhB,qBAAxB,CAA8C,KAAKmB,EAAL,CAAQrB,WAAR,GAAsB,IAAtB,GAA6B+Q,CAA3E;AACA,WAAK+8B,UAAL,CAAgB3sB,OAAhB,CAAwBhhB,uBAAxB,CAAgDghB,OAAhD,EAAyD,KAAK9f,EAAL,CAAQrB,WAAR,GAAsB,IAAtB,GAA6B+Q,CAAtF;AACD,KAJD,MAIO,IAAI,OAAOg9B,MAAP,KAAkB,WAAtB,EAAmC;AACtC5sB,aAAO,CAACxmB,OAAR,CAAgB,KAAKmzC,UAAL,CAAgB3sB,OAAhC;AACH;;AACD,WAAO,KAAK2sB,UAAL,CAAgB3sB,OAAhB,CAAwBtpB,KAA/B;AACD,GAVD;AAYA;;;;;;;;;AAOA8H,IAAE,CAACkuC,UAAH,CAAcn2C,SAAd,CAAwB6sB,SAAxB,GAAmC,YAAW;AAC5C,WAAO,KAAKupB,UAAL,CAAgBvpB,SAAhB,CAA0B1sB,KAAjC;AACD,GAFD;;AAKD8H,IAAE,CAACkuC,UAAH,CAAcn2C,SAAd,CAAwB8C,OAAxB,GAAkC,YAAW;AAC1C4G,UAAM,CAAC1J,SAAP,CAAiB8C,OAAjB,CAAyBU,KAAzB,CAA+B,IAA/B;;AACA,QAAI,KAAK4yC,UAAT,EAAqB;AACnB,WAAKA,UAAL,CAAgBpzC,UAAhB;AACA,aAAO,KAAKozC,UAAZ;AACD;AACH,GAND;;AAQC,SAAOnuC,EAAE,CAACkuC,UAAV;AACD,CAtOK;AAAA,oGAAN,C;;;;;;;ACAA,kCAAa;;AAEb/2C,mCAAO,UAAUoK,OAAV,EAAmB;AAExB;AAEA,MAAIxB,OAAO,GAAGwB,mBAAO,CAAC,CAAD,CAArB;;AACA,MAAIsE,YAAY,GAAGtE,mBAAO,CAAC,CAAD,CAAP,CAAmBsE,YAAtC;;AACA,MAAImiB,cAAc,GAAGzmB,mBAAO,CAAC,EAAD,CAA5B;;AACA,MAAIG,EAAE,GAAG3B,OAAO,CAACZ,YAAjB;AAEA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAmEAa,IAAE,CAACquC,aAAH,GAAmB,YAAW;AAC5B,SAAK52C,KAAL,GAAaiK,EAAE,CAAC/J,UAAH,EAAb;AACA,SAAKE,MAAL,GAAc6J,EAAE,CAAC/J,UAAH,EAAd;AAEA,SAAK22C,cAAL,GAAsB,CAAtB;AACA,SAAKC,eAAL,GAAuB,CAAvB,CAL4B,CAKF;;AAE1B,SAAKplB,YAAL,GAAoB,IAAI+F,gBAAJ,CAAqBxtB,EAArB,EAAyBsmB,cAAc,CAACza,iBAAxC,EAA2D;AAC7E6mB,wBAAkB,EAAE,CAAC,KAAKma,eAAN,CADyD;AAE7Ela,sBAAgB,EAAE;AAAEjN,wBAAgB,EAAE,KAAKknB;AAAzB;AAF2D,KAA3D,CAApB;;AAKA,SAAKnlB,YAAL,CAAkBgG,IAAlB,CAAuBC,SAAvB,GAAmC,UAASzb,KAAT,EAAgB;AACjD,UAAIA,KAAK,CAAC0b,IAAN,CAAW5lB,IAAX,KAAoB,SAAxB,EAAmC;AACjC,YAAM+kC,OAAO,GAAG,CACd,IAAI3rC,YAAJ,CAAiB8Q,KAAK,CAAC0b,IAAN,CAAWof,UAA5B,CADc,EAEd,IAAI5rC,YAAJ,CAAiB8Q,KAAK,CAAC0b,IAAN,CAAWqf,WAA5B,CAFc,CAAhB;;AAIA,aAAKC,SAAL,CAAeH,OAAf;AACD;AACF,KARkC,CAQjCjjC,IARiC,CAQ5B,IAR4B,CAAnC;AAUA;;;;;;;AAKA,SAAKojC,SAAL,GAAiB,YAAW,CAAE,CAA9B,CA3B4B,CA6B5B;;;AACA,SAAKxlB,YAAL,CAAkBnuB,OAAlB,CAA0BgF,EAAE,CAACS,QAAH,CAAYC,WAAtC;;AACA,SAAKkgB,QAAL,GA/B4B,CAiC5B;;AACA7gB,WAAO,CAACH,UAAR,CAAmBvF,IAAnB,CAAwB,IAAxB;AACD,GAnCD;AAqCA;;;;;;;;;;;;AAUA2F,IAAE,CAACquC,aAAH,CAAiBt2C,SAAjB,CAA2B6oB,QAA3B,GAAsC,UAAS3lB,IAAT,EAAe;AACnD,SAAKxD,KAAL,CAAWsD,UAAX;AACA,SAAKtD,KAAL,GAAa,IAAb;AACA,SAAKA,KAAL,GAAaiK,EAAE,CAAC/J,UAAH,EAAb;AACA,SAAKF,KAAL,CAAWuD,OAAX,CAAmB,KAAKmuB,YAAxB;AACA,SAAK1xB,KAAL,CAAWuD,OAAX,CAAmB,KAAKnD,MAAxB;;AACA,QAAIoD,IAAJ,EAAU;AACRA,UAAI,CAACD,OAAL,CAAa,KAAKvD,KAAlB;AACD,KAFD,MAEO;AACLuI,QAAE,CAACS,QAAH,CAAY5I,MAAZ,CAAmBmD,OAAnB,CAA2B,KAAKvD,KAAhC;AACD;AACF,GAXD;AAaA;;;;;;;;;;;;;;;;;;AAgBAuI,IAAE,CAACquC,aAAH,CAAiBt2C,SAAjB,CAA2B62C,MAA3B,GAAoC,UAASC,KAAT,EAAgBh/B,QAAhB,EAA0ByD,QAA1B,EAAoC;AACtE,SAAK6V,YAAL,CAAkBgG,IAAlB,CAAuBpiB,WAAvB,CAAmC;AAAEtD,UAAI,EAAE,OAAR;AAAiBoG,cAAQ,EAAEA;AAA3B,KAAnC;;AAEA,QAAIg/B,KAAK,IAAIv7B,QAAb,EAAuB;AACrB,WAAKq7B,SAAL,GAAiB,UAAStoC,MAAT,EAAiB;AAChCwoC,aAAK,CAACrgB,SAAN,CAAgBnoB,MAAhB;AACAiN,gBAAQ;AACT,OAHD;AAID,KALD,MAMK,IAAIu7B,KAAJ,EAAW;AACd,WAAKF,SAAL,GAAiB,UAAStoC,MAAT,EAAiB;AAChCwoC,aAAK,CAACrgB,SAAN,CAAgBnoB,MAAhB;AACD,OAFD;AAGD;AACF,GAdD;AAgBA;;;;;;;;;;;AASArG,IAAE,CAACquC,aAAH,CAAiBt2C,SAAjB,CAA2B6jB,IAA3B,GAAkC,YAAW;AAC3C,SAAKuN,YAAL,CAAkBgG,IAAlB,CAAuBpiB,WAAvB,CAAmC;AAAEtD,UAAI,EAAE;AAAR,KAAnC;AACD,GAFD;;AAIAzJ,IAAE,CAACquC,aAAH,CAAiBt2C,SAAjB,CAA2B8C,OAA3B,GAAqC,YAAW;AAC9C;AACA,QAAIsH,KAAK,GAAGpC,OAAO,CAACH,UAAR,CAAmBlH,OAAnB,CAA2B,IAA3B,CAAZ;AACAqH,WAAO,CAACH,UAAR,CAAmB7G,MAAnB,CAA0BoJ,KAA1B,EAAiC,CAAjC;;AAEA,SAAKwsC,SAAL,GAAiB,YAAW,CAAE,CAA9B;;AACA,QAAI,KAAKl3C,KAAT,EAAgB;AACd,WAAKA,KAAL,CAAWsD,UAAX;AACD;;AACD,SAAKtD,KAAL,GAAa,IAAb;AACA,SAAK0xB,YAAL,GAAoB,IAApB;AACD,GAXD;AAcA;;;;;;;;;;;AAWA;;;AACAnpB,IAAE,CAACjI,SAAH,CAAa47B,SAAb,GAAyB,UAAUI,SAAV,EAAqBN,QAArB,EAA+B;AACtD,QAAMC,QAAQ,GAAG7tB,YAAY,CAACkuB,SAAS,CAAC1tB,MAAX,CAA7B;AACArG,MAAE,CAACjI,SAAH,CAAa+2C,SAAb,CAAuB,CAACpb,QAAD,CAAvB,EAAmCD,QAAnC,EAA6C,KAA7C;AACD,GAHD;AAID,CAnNK;AAAA,oGAAN,C;;;;;;;ACFA,kCAAa;;AAEbt8B,mCAAO,YAAY;AACjB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA2FA6I,IAAE,CAAC+uC,UAAH,GAAgB,UAAS5X,KAAT,EAAgBC,KAAhB,EAAuB73B,SAAvB,EAAkCyvC,cAAlC,EAAkD;AAChE;AACA;AACA,SAAKC,aAAL,GAAqBD,cAAc,IAAI,EAAvC;AACA,SAAKE,mBAAL,GAA2B,CAA3B;AACA,SAAK7F,SAAL,GAAiB,IAAjB;AAEA,SAAK9pC,SAAL,GAAiBA,SAAS,IAAI,IAA9B;AACA,SAAK4vC,MAAL,GAAc,CAAd,CARgE,CAUhE;AACA;;AACA,SAAKC,UAAL,GAAkB,GAAlB;AAEA,SAAKC,MAAL,GAAc,CAAd;AACA,SAAKC,OAAL,GAAe,CAAf,CAfgE,CAiBhE;;AACA,SAAKC,YAAL,GAAoB,CAApB;AAEA;;;;;;;AAMA,SAAKC,UAAL,GAAkB,KAAlB;AAEA,SAAKC,EAAL,GAAUtY,KAAK,IAAI,EAAnB;AACA,SAAKuY,EAAL,GAAUtY,KAAK,IAAI,KAAnB,CA7BgE,CA+BhE;;AACA,SAAKuY,OAAL,GAAe,YAAW,CAAE,CAA5B;AACD,GAjCD;AAoCA;;;;;;;;;;;;AAUA3vC,IAAE,CAAC+uC,UAAH,CAAch3C,SAAd,CAAwB63C,MAAxB,GAAiC,UAASC,SAAT,EAAoB;AACnD,QAAIC,GAAG,GAAG,KAAKT,MAAL,GAAcQ,SAAS,CAACnZ,SAAV,CAAoB,KAAK+Y,EAAzB,EAA4B,KAAKC,EAAjC,IAAqC,GAA7D;;AACA,QAAII,GAAG,GAAG,KAAKX,MAAX,IAAqBW,GAAG,GAAG,KAAKvwC,SAAhC,IAA6CuwC,GAAG,GAAC,KAAKR,OAAT,GAAmB,CAApE,EAAuE;AAErE;AACA,WAAKK,OAAL;;AACA,WAAKH,UAAL,GAAkB,IAAlB,CAJqE,CAMrE;;AACA,WAAKL,MAAL,GAAcW,GAAG,GAAG,KAAKV,UAAzB;AACA,WAAKF,mBAAL,GAA2B,CAA3B;AACD,KATD,MASO;AACL,WAAKM,UAAL,GAAkB,KAAlB;;AACA,UAAI,KAAKN,mBAAL,IAA4B,KAAKD,aAArC,EAAoD;AAClD,aAAKC,mBAAL;AACD,OAFD,MAEO;AACL,aAAKC,MAAL,IAAe,KAAK9F,SAApB;AACA,aAAK8F,MAAL,GAAc7xC,IAAI,CAAC8O,GAAL,CAAS,KAAK+iC,MAAd,EAAsB,KAAK5vC,SAA3B,CAAd;AACD;AACF;;AAED,SAAKgwC,YAAL,GAAoBO,GAApB;AACA,SAAKR,OAAL,GAAeQ,GAAf;AACD,GAvBD;AAyBA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA+DA9vC,IAAE,CAAC+uC,UAAH,CAAch3C,SAAd,CAAwBg4C,MAAxB,GAAiC,UAASz8B,QAAT,EAAmBjX,GAAnB,EAAwB;AACvD,QAAI0f,IAAI,GAAG,IAAX;;AAEAA,QAAI,CAAC4zB,OAAL,GAAe,YAAW;AACxBr8B,cAAQ,CAACyI,IAAI,CAACszB,MAAN,EAAchzC,GAAd,CAAR;AACD,KAFD;AAGD,GAND;AAQD,CA1OK;AAAA,oGAAN,C;;;;;;;ACFA,kCAAa;;AAEblF,mCAAO,UAAUoK,OAAV,EAAmB;AACxB,MAAIxB,OAAO,GAAGwB,mBAAO,CAAC,CAAD,CAArB;AAEA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAkEAvB,IAAE,CAACsB,IAAH,GAAU,YAAW;AACnB,SAAKI,EAAL,GAAU3B,OAAO,CAACZ,YAAlB;AAEA,SAAK1H,KAAL,GAAa,KAAKiK,EAAL,CAAQ/J,UAAR,EAAb;AACA,SAAKE,MAAL,GAAc,KAAK6J,EAAL,CAAQ/J,UAAR,EAAd,CAJmB,CAMnB;;AACA,SAAKF,KAAL,CAAWoG,IAAX,CAAgB3F,KAAhB,GAAwB,GAAxB;AACA,SAAKT,KAAL,CAAWuD,OAAX,CAAmB,KAAKnD,MAAxB,EARmB,CAUnB;;AACAkI,WAAO,CAACH,UAAR,CAAmBvF,IAAnB,CAAwB,IAAxB;AACD,GAZD;AAcA;;;;;;;;;;AAUA2F,IAAE,CAACsB,IAAH,CAAQvJ,SAAR,CAAkB6oB,QAAlB,GAA6B,UAAStO,GAAT,EAAc;AACzCA,OAAG,CAACtX,OAAJ,CAAY,KAAKvD,KAAjB;AACD,GAFD;AAIA;;;;;;;;;AAOAuI,IAAE,CAACsB,IAAH,CAAQvJ,SAAR,CAAkBiD,OAAlB,GAA4B,UAASC,IAAT,EAAe;AACzC,QAAIiH,CAAC,GAAGjH,IAAI,IAAI+E,EAAE,CAACS,QAAH,CAAYhJ,KAA5B;AACA,SAAKI,MAAL,CAAYmD,OAAZ,CAAoBkH,CAAC,CAACzK,KAAF,GAAUyK,CAAC,CAACzK,KAAZ,GAAoByK,CAAxC;AACD,GAHD;AAKA;;;;;;;;AAMAlC,IAAE,CAACsB,IAAH,CAAQvJ,SAAR,CAAkBgD,UAAlB,GAA+B,YAAW;AACxC,QAAI,KAAKlD,MAAT,EAAiB;AACf,WAAKA,MAAL,CAAYkD,UAAZ;AACD;AACF,GAJD;AAMA;;;;;;;;;;;;AAUAiF,IAAE,CAACsB,IAAH,CAAQvJ,SAAR,CAAkBgK,GAAlB,GAAwB,UAAS5B,GAAT,EAAchI,QAAd,EAAwBiI,QAAxB,EAAkC;AACxD,QAAIjI,QAAQ,GAAGA,QAAQ,IAAI,CAA3B;AACA,QAAIiI,QAAQ,GAAGA,QAAQ,IAAI,CAA3B;AACA,QAAIlC,GAAG,GAAG6B,OAAO,CAACZ,YAAR,CAAqBkB,WAA/B;AACA,QAAIC,UAAU,GAAG,KAAKzI,MAAL,CAAYgG,IAAZ,CAAiB3F,KAAlC;AACA,SAAKL,MAAL,CAAYgG,IAAZ,CAAiB0C,qBAAjB,CAAuCrC,GAAvC;AACA,SAAKrG,MAAL,CAAYgG,IAAZ,CAAiB2C,uBAAjB,CAAyCF,UAAzC,EAAqDpC,GAAG,GAAGkC,QAA3D;AACA,SAAKvI,MAAL,CAAYgG,IAAZ,CAAiB2C,uBAAjB,CAAyCL,GAAzC,EAA8CjC,GAAG,GAAGkC,QAAN,GAAiBjI,QAA/D;AACD,GARD;;AAUA6H,IAAE,CAACsB,IAAH,CAAQvJ,SAAR,CAAkB8C,OAAlB,GAA4B,YAAW;AACrC;AACA,QAAIsH,KAAK,GAAGpC,OAAO,CAACH,UAAR,CAAmBlH,OAAnB,CAA2B,IAA3B,CAAZ;AACAqH,WAAO,CAACH,UAAR,CAAmB7G,MAAnB,CAA0BoJ,KAA1B,EAAiC,CAAjC;;AACA,QAAI,KAAKtK,MAAT,EAAiB;AACf,WAAKA,MAAL,CAAYkD,UAAZ;AACA,aAAO,KAAKlD,MAAZ;AACD;;AACD,QAAI,KAAKJ,KAAT,EAAgB;AACd,WAAKA,KAAL,CAAWsD,UAAX;AACA,aAAO,KAAKtD,KAAZ;AACD;AACF,GAZD;AAcD,CA3JK;AAAA,oGAAN,C;;;;;;;ACFA,kCAAa;;AAEbN,mCAAO,UAAUoK,OAAV,EAAmB;AAExB,MAAIE,MAAM,GAAGF,mBAAO,CAAC,CAAD,CAApB;AAEA;;;;;AAGA,WAASyuC,mBAAT,CAA6BC,MAA7B,EAAqC;AACnC,QAAIC,CAAC,GAAG,OAAOD,MAAP,KAAkB,QAAlB,GAA6BA,MAA7B,GAAsC,EAA9C;AACA,QAAIE,UAAU,GAAG,KAAjB;AACA,QAAIxtC,KAAK,GAAG,IAAIE,YAAJ,CAAiBstC,UAAjB,CAAZ;AACA,QAAIC,GAAG,GAAG9yC,IAAI,CAACC,EAAL,GAAU,GAApB;AACA,QAAI1E,CAAC,GAAG,CAAR;AACA,QAAIw+B,CAAJ;;AACA,WAAQx+B,CAAC,GAAGs3C,UAAZ,EAAwB,EAAEt3C,CAA1B,EAA8B;AAC5Bw+B,OAAC,GAAGx+B,CAAC,GAAG,CAAJ,GAAQs3C,UAAR,GAAqB,CAAzB;AACAxtC,WAAK,CAAC9J,CAAD,CAAL,GAAW,CAAE,IAAIq3C,CAAN,IAAY7Y,CAAZ,GAAgB,EAAhB,GAAqB+Y,GAArB,IAA6B9yC,IAAI,CAACC,EAAL,GAAU2yC,CAAC,GAAG5yC,IAAI,CAACue,GAAL,CAASwb,CAAT,CAA3C,CAAX;AACD;;AACD,WAAO10B,KAAP;AACD;AAED;;;;;;;;;;;;;;;;;;;;AAkBA3C,IAAE,CAACqwC,UAAH,GAAgB,UAASJ,MAAT,EAAiBhtC,UAAjB,EAA6B;AAC3CxB,UAAM,CAAClF,IAAP,CAAY,IAAZ;;AAEA,QAAI,OAAO0zC,MAAP,KAAkB,WAAtB,EAAmC;AACjCA,YAAM,GAAG,IAAT;AACD;;AAAC,QAAI,OAAOA,MAAP,KAAkB,QAAtB,EAAgC;AAChC,YAAM,IAAIpmC,KAAJ,CAAU,yBAAV,CAAN;AACD;;AAAC,QAAI,OAAO5G,UAAP,KAAsB,WAA1B,EAAuC;AACvCA,gBAAU,GAAG,IAAb;AACD;;AAAC,QAAI,OAAOA,UAAP,KAAsB,QAA1B,EAAoC;AACpC,YAAM,IAAI4G,KAAJ,CAAU,6BAAV,CAAN;AACD;;AAED,QAAIymC,WAAW,GAAGtwC,EAAE,CAACjI,SAAH,CAAa0b,GAAb,CAAiBw8B,MAAjB,EAAyB,GAAzB,EAA8B,GAA9B,EAAmC,CAAnC,EAAsC,IAAtC,CAAlB;AAEA;;;;;;;;AAOA,SAAKM,cAAL,GAAsB,KAAK7uC,EAAL,CAAQe,gBAAR,EAAtB;AAEA,SAAKwtC,MAAL,GAAcK,WAAd;AACA,SAAKC,cAAL,CAAoB5tC,KAApB,GAA4BqtC,mBAAmB,CAACM,WAAD,CAA/C;AACA,SAAKC,cAAL,CAAoBttC,UAApB,GAAiCA,UAAjC;AAEA,SAAKxL,KAAL,CAAWuD,OAAX,CAAmB,KAAKu1C,cAAxB;AAEA,SAAKA,cAAL,CAAoBv1C,OAApB,CAA4B,KAAK4G,GAAjC;AACD,GA/BD;;AAiCA5B,IAAE,CAACqwC,UAAH,CAAct4C,SAAd,GAA0BkC,MAAM,CAACmY,MAAP,CAAc3Q,MAAM,CAAC1J,SAArB,CAA1B;AAGA;;;;;;;;;;AASAiI,IAAE,CAACqwC,UAAH,CAAct4C,SAAd,CAAwBsa,OAAxB,GAAkC,UAASC,GAAT,EAAc29B,MAAd,EAAsBhtC,UAAtB,EAAkC;AAClEqP,OAAG,CAACtX,OAAJ,CAAY,KAAKvD,KAAjB;AACA,SAAKO,GAAL,CAASi4C,MAAT,EAAiBhtC,UAAjB;AACD,GAHD;AAKA;;;;;;;;;;;AASAjD,IAAE,CAACqwC,UAAH,CAAct4C,SAAd,CAAwBC,GAAxB,GAA8B,UAASi4C,MAAT,EAAiBhtC,UAAjB,EAA6B;AACzD,QAAIgtC,MAAJ,EAAY;AACV,UAAIK,WAAW,GAAGtwC,EAAE,CAACjI,SAAH,CAAa0b,GAAb,CAAiBw8B,MAAjB,EAAyB,GAAzB,EAA8B,GAA9B,EAAmC,CAAnC,EAAsC,IAAtC,CAAlB;AACA,WAAKA,MAAL,GAAcK,WAAd;AACA,WAAKC,cAAL,CAAoB5tC,KAApB,GAA4BqtC,mBAAmB,CAACM,WAAD,CAA/C;AACD;;AACD,QAAIrtC,UAAJ,EAAgB;AACd,WAAKstC,cAAL,CAAoBttC,UAApB,GAAiCA,UAAjC;AACD;AACF,GATD;AAWA;;;;;;;;;;AAQAjD,IAAE,CAACqwC,UAAH,CAAct4C,SAAd,CAAwBy4C,SAAxB,GAAoC,YAAW;AAC7C,WAAO,KAAKP,MAAZ;AACD,GAFD;AAIA;;;;;;;;;AAOAjwC,IAAE,CAACqwC,UAAH,CAAct4C,SAAd,CAAwB04C,aAAxB,GAAwC,YAAW;AACjD,WAAO,KAAKF,cAAL,CAAoBttC,UAA3B;AACD,GAFD;;AAKAjD,IAAE,CAACqwC,UAAH,CAAct4C,SAAd,CAAwB8C,OAAxB,GAAkC,YAAW;AAC3C4G,UAAM,CAAC1J,SAAP,CAAiB8C,OAAjB,CAAyBU,KAAzB,CAA+B,IAA/B;;AACA,QAAI,KAAKg1C,cAAT,EAAyB;AACvB,WAAKA,cAAL,CAAoBx1C,UAApB;AACA,WAAKw1C,cAAL,GAAsB,IAAtB;AACD;AACF,GAND;AAOD,CA5IK;AAAA,oGAAN,C","file":"p5.sound.js","sourcesContent":[" \t// The module cache\n \tvar installedModules = {};\n\n \t// The require function\n \tfunction __webpack_require__(moduleId) {\n\n \t\t// Check if module is in cache\n \t\tif(installedModules[moduleId]) {\n \t\t\treturn installedModules[moduleId].exports;\n \t\t}\n \t\t// Create a new module (and put it into the cache)\n \t\tvar module = installedModules[moduleId] = {\n \t\t\ti: moduleId,\n \t\t\tl: false,\n \t\t\texports: {}\n \t\t};\n\n \t\t// Execute the module function\n \t\tmodules[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n\n \t\t// Flag the module as loaded\n \t\tmodule.l = true;\n\n \t\t// Return the exports of the module\n \t\treturn module.exports;\n \t}\n\n\n \t// expose the modules object (__webpack_modules__)\n \t__webpack_require__.m = modules;\n\n \t// expose the module cache\n \t__webpack_require__.c = installedModules;\n\n \t// define getter function for harmony exports\n \t__webpack_require__.d = function(exports, name, getter) {\n \t\tif(!__webpack_require__.o(exports, name)) {\n \t\t\tObject.defineProperty(exports, name, { enumerable: true, get: getter });\n \t\t}\n \t};\n\n \t// define __esModule on exports\n \t__webpack_require__.r = function(exports) {\n \t\tif(typeof Symbol !== 'undefined' && Symbol.toStringTag) {\n \t\t\tObject.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });\n \t\t}\n \t\tObject.defineProperty(exports, '__esModule', { value: true });\n \t};\n\n \t// create a fake namespace object\n \t// mode & 1: value is a module id, require it\n \t// mode & 2: merge all properties of value into the ns\n \t// mode & 4: return value when already ns object\n \t// mode & 8|1: behave like require\n \t__webpack_require__.t = function(value, mode) {\n \t\tif(mode & 1) value = __webpack_require__(value);\n \t\tif(mode & 8) return value;\n \t\tif((mode & 4) && typeof value === 'object' && value && value.__esModule) return value;\n \t\tvar ns = Object.create(null);\n \t\t__webpack_require__.r(ns);\n \t\tObject.defineProperty(ns, 'default', { enumerable: true, value: value });\n \t\tif(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key));\n \t\treturn ns;\n \t};\n\n \t// getDefaultExport function for compatibility with non-harmony modules\n \t__webpack_require__.n = function(module) {\n \t\tvar getter = module && module.__esModule ?\n \t\t\tfunction getDefault() { return module['default']; } :\n \t\t\tfunction getModuleExports() { return module; };\n \t\t__webpack_require__.d(getter, 'a', getter);\n \t\treturn getter;\n \t};\n\n \t// Object.prototype.hasOwnProperty.call\n \t__webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };\n\n \t// __webpack_public_path__\n \t__webpack_require__.p = \"\";\n\n\n \t// Load entry module and return exports\n \treturn __webpack_require__(__webpack_require__.s = 31);\n","/**\n * Tone.js\n * @author Yotam Mann\n * @license http://opensource.org/licenses/MIT MIT License\n * @copyright 2014-2017 Yotam Mann\n */\ndefine(function(){\n\n\t\"use strict\";\n\n\t///////////////////////////////////////////////////////////////////////////\n\t//\tTONE\n\t///////////////////////////////////////////////////////////////////////////\n\n\t/**\n\t * @class Tone is the base class of all other classes. It provides \n\t * a lot of methods and functionality to all classes that extend\n\t * it. \n\t * \n\t * @constructor\n\t * @alias Tone\n\t * @param {number} [inputs=1] the number of input nodes\n\t * @param {number} [outputs=1] the number of output nodes\n\t */\n\tvar Tone = function(inputs, outputs){\n\n\t\t/**\n\t\t * the input node(s)\n\t\t * @type {GainNode|Array}\n\t\t */\n\t\tif (this.isUndef(inputs) || inputs === 1){\n\t\t\tthis.input = this.context.createGain();\n\t\t} else if (inputs > 1){\n\t\t\tthis.input = new Array(inputs);\n\t\t}\n\n\t\t/**\n\t\t * the output node(s)\n\t\t * @type {GainNode|Array}\n\t\t */\n\t\tif (this.isUndef(outputs) || outputs === 1){\n\t\t\tthis.output = this.context.createGain();\n\t\t} else if (outputs > 1){\n\t\t\tthis.output = new Array(inputs);\n\t\t}\n\t};\n\n\t/**\n\t * Set the parameters at once. Either pass in an\n\t * object mapping parameters to values, or to set a\n\t * single parameter, by passing in a string and value.\n\t * The last argument is an optional ramp time which \n\t * will ramp any signal values to their destination value\n\t * over the duration of the rampTime.\n\t * @param {Object|string} params\n\t * @param {number=} value\n\t * @param {Time=} rampTime\n\t * @returns {Tone} this\n\t * @example\n\t * //set values using an object\n\t * filter.set({\n\t * \t\"frequency\" : 300,\n\t * \t\"type\" : highpass\n\t * });\n\t * @example\n\t * filter.set(\"type\", \"highpass\");\n\t * @example\n\t * //ramp to the value 220 over 3 seconds. \n\t * oscillator.set({\n\t * \t\"frequency\" : 220\n\t * }, 3);\n\t */\n\tTone.prototype.set = function(params, value, rampTime){\n\t\tif (this.isObject(params)){\n\t\t\trampTime = value;\n\t\t} else if (this.isString(params)){\n\t\t\tvar tmpObj = {};\n\t\t\ttmpObj[params] = value;\n\t\t\tparams = tmpObj;\n\t\t}\n\n\t\tparamLoop:\n\t\tfor (var attr in params){\n\t\t\tvalue = params[attr];\n\t\t\tvar parent = this;\n\t\t\tif (attr.indexOf(\".\") !== -1){\n\t\t\t\tvar attrSplit = attr.split(\".\");\n\t\t\t\tfor (var i = 0; i < attrSplit.length - 1; i++){\n\t\t\t\t\tparent = parent[attrSplit[i]];\n\t\t\t\t\tif (parent instanceof Tone) {\n\t\t\t\t\t\tattrSplit.splice(0,i+1);\n\t\t\t\t\t\tvar innerParam = attrSplit.join(\".\");\n\t\t\t\t\t\tparent.set(innerParam, value);\n\t\t\t\t\t\tcontinue paramLoop;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tattr = attrSplit[attrSplit.length - 1];\n\t\t\t}\n\t\t\tvar param = parent[attr];\n\t\t\tif (this.isUndef(param)){\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tif ((Tone.Signal && param instanceof Tone.Signal) || \n\t\t\t\t\t(Tone.Param && param instanceof Tone.Param)){\n\t\t\t\tif (param.value !== value){\n\t\t\t\t\tif (this.isUndef(rampTime)){\n\t\t\t\t\t\tparam.value = value;\n\t\t\t\t\t} else {\n\t\t\t\t\t\tparam.rampTo(value, rampTime);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} else if (param instanceof AudioParam){\n\t\t\t\tif (param.value !== value){\n\t\t\t\t\tparam.value = value;\n\t\t\t\t}\t\t\t\t\n\t\t\t} else if (param instanceof Tone){\n\t\t\t\tparam.set(value);\n\t\t\t} else if (param !== value){\n\t\t\t\tparent[attr] = value;\n\t\t\t}\n\t\t}\n\t\treturn this;\n\t};\n\n\t/**\n\t * Get the object's attributes. Given no arguments get\n\t * will return all available object properties and their corresponding\n\t * values. Pass in a single attribute to retrieve or an array\n\t * of attributes. The attribute strings can also include a \".\"\n\t * to access deeper properties.\n\t * @example\n\t * osc.get();\n\t * //returns {\"type\" : \"sine\", \"frequency\" : 440, ...etc}\n\t * @example\n\t * osc.get(\"type\");\n\t * //returns { \"type\" : \"sine\"}\n\t * @example\n\t * //use dot notation to access deep properties\n\t * synth.get([\"envelope.attack\", \"envelope.release\"]);\n\t * //returns {\"envelope\" : {\"attack\" : 0.2, \"release\" : 0.4}}\n\t * @param {Array=|string|undefined} params the parameters to get, otherwise will return \n\t * \t\t\t\t\t all available.\n\t * @returns {Object}\n\t */\n\tTone.prototype.get = function(params){\n\t\tif (this.isUndef(params)){\n\t\t\tparams = this._collectDefaults(this.constructor);\n\t\t} else if (this.isString(params)){\n\t\t\tparams = [params];\n\t\t} \n\t\tvar ret = {};\n\t\tfor (var i = 0; i < params.length; i++){\n\t\t\tvar attr = params[i];\n\t\t\tvar parent = this;\n\t\t\tvar subRet = ret;\n\t\t\tif (attr.indexOf(\".\") !== -1){\n\t\t\t\tvar attrSplit = attr.split(\".\");\n\t\t\t\tfor (var j = 0; j < attrSplit.length - 1; j++){\n\t\t\t\t\tvar subAttr = attrSplit[j];\n\t\t\t\t\tsubRet[subAttr] = subRet[subAttr] || {};\n\t\t\t\t\tsubRet = subRet[subAttr];\n\t\t\t\t\tparent = parent[subAttr];\n\t\t\t\t}\n\t\t\t\tattr = attrSplit[attrSplit.length - 1];\n\t\t\t}\n\t\t\tvar param = parent[attr];\n\t\t\tif (this.isObject(params[attr])){\n\t\t\t\tsubRet[attr] = param.get();\n\t\t\t} else if (Tone.Signal && param instanceof Tone.Signal){\n\t\t\t\tsubRet[attr] = param.value;\n\t\t\t} else if (Tone.Param && param instanceof Tone.Param){\n\t\t\t\tsubRet[attr] = param.value;\n\t\t\t} else if (param instanceof AudioParam){\n\t\t\t\tsubRet[attr] = param.value;\n\t\t\t} else if (param instanceof Tone){\n\t\t\t\tsubRet[attr] = param.get();\n\t\t\t} else if (!this.isFunction(param) && !this.isUndef(param)){\n\t\t\t\tsubRet[attr] = param;\n\t\t\t} \n\t\t}\n\t\treturn ret;\n\t};\n\n\t/**\n\t * collect all of the default attributes in one\n\t * @private\n\t * @param {function} constr the constructor to find the defaults from\n\t * @return {Array} all of the attributes which belong to the class\n\t */\n\tTone.prototype._collectDefaults = function(constr){\n\t\tvar ret = [];\n\t\tif (!this.isUndef(constr.defaults)){\n\t\t\tret = Object.keys(constr.defaults);\n\t\t}\n\t\tif (!this.isUndef(constr._super)){\n\t\t\tvar superDefs = this._collectDefaults(constr._super);\n\t\t\t//filter out repeats\n\t\t\tfor (var i = 0; i < superDefs.length; i++){\n\t\t\t\tif (ret.indexOf(superDefs[i]) === -1){\n\t\t\t\t\tret.push(superDefs[i]);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\treturn ret;\n\t};\n\n\t/**\n\t * @returns {string} returns the name of the class as a string\n\t */\n\tTone.prototype.toString = function(){\n\t\tfor (var className in Tone){\n\t\t\tvar isLetter = className[0].match(/^[A-Z]$/);\n\t\t\tvar sameConstructor = Tone[className] === this.constructor;\n\t\t\tif (this.isFunction(Tone[className]) && isLetter && sameConstructor){\n\t\t\t\treturn className;\n\t\t\t}\n\t\t}\n\t\treturn \"Tone\";\n\t};\n\n\t///////////////////////////////////////////////////////////////////////////\n\t//\tCLASS VARS\n\t///////////////////////////////////////////////////////////////////////////\n\n\t/**\n\t * The number of inputs feeding into the AudioNode. \n\t * For source nodes, this will be 0.\n\t * @memberOf Tone#\n\t * @name numberOfInputs\n\t * @readOnly\n\t */\n\tObject.defineProperty(Tone.prototype, \"numberOfInputs\", {\n\t\tget : function(){\n\t\t\tif (this.input){\n\t\t\t\tif (this.isArray(this.input)){\n\t\t\t\t\treturn this.input.length;\n\t\t\t\t} else {\n\t\t\t\t\treturn 1;\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\treturn 0;\n\t\t\t}\n\t\t}\n\t});\n\n\t/**\n\t * The number of outputs coming out of the AudioNode. \n\t * For source nodes, this will be 0.\n\t * @memberOf Tone#\n\t * @name numberOfInputs\n\t * @readOnly\n\t */\n\tObject.defineProperty(Tone.prototype, \"numberOfOutputs\", {\n\t\tget : function(){\n\t\t\tif (this.output){\n\t\t\t\tif (this.isArray(this.output)){\n\t\t\t\t\treturn this.output.length;\n\t\t\t\t} else {\n\t\t\t\t\treturn 1;\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\treturn 0;\n\t\t\t}\n\t\t}\n\t});\n\t\n\t///////////////////////////////////////////////////////////////////////////\n\t//\tCONNECTIONS\n\t///////////////////////////////////////////////////////////////////////////\n\n\t/**\n\t * disconnect and dispose\n\t * @returns {Tone} this\n\t */\n\tTone.prototype.dispose = function(){\n\t\tif (!this.isUndef(this.input)){\n\t\t\tif (this.input instanceof AudioNode){\n\t\t\t\tthis.input.disconnect();\n\t\t\t} \n\t\t\tthis.input = null;\n\t\t}\n\t\tif (!this.isUndef(this.output)){\n\t\t\tif (this.output instanceof AudioNode){\n\t\t\t\tthis.output.disconnect();\n\t\t\t} \n\t\t\tthis.output = null;\n\t\t}\n\t\treturn this;\n\t};\n\n\t/**\n\t * connect the output of a ToneNode to an AudioParam, AudioNode, or ToneNode\n\t * @param {Tone | AudioParam | AudioNode} unit \n\t * @param {number} [outputNum=0] optionally which output to connect from\n\t * @param {number} [inputNum=0] optionally which input to connect to\n\t * @returns {Tone} this\n\t */\n\tTone.prototype.connect = function(unit, outputNum, inputNum){\n\t\tif (Array.isArray(this.output)){\n\t\t\toutputNum = this.defaultArg(outputNum, 0);\n\t\t\tthis.output[outputNum].connect(unit, 0, inputNum);\n\t\t} else {\n\t\t\tthis.output.connect(unit, outputNum, inputNum);\n\t\t}\n\t\treturn this;\n\t};\n\n\t/**\n\t * disconnect the output\n\t * @param {Number|AudioNode} output Either the output index to disconnect\n\t * if the output is an array, or the\n\t * node to disconnect from.\n\t * @returns {Tone} this\n\t */\n\tTone.prototype.disconnect = function(destination, outputNum, inputNum){\n\t\tif (this.isArray(this.output)){\n\t\t\tif (this.isNumber(destination)){\n\t\t\t\tthis.output[destination].disconnect();\n\t\t\t} else {\n\t\t\t\toutputNum = this.defaultArg(outputNum, 0);\n\t\t\t\tthis.output[outputNum].disconnect(destination, 0, inputNum);\n\t\t\t}\n\t\t} else {\n\t\t\tthis.output.disconnect.apply(this.output, arguments);\n\t\t}\n\t};\n\n\t/**\n\t * connect together all of the arguments in series\n\t * @param {...AudioParam|Tone|AudioNode} nodes\n\t * @returns {Tone} this\n\t */\n\tTone.prototype.connectSeries = function(){\n\t\tif (arguments.length > 1){\n\t\t\tvar currentUnit = arguments[0];\n\t\t\tfor (var i = 1; i < arguments.length; i++){\n\t\t\t\tvar toUnit = arguments[i];\n\t\t\t\tcurrentUnit.connect(toUnit);\n\t\t\t\tcurrentUnit = toUnit;\n\t\t\t}\n\t\t}\n\t\treturn this;\n\t};\n\n\t/**\n\t * Connect the output of this node to the rest of the nodes in series.\n\t * @example\n\t * //connect a node to an effect, panVol and then to the master output\n\t * node.chain(effect, panVol, Tone.Master);\n\t * @param {...AudioParam|Tone|AudioNode} nodes\n\t * @returns {Tone} this\n\t */\n\tTone.prototype.chain = function(){\n\t\tif (arguments.length > 0){\n\t\t\tvar currentUnit = this;\n\t\t\tfor (var i = 0; i < arguments.length; i++){\n\t\t\t\tvar toUnit = arguments[i];\n\t\t\t\tcurrentUnit.connect(toUnit);\n\t\t\t\tcurrentUnit = toUnit;\n\t\t\t}\n\t\t}\n\t\treturn this;\n\t};\n\n\t/**\n\t * connect the output of this node to the rest of the nodes in parallel.\n\t * @param {...AudioParam|Tone|AudioNode} nodes\n\t * @returns {Tone} this\n\t */\n\tTone.prototype.fan = function(){\n\t\tif (arguments.length > 0){\n\t\t\tfor (var i = 0; i < arguments.length; i++){\n\t\t\t\tthis.connect(arguments[i]);\n\t\t\t}\n\t\t}\n\t\treturn this;\n\t};\n\n\t//give native nodes chain and fan methods\n\tAudioNode.prototype.chain = Tone.prototype.chain;\n\tAudioNode.prototype.fan = Tone.prototype.fan;\n\n\t///////////////////////////////////////////////////////////////////////////\n\t//\tUTILITIES / HELPERS / MATHS\n\t///////////////////////////////////////////////////////////////////////////\n\n\t/**\n\t * If the `given` parameter is undefined, use the `fallback`. \n\t * If both `given` and `fallback` are object literals, it will\n\t * return a deep copy which includes all of the parameters from both \n\t * objects. If a parameter is undefined in given, it will return\n\t * the fallback property. \n\t *
\n\t * WARNING: if object is self referential, it will go into an an \n\t * infinite recursive loop.\n\t * \n\t * @param {*} given \n\t * @param {*} fallback \n\t * @return {*} \n\t */\n\tTone.prototype.defaultArg = function(given, fallback){\n\t\tif (this.isObject(given) && this.isObject(fallback)){\n\t\t\tvar ret = {};\n\t\t\t//make a deep copy of the given object\n\t\t\tfor (var givenProp in given) {\n\t\t\t\tret[givenProp] = this.defaultArg(fallback[givenProp], given[givenProp]);\n\t\t\t}\n\t\t\tfor (var fallbackProp in fallback) {\n\t\t\t\tret[fallbackProp] = this.defaultArg(given[fallbackProp], fallback[fallbackProp]);\n\t\t\t}\n\t\t\treturn ret;\n\t\t} else {\n\t\t\treturn this.isUndef(given) ? fallback : given;\n\t\t}\n\t};\n\n\t/**\n\t * returns the args as an options object with given arguments\n\t * mapped to the names provided. \n\t *\n\t * if the args given is an array containing only one object, it is assumed\n\t * that that's already the options object and will just return it. \n\t * \n\t * @param {Array} values the 'arguments' object of the function\n\t * @param {Array} keys the names of the arguments as they\n\t * should appear in the options object\n\t * @param {Object=} defaults optional defaults to mixin to the returned \n\t * options object \n\t * @return {Object} the options object with the names mapped to the arguments\n\t */\n\tTone.prototype.optionsObject = function(values, keys, defaults){\n\t\tvar options = {};\n\t\tif (values.length === 1 && this.isObject(values[0])){\n\t\t\toptions = values[0];\n\t\t} else {\n\t\t\tfor (var i = 0; i < keys.length; i++){\n\t\t\t\toptions[keys[i]] = values[i];\n\t\t\t}\n\t\t}\n\t\tif (!this.isUndef(defaults)){\n\t\t\treturn this.defaultArg(options, defaults);\n\t\t} else {\n\t\t\treturn options;\n\t\t}\n\t};\n\n\t///////////////////////////////////////////////////////////////////////////\n\t// TYPE CHECKING\n\t///////////////////////////////////////////////////////////////////////////\n\n\t/**\n\t * test if the arg is undefined\n\t * @param {*} arg the argument to test\n\t * @returns {boolean} true if the arg is undefined\n\t * @function\n\t */\n\tTone.prototype.isUndef = function(val){\n\t\treturn typeof val === \"undefined\";\n\t};\n\n\t/**\n\t * test if the arg is a function\n\t * @param {*} arg the argument to test\n\t * @returns {boolean} true if the arg is a function\n\t * @function\n\t */\n\tTone.prototype.isFunction = function(val){\n\t\treturn typeof val === \"function\";\n\t};\n\n\t/**\n\t * Test if the argument is a number.\n\t * @param {*} arg the argument to test\n\t * @returns {boolean} true if the arg is a number\n\t */\n\tTone.prototype.isNumber = function(arg){\n\t\treturn (typeof arg === \"number\");\n\t};\n\n\t/**\n\t * Test if the given argument is an object literal (i.e. `{}`);\n\t * @param {*} arg the argument to test\n\t * @returns {boolean} true if the arg is an object literal.\n\t */\n\tTone.prototype.isObject = function(arg){\n\t\treturn (Object.prototype.toString.call(arg) === \"[object Object]\" && arg.constructor === Object);\n\t};\n\n\t/**\n\t * Test if the argument is a boolean.\n\t * @param {*} arg the argument to test\n\t * @returns {boolean} true if the arg is a boolean\n\t */\n\tTone.prototype.isBoolean = function(arg){\n\t\treturn (typeof arg === \"boolean\");\n\t};\n\n\t/**\n\t * Test if the argument is an Array\n\t * @param {*} arg the argument to test\n\t * @returns {boolean} true if the arg is an array\n\t */\n\tTone.prototype.isArray = function(arg){\n\t\treturn (Array.isArray(arg));\n\t};\n\n\t/**\n\t * Test if the argument is a string.\n\t * @param {*} arg the argument to test\n\t * @returns {boolean} true if the arg is a string\n\t */\n\tTone.prototype.isString = function(arg){\n\t\treturn (typeof arg === \"string\");\n\t};\n\n \t/**\n\t * An empty function.\n\t * @static\n\t */\n\tTone.noOp = function(){};\n\n\t/**\n\t * Make the property not writable. Internal use only. \n\t * @private\n\t * @param {string} property the property to make not writable\n\t */\n\tTone.prototype._readOnly = function(property){\n\t\tif (Array.isArray(property)){\n\t\t\tfor (var i = 0; i < property.length; i++){\n\t\t\t\tthis._readOnly(property[i]);\n\t\t\t}\n\t\t} else {\n\t\t\tObject.defineProperty(this, property, { \n\t\t\t\twritable: false,\n\t\t\t\tenumerable : true,\n\t\t\t});\n\t\t}\n\t};\n\n\t/**\n\t * Make an attribute writeable. Interal use only. \n\t * @private\n\t * @param {string} property the property to make writable\n\t */\n\tTone.prototype._writable = function(property){\n\t\tif (Array.isArray(property)){\n\t\t\tfor (var i = 0; i < property.length; i++){\n\t\t\t\tthis._writable(property[i]);\n\t\t\t}\n\t\t} else {\n\t\t\tObject.defineProperty(this, property, { \n\t\t\t\twritable: true,\n\t\t\t});\n\t\t}\n\t};\n\n\t/**\n\t * Possible play states. \n\t * @enum {string}\n\t */\n\tTone.State = {\n\t\tStarted : \"started\",\n\t\tStopped : \"stopped\",\n\t\tPaused : \"paused\",\n \t};\n\n\t///////////////////////////////////////////////////////////////////////////\n\t// CONVERSIONS\n\t///////////////////////////////////////////////////////////////////////////\n\n\t/**\n\t * Equal power gain scale. Good for cross-fading.\n\t * @param {NormalRange} percent (0-1)\n\t * @return {Number} output gain (0-1)\n\t */\n\tTone.prototype.equalPowerScale = function(percent){\n\t\tvar piFactor = 0.5 * Math.PI;\n\t\treturn Math.sin(percent * piFactor);\n\t};\n\n\t/**\n\t * Convert decibels into gain.\n\t * @param {Decibels} db\n\t * @return {Number} \n\t */\n\tTone.prototype.dbToGain = function(db) {\n\t\treturn Math.pow(2, db / 6);\n\t};\n\n\t/**\n\t * Convert gain to decibels.\n\t * @param {Number} gain (0-1)\n\t * @return {Decibels} \n\t */\n\tTone.prototype.gainToDb = function(gain) {\n\t\treturn 20 * (Math.log(gain) / Math.LN10);\n\t};\n\n\t/**\n\t * Convert an interval (in semitones) to a frequency ratio.\n\t * @param {Interval} interval the number of semitones above the base note\n\t * @return {number} the frequency ratio\n\t * @example\n\t * tone.intervalToFrequencyRatio(0); // 1\n\t * tone.intervalToFrequencyRatio(12); // 2\n\t * tone.intervalToFrequencyRatio(-12); // 0.5\n\t */\n\tTone.prototype.intervalToFrequencyRatio = function(interval){\n\t\treturn Math.pow(2,(interval/12));\n\t};\n\n\t///////////////////////////////////////////////////////////////////////////\n\t//\tTIMING\n\t///////////////////////////////////////////////////////////////////////////\n\n\t/**\n\t * Return the current time of the AudioContext clock.\n\t * @return {Number} the currentTime from the AudioContext\n\t */\n\tTone.prototype.now = function(){\n\t\treturn Tone.context.now();\n\t};\n\n\t/**\n\t * Return the current time of the AudioContext clock.\n\t * @return {Number} the currentTime from the AudioContext\n\t * @static\n\t */\n\tTone.now = function(){\n\t\treturn Tone.context.now();\n\t};\n\n\t///////////////////////////////////////////////////////////////////////////\n\t//\tINHERITANCE\n\t///////////////////////////////////////////////////////////////////////////\n\n\t/**\n\t * have a child inherit all of Tone's (or a parent's) prototype\n\t * to inherit the parent's properties, make sure to call \n\t * Parent.call(this) in the child's constructor\n\t *\n\t * based on closure library's inherit function\n\t *\n\t * @static\n\t * @param {function} \tchild \n\t * @param {function=} parent (optional) parent to inherit from\n\t * if no parent is supplied, the child\n\t * will inherit from Tone\n\t */\n\tTone.extend = function(child, parent){\n\t\tif (Tone.prototype.isUndef(parent)){\n\t\t\tparent = Tone;\n\t\t}\n\t\tfunction TempConstructor(){}\n\t\tTempConstructor.prototype = parent.prototype;\n\t\tchild.prototype = new TempConstructor();\n\t\t/** @override */\n\t\tchild.prototype.constructor = child;\n\t\tchild._super = parent;\n\t};\n\n\t///////////////////////////////////////////////////////////////////////////\n\t//\tCONTEXT\n\t///////////////////////////////////////////////////////////////////////////\n\n\t/**\n\t * The private audio context shared by all Tone Nodes. \n\t * @private\n\t * @type {Tone.Context|undefined}\n\t */\n\tvar audioContext;\n\n\t/**\n\t * A static pointer to the audio context accessible as Tone.context. \n\t * @type {Tone.Context}\n\t * @name context\n\t * @memberOf Tone\n\t */\n\tObject.defineProperty(Tone, \"context\", {\n\t\tget : function(){\n\t\t\treturn audioContext;\n\t\t},\n\t\tset : function(context){\n\t\t\tif (Tone.Context && context instanceof Tone.Context){\n\t\t\t\taudioContext = context;\n\t\t\t} else {\n\t\t\t\taudioContext = new Tone.Context(context);\n\t\t\t}\n\t\t\t//initialize the new audio context\n\t\t\tif (Tone.Context){\n\t\t\t\tTone.Context.emit(\"init\", audioContext);\n\t\t\t}\n\t\t}\n\t});\n\n\t/**\n\t * The AudioContext\n\t * @type {Tone.Context}\n\t * @name context\n\t * @memberOf Tone#\n\t * @readOnly\n\t */\n\tObject.defineProperty(Tone.prototype, \"context\", {\n\t\tget : function(){\n\t\t\treturn Tone.context;\n\t\t}\n\t});\n\n\t/**\n\t * Tone automatically creates a context on init, but if you are working\n\t * with other libraries which also create an AudioContext, it can be\n\t * useful to set your own. If you are going to set your own context, \n\t * be sure to do it at the start of your code, before creating any objects.\n\t * @static\n\t * @param {AudioContext} ctx The new audio context to set\n\t */\n\tTone.setContext = function(ctx){\n\t\tTone.context = ctx;\n\t};\n\n\t/**\n\t * The number of seconds of 1 processing block (128 samples)\n\t * @type {Number}\n\t * @name blockTime\n\t * @memberOf Tone#\n\t * @readOnly\n\t */\n\tObject.defineProperty(Tone.prototype, \"blockTime\", {\n\t\tget : function(){\n\t\t\treturn 128 / this.context.sampleRate;\n\t\t}\n\t});\n\n\t/**\n\t * The duration in seconds of one sample.\n\t * @type {Number}\n\t * @name sampleTime\n\t * @memberOf Tone#\n\t * @readOnly\n\t */\n\tObject.defineProperty(Tone.prototype, \"sampleTime\", {\n\t\tget : function(){\n\t\t\treturn 1 / this.context.sampleRate;\n\t\t}\n\t});\n\n\t/**\n\t * Whether or not all the technologies that Tone.js relies on are supported by the current browser. \n\t * @type {Boolean}\n\t * @name supported\n\t * @memberOf Tone\n\t * @readOnly\n\t */\n\tObject.defineProperty(Tone, \"supported\", {\n\t\tget : function(){\n\t\t\tvar hasAudioContext = window.hasOwnProperty(\"AudioContext\") || window.hasOwnProperty(\"webkitAudioContext\");\n\t\t\tvar hasPromises = window.hasOwnProperty(\"Promise\");\n\t\t\tvar hasWorkers = window.hasOwnProperty(\"Worker\");\n\t\t\treturn hasAudioContext && hasPromises && hasWorkers;\n\t\t}\n\t});\n\n\tTone.version = \"r10\";\n\n\t// allow optional silencing of this log\n\tif (!window.TONE_SILENCE_VERSION_LOGGING) {\n\t\tconsole.log(\"%c * Tone.js \" + Tone.version + \" * \", \"background: #000; color: #fff\");\n\t}\n\n\treturn Tone;\n});\n","'use strict';\n\n\ndefine(['audiocontext'], function (audiocontext) {\n /**\n * Master contains AudioContext and the master sound output.\n * @for p5\n */\n var Master = function() {\n this.input = audiocontext.createGain();\n this.output = audiocontext.createGain();\n\n //put a hard limiter on the output\n this.limiter = audiocontext.createDynamicsCompressor();\n this.limiter.threshold.value = -3;\n this.limiter.ratio.value = 20;\n this.limiter.knee.value = 1;\n\n this.audiocontext = audiocontext;\n\n this.output.disconnect();\n\n // connect input to limiter\n this.input.connect(this.limiter);\n\n // connect limiter to output\n this.limiter.connect(this.output);\n\n // meter is just for global Amplitude / FFT analysis\n this.meter = audiocontext.createGain();\n this.fftMeter = audiocontext.createGain();\n this.output.connect(this.meter);\n this.output.connect(this.fftMeter);\n\n // connect output to destination\n this.output.connect(this.audiocontext.destination);\n\n // an array of all sounds in the sketch\n this.soundArray = [];\n // an array of all musical parts in the sketch\n this.parts = [];\n\n // file extensions to search for\n this.extensions = [];\n };\n\n // create a single instance of the p5Sound / master output for use within this sketch\n var p5sound = new Master();\n\n /**\n * Returns a number representing the master amplitude (volume) for sound\n * in this sketch.\n *\n * @method getMasterVolume\n * @return {Number} Master amplitude (volume) for sound in this sketch.\n * Should be between 0.0 (silence) and 1.0.\n */\n p5.prototype.getMasterVolume = function() {\n return p5sound.output.gain.value;\n };\n\n /**\n *
Scale the output of all sound in this sketch
\n * Scaled between 0.0 (silence) and 1.0 (full volume).\n * 1.0 is the maximum amplitude of a digital sound, so multiplying\n * by greater than 1.0 may cause digital distortion. To\n * fade, provide a rampTime parameter. For more\n * complex fades, see the Envelope class.\n *\n * Alternately, you can pass in a signal source such as an\n * oscillator to modulate the amplitude with an audio signal.\n *\n *
How This Works: When you load the p5.sound module, it\n * creates a single instance of p5sound. All sound objects in this\n * module output to p5sound before reaching your computer's output.\n * So if you change the amplitude of p5sound, it impacts all of the\n * sound in this module.
\n *\n *
If no value is provided, returns a Web Audio API Gain Node
\n *\n * @method masterVolume\n * @param {Number|Object} volume Volume (amplitude) between 0.0\n * and 1.0 or modulating signal/oscillator\n * @param {Number} [rampTime] Fade for t seconds\n * @param {Number} [timeFromNow] Schedule this event to happen at\n * t seconds in the future\n */\n p5.prototype.masterVolume = function(vol, rampTime, tFromNow) {\n if (typeof vol === 'number') {\n var rampTime = rampTime || 0;\n var tFromNow = tFromNow || 0;\n var now = p5sound.audiocontext.currentTime;\n var currentVol = p5sound.output.gain.value;\n p5sound.output.gain.cancelScheduledValues(now + tFromNow);\n p5sound.output.gain.linearRampToValueAtTime(currentVol, now + tFromNow);\n p5sound.output.gain.linearRampToValueAtTime(vol, now + tFromNow + rampTime);\n }\n else if (vol) {\n vol.connect(p5sound.output.gain);\n } else {\n // return the Gain Node\n return p5sound.output.gain;\n }\n };\n\n /**\n * `p5.soundOut` is the p5.sound master output. It sends output to\n * the destination of this window's web audio context. It contains\n * Web Audio API nodes including a dyanmicsCompressor (.limiter),\n * and Gain Nodes for .input and .output.\n *\n * @property {Object} soundOut\n */\n p5.prototype.soundOut = p5.soundOut = p5sound;\n\n /**\n * a silent connection to the DesinationNode\n * which will ensure that anything connected to it\n * will not be garbage collected\n *\n * @private\n */\n p5.soundOut._silentNode = p5sound.audiocontext.createGain();\n p5.soundOut._silentNode.gain.value = 0;\n p5.soundOut._silentNode.connect(p5sound.audiocontext.destination);\n\n\n return p5sound;\n});\n","define([\"Tone/core/Tone\", \"Tone/signal/WaveShaper\", \"Tone/type/Type\", \"Tone/core/Param\", \"Tone/core/Gain\"], function(Tone){\n\n\t\"use strict\";\n\n\t/**\n\t * @class A signal is an audio-rate value. Tone.Signal is a core component of the library.\n\t * Unlike a number, Signals can be scheduled with sample-level accuracy. Tone.Signal\n\t * has all of the methods available to native Web Audio \n\t * [AudioParam](http://webaudio.github.io/web-audio-api/#the-audioparam-interface)\n\t * as well as additional conveniences. Read more about working with signals \n\t * [here](https://github.com/Tonejs/Tone.js/wiki/Signals).\n\t *\n\t * @constructor\n\t * @extends {Tone.Param}\n\t * @param {Number|AudioParam} [value] Initial value of the signal. If an AudioParam\n\t * is passed in, that parameter will be wrapped\n\t * and controlled by the Signal. \n\t * @param {string} [units=Number] unit The units the signal is in. \n\t * @example\n\t * var signal = new Tone.Signal(10);\n\t */\n\tTone.Signal = function(){\n\n\t\tvar options = this.optionsObject(arguments, [\"value\", \"units\"], Tone.Signal.defaults);\n\n\t\t/**\n\t\t * The node where the constant signal value is scaled.\n\t\t * @type {GainNode}\n\t\t * @private\n\t\t */\n\t\tthis.output = this._gain = this.context.createGain();\n\n\t\toptions.param = this._gain.gain;\n\t\tTone.Param.call(this, options);\n\n\t\t/**\n\t\t * The node where the value is set.\n\t\t * @type {Tone.Param}\n\t\t * @private\n\t\t */\n\t\tthis.input = this._param = this._gain.gain;\n\n\t\t//connect the const output to the node output\n\t\tthis.context.getConstant(1).chain(this._gain);\n\t};\n\n\tTone.extend(Tone.Signal, Tone.Param);\n\n\t/**\n\t * The default values\n\t * @type {Object}\n\t * @static\n\t * @const\n\t */\n\tTone.Signal.defaults = {\n\t\t\"value\" : 0,\n\t\t\"units\" : Tone.Type.Default,\n\t\t\"convert\" : true,\n\t};\n\n\t/**\n\t * When signals connect to other signals or AudioParams, \n\t * they take over the output value of that signal or AudioParam. \n\t * For all other nodes, the behavior is the same as a default connect. \n\t *\n\t * @override\n\t * @param {AudioParam|AudioNode|Tone.Signal|Tone} node \n\t * @param {number} [outputNumber=0] The output number to connect from.\n\t * @param {number} [inputNumber=0] The input number to connect to.\n\t * @returns {Tone.SignalBase} this\n\t * @method\n\t */\n\tTone.Signal.prototype.connect = Tone.SignalBase.prototype.connect;\n\n\t/**\n\t * dispose and disconnect\n\t * @returns {Tone.Signal} this\n\t */\n\tTone.Signal.prototype.dispose = function(){\n\t\tTone.Param.prototype.dispose.call(this);\n\t\tthis._param = null;\n\t\tthis._gain.disconnect();\n\t\tthis._gain = null;\n\t\treturn this;\n\t};\n\n\treturn Tone.Signal;\n});","define([\"Tone/core/Tone\", \"Tone/signal/Signal\", \"Tone/core/Gain\"], function(Tone){\n\n\t\"use strict\";\n\n\t/**\n\t * @class Multiply two incoming signals. Or, if a number is given in the constructor, \n\t * multiplies the incoming signal by that value. \n\t *\n\t * @constructor\n\t * @extends {Tone.Signal}\n\t * @param {number=} value Constant value to multiple. If no value is provided,\n\t * it will return the product of the first and second inputs\n\t * @example\n\t * var mult = new Tone.Multiply();\n\t * var sigA = new Tone.Signal(3);\n\t * var sigB = new Tone.Signal(4);\n\t * sigA.connect(mult, 0, 0);\n\t * sigB.connect(mult, 0, 1);\n\t * //output of mult is 12.\n\t * @example\n\t * var mult = new Tone.Multiply(10);\n\t * var sig = new Tone.Signal(2).connect(mult);\n\t * //the output of mult is 20. \n\t */\n\tTone.Multiply = function(value){\n\n\t\tthis.createInsOuts(2, 0);\n\n\t\t/**\n\t\t * the input node is the same as the output node\n\t\t * it is also the GainNode which handles the scaling of incoming signal\n\t\t * \n\t\t * @type {GainNode}\n\t\t * @private\n\t\t */\n\t\tthis._mult = this.input[0] = this.output = new Tone.Gain();\n\n\t\t/**\n\t\t * the scaling parameter\n\t\t * @type {AudioParam}\n\t\t * @private\n\t\t */\n\t\tthis._param = this.input[1] = this.output.gain;\n\t\t\n\t\tthis._param.value = this.defaultArg(value, 0);\n\t};\n\n\tTone.extend(Tone.Multiply, Tone.Signal);\n\n\t/**\n\t * clean up\n\t * @returns {Tone.Multiply} this\n\t */\n\tTone.Multiply.prototype.dispose = function(){\n\t\tTone.prototype.dispose.call(this);\n\t\tthis._mult.dispose();\n\t\tthis._mult = null;\n\t\tthis._param = null;\n\t\treturn this;\n\t}; \n\n\treturn Tone.Multiply;\n});\n","'use strict';\ndefine(function (require) {\n\n var p5sound = require('master');\n var CrossFade = require('Tone/component/CrossFade');\n\n /**\n * Effect is a base class for audio effects in p5. \n * This module handles the nodes and methods that are\n * common and useful for current and future effects.\n *\n *\n * This class is extended by p5.Distortion,\n * p5.Compressor,\n * p5.Delay,\n * p5.Filter,\n * p5.Reverb.\n *\n * @class p5.Effect\n * @constructor\n *\n * @param {Object} [ac] Reference to the audio context of the p5 object\n * @param {AudioNode} [input] Gain Node effect wrapper\n * @param {AudioNode} [output] Gain Node effect wrapper\n * @param {Object} [_drywet] Tone.JS CrossFade node (defaults to value: 1)\n * @param {AudioNode} [wet] Effects that extend this class should connect\n * to the wet signal to this gain node, so that dry and wet\n * signals are mixed properly.\n */\n p5.Effect = function() {\n this.ac = p5sound.audiocontext;\n\n this.input = this.ac.createGain();\n this.output = this.ac.createGain();\n\n /**\n *\tThe p5.Effect class is built\n * \tusing Tone.js CrossFade\n * \t@private\n */\n\n this._drywet = new CrossFade(1);\n\n /**\n *\tIn classes that extend\n *\tp5.Effect, connect effect nodes\n *\tto the wet parameter\n */\n this.wet = this.ac.createGain();\n\n this.input.connect(this._drywet.a);\n this.wet.connect(this._drywet.b);\n this._drywet.connect(this.output);\n\n this.connect();\n\n //Add to the soundArray\n p5sound.soundArray.push(this);\n };\n\n /**\n * Set the output volume of the filter.\n *\n * @method amp\n * @for p5.Effect\n * @param {Number} [vol] amplitude between 0 and 1.0\n * @param {Number} [rampTime] create a fade that lasts until rampTime\n * @param {Number} [tFromNow] schedule this event to happen in tFromNow seconds\n */\n p5.Effect.prototype.amp = function(vol, rampTime, tFromNow){\n var rampTime = rampTime || 0;\n var tFromNow = tFromNow || 0;\n var now = p5sound.audiocontext.currentTime;\n var currentVol = this.output.gain.value;\n this.output.gain.cancelScheduledValues(now);\n this.output.gain.linearRampToValueAtTime(currentVol, now + tFromNow + .001);\n this.output.gain.linearRampToValueAtTime(vol, now + tFromNow + rampTime + .001);\n };\n\n /**\n * Link effects together in a chain\n * Example usage: filter.chain(reverb, delay, panner);\n * May be used with an open-ended number of arguments\n *\n * @method chain\n * @for p5.Effect\n * @param {Object} [arguments] Chain together multiple sound objects\n */\n p5.Effect.prototype.chain = function(){\n if (arguments.length>0){\n this.connect(arguments[0]);\n for(var i=1;i\n * var notes = [60, 64, 67, 72];\n * var i = 0;\n *\n * function setup() {\n * osc = new p5.Oscillator('Triangle');\n * osc.start();\n * frameRate(1);\n * }\n *\n * function draw() {\n * var freq = midiToFreq(notes[i]);\n * osc.freq(freq);\n * i++;\n * if (i >= notes.length){\n * i = 0;\n * }\n * }\n * \n */\n var midiToFreq = p5.prototype.midiToFreq = function(m) {\n return 440 * Math.pow(2, (m-69)/12.0);\n };\n\n // This method converts ANSI notes specified as a string \"C4\", \"Eb3\" to a frequency\n var noteToFreq = function(note) {\n if (typeof note !== 'string') {\n return note;\n }\n var wholeNotes = {A:21, B:23, C:24, D:26, E:28, F:29, G:31};\n var value = wholeNotes[ note[0].toUpperCase() ];\n var octave = ~~note.slice(-1);\n value += 12 * (octave -1);\n\n switch(note[1]) {\n case '#':\n value += 1;\n break;\n case 'b':\n value -= 1;\n break;\n default:\n break;\n }\n return midiToFreq(value);\n };\n\n /**\n * List the SoundFile formats that you will include. LoadSound\n * will search your directory for these extensions, and will pick\n * a format that is compatable with the client's web browser.\n * Here is a free online file\n * converter.\n *\n * @method soundFormats\n * @param {String} [...formats] i.e. 'mp3', 'wav', 'ogg'\n * @example\n *
\n * function preload() {\n * // set the global sound formats\n * soundFormats('mp3', 'ogg');\n *\n * // load either beatbox.mp3, or .ogg, depending on browser\n * mySound = loadSound('assets/beatbox.mp3');\n * }\n *\n * function setup() {\n * mySound.play();\n * }\n *
\n */\n p5.prototype.soundFormats = function() {\n // reset extensions array\n p5sound.extensions = [];\n // add extensions\n for (var i = 0; i < arguments.length; i++) {\n arguments[i] = arguments[i].toLowerCase();\n if (['mp3','wav','ogg', 'm4a', 'aac'].indexOf(arguments[i]) > -1) {\n p5sound.extensions.push(arguments[i]);\n } else {\n throw arguments[i] + ' is not a valid sound format!';\n }\n }\n };\n\n p5.prototype.disposeSound = function() {\n for (var i = 0; i < p5sound.soundArray.length; i++) {\n p5sound.soundArray[i].dispose();\n }\n };\n\n // register removeSound to dispose of p5sound SoundFiles, Convolvers,\n // Oscillators etc when sketch ends\n p5.prototype.registerMethod('remove', p5.prototype.disposeSound);\n\n p5.prototype._checkFileFormats = function(paths) {\n var path;\n // if path is a single string, check to see if extension is provided\n if (typeof paths === 'string') {\n path = paths;\n // see if extension is provided\n var extTest = path.split('.').pop();\n // if an extension is provided...\n if (['mp3','wav','ogg', 'm4a', 'aac'].indexOf(extTest) > -1) {\n if (p5.prototype.isFileSupported(extTest)) {\n path = path;\n }\n else {\n var pathSplit = path.split('.');\n var pathCore = pathSplit[pathSplit.length - 1];\n for (var i = 0; i 1) {\n rightChannel = audioBuffer.getChannelData(1);\n } else {\n rightChannel = leftChannel;\n }\n\n var interleaved = interleave(leftChannel, rightChannel);\n\n // create the buffer and view to create the .WAV file\n var buffer = new window.ArrayBuffer(44 + interleaved.length * 2);\n var view = new window.DataView(buffer);\n\n // write the WAV container,\n // check spec at: https://web.archive.org/web/20171215131933/http://tiny.systems/software/soundProgrammer/WavFormatDocs.pdf\n\n // RIFF chunk descriptor\n writeUTFBytes(view, 0, 'RIFF');\n view.setUint32(4, 36 + interleaved.length * 2, true);\n writeUTFBytes(view, 8, 'WAVE');\n // FMT sub-chunk\n writeUTFBytes(view, 12, 'fmt ');\n view.setUint32(16, 16, true);\n view.setUint16(20, 1, true);\n // stereo (2 channels)\n view.setUint16(22, 2, true);\n view.setUint32(24, p5sound.audiocontext.sampleRate, true);\n view.setUint32(28, p5sound.audiocontext.sampleRate * 4, true);\n view.setUint16(32, 4, true);\n view.setUint16(34, 16, true);\n // data sub-chunk\n writeUTFBytes(view, 36, 'data');\n view.setUint32(40, interleaved.length * 2, true);\n\n // write the PCM samples\n var lng = interleaved.length;\n var index = 44;\n var volume = 1;\n for (var i = 0; i < lng; i++) {\n view.setInt16(index, interleaved[i] * (0x7FFF * volume), true);\n index += 2;\n }\n\n return view;\n }\n\n // helper methods to save waves\n function interleave(leftChannel, rightChannel) {\n var length = leftChannel.length + rightChannel.length;\n var result = new Float32Array(length);\n\n var inputIndex = 0;\n\n for (var index = 0; index < length;) {\n result[index++] = leftChannel[inputIndex];\n result[index++] = rightChannel[inputIndex];\n inputIndex++;\n }\n return result;\n }\n\n function writeUTFBytes(view, offset, string) {\n var lng = string.length;\n for (var i = 0; i < lng; i++) {\n view.setUint8(offset + i, string.charCodeAt(i));\n }\n }\n\n return {\n convertToWav: convertToWav,\n midiToFreq: midiToFreq,\n noteToFreq: noteToFreq\n };\n\n});\n","define([\"Tone/core/Tone\", \"Tone/signal/Signal\", \"Tone/core/Gain\"], function(Tone){\n\n\t\"use strict\";\n\n\t/**\n\t * @class Add a signal and a number or two signals. When no value is\n\t * passed into the constructor, Tone.Add will sum input[0]\n\t * and input[1]. If a value is passed into the constructor, \n\t * the it will be added to the input.\n\t * \n\t * @constructor\n\t * @extends {Tone.Signal}\n\t * @param {number=} value If no value is provided, Tone.Add will sum the first\n\t * and second inputs. \n\t * @example\n\t * var signal = new Tone.Signal(2);\n\t * var add = new Tone.Add(2);\n\t * signal.connect(add);\n\t * //the output of add equals 4\n\t * @example\n\t * //if constructed with no arguments\n\t * //it will add the first and second inputs\n\t * var add = new Tone.Add();\n\t * var sig0 = new Tone.Signal(3).connect(add, 0, 0);\n\t * var sig1 = new Tone.Signal(4).connect(add, 0, 1);\n\t * //the output of add equals 7. \n\t */\n\tTone.Add = function(value){\n\n\t\tthis.createInsOuts(2, 0);\n\n\t\t/**\n\t\t * the summing node\n\t\t * @type {GainNode}\n\t\t * @private\n\t\t */\n\t\tthis._sum = this.input[0] = this.input[1] = this.output = new Tone.Gain();\n\n\t\t/**\n\t\t * @private\n\t\t * @type {Tone.Signal}\n\t\t */\n\t\tthis._param = this.input[1] = new Tone.Signal(value);\n\n\t\tthis._param.connect(this._sum);\n\t};\n\n\tTone.extend(Tone.Add, Tone.Signal);\n\t\n\t/**\n\t * Clean up.\n\t * @returns {Tone.Add} this\n\t */\n\tTone.Add.prototype.dispose = function(){\n\t\tTone.prototype.dispose.call(this);\n\t\tthis._sum.dispose();\n\t\tthis._sum = null;\n\t\tthis._param.dispose();\n\t\tthis._param = null;\n\t\treturn this;\n\t}; \n\n\treturn Tone.Add;\n});","define([\"Tone/core/Tone\", \"Tone/type/Time\", \"Tone/type/Frequency\", \"Tone/type/TransportTime\", \"Tone/core/Context\"],\nfunction (Tone) {\t\n\n\t///////////////////////////////////////////////////////////////////////////\n\t//\tTYPES\n\t///////////////////////////////////////////////////////////////////////////\n\n\t/**\n\t * Units which a value can take on.\n\t * @enum {String}\n\t */\n\tTone.Type = {\n\t\t/** \n\t\t * Default units\n\t\t * @typedef {Default}\n\t\t */\n\t\tDefault : \"number\",\n\t\t/**\n\t\t * Time can be described in a number of ways. Read more [Time](https://github.com/Tonejs/Tone.js/wiki/Time).\n\t\t *\n\t\t *
\n\t\t *
Numbers, which will be taken literally as the time (in seconds).
\n\t\t *
Notation, (\"4n\", \"8t\") describes time in BPM and time signature relative values.
\n\t\t *
TransportTime, (\"4:3:2\") will also provide tempo and time signature relative times \n\t\t * in the form BARS:QUARTERS:SIXTEENTHS.
\n\t\t *
Frequency, (\"8hz\") is converted to the length of the cycle in seconds.
\n\t\t *
Now-Relative, (\"+1\") prefix any of the above with \"+\" and it will be interpreted as \n\t\t * \"the current time plus whatever expression follows\".
\n\t\t *
Expressions, (\"3:0 + 2 - (1m / 7)\") any of the above can also be combined \n\t\t * into a mathematical expression which will be evaluated to compute the desired time.
\n\t\t *
No Argument, for methods which accept time, no argument will be interpreted as \n\t\t * \"now\" (i.e. the currentTime).
\n\t\t *
\n\t\t * \n\t\t * @typedef {Time}\n\t\t */\n\t\tTime : \"time\",\n\t\t/**\n\t\t * Frequency can be described similar to time, except ultimately the\n\t\t * values are converted to frequency instead of seconds. A number\n\t\t * is taken literally as the value in hertz. Additionally any of the \n\t\t * Time encodings can be used. Note names in the form\n\t\t * of NOTE OCTAVE (i.e. C4) are also accepted and converted to their\n\t\t * frequency value. \n\t\t * @typedef {Frequency}\n\t\t */\n\t\tFrequency : \"frequency\",\n\t\t/**\n\t\t * TransportTime describes a position along the Transport's timeline. It is\n\t\t * similar to Time in that it uses all the same encodings, but TransportTime specifically\n\t\t * pertains to the Transport's timeline, which is startable, stoppable, loopable, and seekable. \n\t\t * [Read more](https://github.com/Tonejs/Tone.js/wiki/TransportTime)\n\t\t * @typedef {TransportTime}\n\t\t */\n\t\tTransportTime : \"transportTime\",\n\t\t/** \n\t\t * Ticks are the basic subunit of the Transport. They are\n\t\t * the smallest unit of time that the Transport supports.\n\t\t * @typedef {Ticks}\n\t\t */\n\t\tTicks : \"ticks\",\n\t\t/** \n\t\t * Normal values are within the range [0, 1].\n\t\t * @typedef {NormalRange}\n\t\t */\n\t\tNormalRange : \"normalRange\",\n\t\t/** \n\t\t * AudioRange values are between [-1, 1].\n\t\t * @typedef {AudioRange}\n\t\t */\n\t\tAudioRange : \"audioRange\",\n\t\t/** \n\t\t * Decibels are a logarithmic unit of measurement which is useful for volume\n\t\t * because of the logarithmic way that we perceive loudness. 0 decibels \n\t\t * means no change in volume. -10db is approximately half as loud and 10db \n\t\t * is twice is loud. \n\t\t * @typedef {Decibels}\n\t\t */\n\t\tDecibels : \"db\",\n\t\t/** \n\t\t * Half-step note increments, i.e. 12 is an octave above the root. and 1 is a half-step up.\n\t\t * @typedef {Interval}\n\t\t */\n\t\tInterval : \"interval\",\n\t\t/** \n\t\t * Beats per minute. \n\t\t * @typedef {BPM}\n\t\t */\n\t\tBPM : \"bpm\",\n\t\t/** \n\t\t * The value must be greater than or equal to 0.\n\t\t * @typedef {Positive}\n\t\t */\n\t\tPositive : \"positive\",\n\t\t/** \n\t\t * A cent is a hundredth of a semitone. \n\t\t * @typedef {Cents}\n\t\t */\n\t\tCents : \"cents\",\n\t\t/** \n\t\t * Angle between 0 and 360. \n\t\t * @typedef {Degrees}\n\t\t */\n\t\tDegrees : \"degrees\",\n\t\t/** \n\t\t * A number representing a midi note.\n\t\t * @typedef {MIDI}\n\t\t */\n\t\tMIDI : \"midi\",\n\t\t/** \n\t\t * A colon-separated representation of time in the form of\n\t\t * Bars:Beats:Sixteenths. \n\t\t * @typedef {BarsBeatsSixteenths}\n\t\t */\n\t\tBarsBeatsSixteenths : \"barsBeatsSixteenths\",\n\t\t/** \n\t\t * Sampling is the reduction of a continuous signal to a discrete signal.\n\t\t * Audio is typically sampled 44100 times per second. \n\t\t * @typedef {Samples}\n\t\t */\n\t\tSamples : \"samples\",\n\t\t/** \n\t\t * Hertz are a frequency representation defined as one cycle per second.\n\t\t * @typedef {Hertz}\n\t\t */\n\t\tHertz : \"hertz\",\n\t\t/** \n\t\t * A frequency represented by a letter name, \n\t\t * accidental and octave. This system is known as\n\t\t * [Scientific Pitch Notation](https://en.wikipedia.org/wiki/Scientific_pitch_notation).\n\t\t * @typedef {Note}\n\t\t */\n\t\tNote : \"note\",\n\t\t/** \n\t\t * One millisecond is a thousandth of a second. \n\t\t * @typedef {Milliseconds}\n\t\t */\n\t\tMilliseconds : \"milliseconds\",\n\t\t/** \n\t\t * Seconds are the time unit of the AudioContext. In the end, \n\t\t * all values need to be evaluated to seconds. \n\t\t * @typedef {Seconds}\n\t\t */\n\t\tSeconds : \"seconds\",\n\t\t/** \n\t\t * A string representing a duration relative to a measure. \n\t\t *
\n\t\t * \t
\"4n\" = quarter note
\n\t\t * \t
\"2m\" = two measures
\n\t\t * \t
\"8t\" = eighth-note triplet
\n\t\t *
\n\t\t * @typedef {Notation}\n\t\t */\n\t\tNotation : \"notation\",\n\t};\n\n\t///////////////////////////////////////////////////////////////////////////\n\t// AUGMENT TONE's PROTOTYPE\n\t///////////////////////////////////////////////////////////////////////////\n\n\t/**\n\t * Convert Time into seconds.\n\t * \n\t * Unlike the method which it overrides, this takes into account \n\t * transporttime and musical notation.\n\t *\n\t * Time : 1.40\n\t * Notation: 4n|1m|2t\n\t * Now Relative: +3n\n\t * Math: 3n+16n or even complicated expressions ((3n*2)/6 + 1)\n\t *\n\t * @param {Time} time \n\t * @return {Seconds} \n\t */\n\tTone.prototype.toSeconds = function(time){\n\t\tif (this.isNumber(time)){\n\t\t\treturn time;\n\t\t} else if (this.isUndef(time)){\n\t\t\treturn this.now();\t\t\t\n\t\t} else if (this.isString(time)){\n\t\t\treturn (new Tone.Time(time)).toSeconds();\n\t\t} else if (time instanceof Tone.TimeBase){\n\t\t\treturn time.toSeconds();\n\t\t}\n\t};\n\n\t/**\n\t * Convert a frequency representation into a number.\n\t * @param {Frequency} freq \n\t * @return {Hertz} the frequency in hertz\n\t */\n\tTone.prototype.toFrequency = function(freq){\n\t\tif (this.isNumber(freq)){\n\t\t\treturn freq;\n\t\t} else if (this.isString(freq) || this.isUndef(freq)){\n\t\t\treturn (new Tone.Frequency(freq)).valueOf();\n\t\t} else if (freq instanceof Tone.TimeBase){\n\t\t\treturn freq.toFrequency();\n\t\t}\n\t};\n\n\t/**\n\t * Convert a time representation into ticks.\n\t * @param {Time} time\n\t * @return {Ticks} the time in ticks\n\t */\n\tTone.prototype.toTicks = function(time){\n\t\tif (this.isNumber(time) || this.isString(time)){\n\t\t\treturn (new Tone.TransportTime(time)).toTicks();\n\t\t} else if (this.isUndef(time)){\n\t\t\treturn Tone.Transport.ticks;\t\t\t\n\t\t} else if (time instanceof Tone.TimeBase){\n\t\t\treturn time.toTicks();\n\t\t}\n\t};\n\n\treturn Tone;\n});","define([\"Tone/core/Tone\", \"Tone/core/Param\", \"Tone/type/Type\"], function (Tone) {\n\n\t\"use strict\";\n\n\t/**\n\t * createGain shim\n\t * @private\n\t */\n\tif (window.GainNode && !AudioContext.prototype.createGain){\n\t\tAudioContext.prototype.createGain = AudioContext.prototype.createGainNode;\n\t}\n\n\t/**\n\t * @class A thin wrapper around the Native Web Audio GainNode.\n\t * The GainNode is a basic building block of the Web Audio\n\t * API and is useful for routing audio and adjusting gains. \n\t * @extends {Tone}\n\t * @param {Number=} gain The initial gain of the GainNode\n\t * @param {Tone.Type=} units The units of the gain parameter. \n\t */\n\tTone.Gain = function(){\n\n\t\tvar options = this.optionsObject(arguments, [\"gain\", \"units\"], Tone.Gain.defaults);\n\n\t\t/**\n\t\t * The GainNode\n\t\t * @type {GainNode}\n\t\t * @private\n\t\t */\n\t\tthis.input = this.output = this._gainNode = this.context.createGain();\n\n\t\t/**\n\t\t * The gain parameter of the gain node.\n\t\t * @type {Tone.Param}\n\t\t * @signal\n\t\t */\n\t\tthis.gain = new Tone.Param({\n\t\t\t\"param\" : this._gainNode.gain, \n\t\t\t\"units\" : options.units,\n\t\t\t\"value\" : options.gain,\n\t\t\t\"convert\" : options.convert\n\t\t});\n\t\tthis._readOnly(\"gain\");\n\t};\n\n\tTone.extend(Tone.Gain);\n\n\t/**\n\t * The defaults\n\t * @const\n\t * @type {Object}\n\t */\n\tTone.Gain.defaults = {\n\t\t\"gain\" : 1,\n\t\t\"convert\" : true,\n\t};\n\n\t/**\n\t * Clean up.\n\t * @return {Tone.Gain} this\n\t */\n\tTone.Gain.prototype.dispose = function(){\n\t\tTone.Param.prototype.dispose.call(this);\n\t\tthis._gainNode.disconnect();\n\t\tthis._gainNode = null;\n\t\tthis._writable(\"gain\");\n\t\tthis.gain.dispose();\n\t\tthis.gain = null;\n\t};\n\n\t//STATIC///////////////////////////////////////////////////////////////////\n\n\t/**\n\t * Create input and outputs for this object.\n\t * @param {Number} input The number of inputs\n\t * @param {Number=} outputs The number of outputs\n\t * @return {Tone} this\n\t * @internal\n\t */\n\tTone.prototype.createInsOuts = function(inputs, outputs){\n\n\t\tif (inputs === 1){\n\t\t\tthis.input = new Tone.Gain();\n\t\t} else if (inputs > 1){\n\t\t\tthis.input = new Array(inputs);\n\t\t}\n\n\t\tif (outputs === 1){\n\t\t\tthis.output = new Tone.Gain();\n\t\t} else if (outputs > 1){\n\t\t\tthis.output = new Array(inputs);\n\t\t}\n\t};\n\n\t///////////////////////////////////////////////////////////////////////////\n\n\treturn Tone.Gain;\n});","'use strict';\n\ndefine(function () {\n /*\n Helper function to generate an error\n with a custom stack trace that points to the sketch\n and removes other parts of the stack trace.\n\n @private\n @class customError\n @constructor\n @param {String} name custom error name\n @param {String} errorTrace custom error trace\n @param {String} failedPath path to the file that failed to load\n @property {String} name custom error name\n @property {String} message custom error message\n @property {String} stack trace the error back to a line in the user's sketch.\n Note: this edits out stack trace within p5.js and p5.sound.\n @property {String} originalStack unedited, original stack trace\n @property {String} failedPath path to the file that failed to load\n @return {Error} returns a custom Error object\n */\n var CustomError = function(name, errorTrace, failedPath) {\n var err = new Error();\n var tempStack, splitStack;\n\n err.name = name;\n err.originalStack = err.stack + errorTrace;\n tempStack = err.stack + errorTrace;\n err.failedPath = failedPath;\n\n // only print the part of the stack trace that refers to the user code:\n var splitStack = tempStack.split('\\n');\n splitStack = splitStack.filter(function(ln) {\n return !ln.match(/(p5.|native code|globalInit)/g);\n });\n err.stack = splitStack.join('\\n');\n\n return err; // TODO: is this really a constructor?\n };\n\n return CustomError;\n});\n","define([\"Tone/core/Tone\", \"Tone/core/Emitter\"], function (Tone) {\n\n\t/**\n\t * shim\n\t * @private\n\t */\n\tif (!window.hasOwnProperty(\"AudioContext\") && window.hasOwnProperty(\"webkitAudioContext\")){\n\t\twindow.AudioContext = window.webkitAudioContext;\n\t}\n\n\t/**\n\t * @class Wrapper around the native AudioContext.\n\t * @extends {Tone.Emitter}\n\t * @param {AudioContext=} context optionally pass in a context\n\t */\n\tTone.Context = function(context){\n\n\t\tTone.Emitter.call(this);\n\n\t\tif (!context){\n\t\t\tcontext = new window.AudioContext();\n\t\t}\n\t\tthis._context = context;\n\t\t// extend all of the methods\n\t\tfor (var prop in this._context){\n\t\t\tthis._defineProperty(this._context, prop);\n\t\t}\n\n\t\t///////////////////////////////////////////////////////////////////////\n\t\t// WORKER\n\t\t///////////////////////////////////////////////////////////////////////\n\n\t\t/**\n\t\t * The default latency hint\n\t\t * @type {String}\n\t\t * @private\n\t\t */\n\t\tthis._latencyHint = \"interactive\";\n\n\t\t/**\n\t\t * The amount of time events are scheduled\n\t\t * into the future\n\t\t * @type {Number}\n\t\t * @private\n\t\t */\n\t\tthis._lookAhead = 0.1;\n\n\t\t/**\n\t\t * How often the update look runs\n\t\t * @type {Number}\n\t\t * @private\n\t\t */\n\t\tthis._updateInterval = this._lookAhead/3;\n\n\t\t/**\n\t\t * A reference to the actual computed update interval\n\t\t * @type {Number}\n\t\t * @private\n\t\t */\n\t\tthis._computedUpdateInterval = 0;\n\n\t\t/**\n\t\t * The web worker which is used to update Tone.Clock\n\t\t * @private\n\t\t * @type {WebWorker}\n\t\t */\n\t\tthis._worker = this._createWorker();\n\n\t\t/**\n\t\t * An object containing all of the constants AudioBufferSourceNodes\n\t\t * @type {Object}\n\t\t * @private\n\t\t */\n\t\tthis._constants = {};\n\n\t};\n\n\tTone.extend(Tone.Context, Tone.Emitter);\n\tTone.Emitter.mixin(Tone.Context);\n\n\t/**\n\t * Define a property on this Tone.Context. \n\t * This is used to extend the native AudioContext\n\t * @param {AudioContext} context\n\t * @param {String} prop \n\t * @private\n\t */\n\tTone.Context.prototype._defineProperty = function(context, prop){\n\t\tif (this.isUndef(this[prop])){\n\t\t\tObject.defineProperty(this, prop, {\n\t\t\t\tget : function(){\n\t\t\t\t\tif (typeof context[prop] === \"function\"){\n\t\t\t\t\t\treturn context[prop].bind(context);\n\t\t\t\t\t} else {\n\t\t\t\t\t\treturn context[prop];\n\t\t\t\t\t}\n\t\t\t\t},\n\t\t\t\tset : function(val){\n\t\t\t\t\tcontext[prop] = val;\n\t\t\t\t}\n\t\t\t});\n\t\t}\n\t};\n\n\t/**\n\t * The current audio context time\n\t * @return {Number}\n\t */\n\tTone.Context.prototype.now = function(){\n\t\treturn this._context.currentTime;\n\t};\n\n\t/**\n\t * Generate a web worker\n\t * @return {WebWorker}\n\t * @private\n\t */\n\tTone.Context.prototype._createWorker = function(){\n\t\t\n\t\t//URL Shim\n\t\twindow.URL = window.URL || window.webkitURL;\n\n\t\tvar blob = new Blob([\n\t\t\t//the initial timeout time\n\t\t\t\"var timeoutTime = \"+(this._updateInterval * 1000).toFixed(1)+\";\" +\n\t\t\t//onmessage callback\n\t\t\t\"self.onmessage = function(msg){\" +\n\t\t\t\"\ttimeoutTime = parseInt(msg.data);\" + \n\t\t\t\"};\" + \n\t\t\t//the tick function which posts a message\n\t\t\t//and schedules a new tick\n\t\t\t\"function tick(){\" +\n\t\t\t\"\tsetTimeout(tick, timeoutTime);\" +\n\t\t\t\"\tself.postMessage('tick');\" +\n\t\t\t\"}\" +\n\t\t\t//call tick initially\n\t\t\t\"tick();\"\n\t\t]);\n\t\tvar blobUrl = URL.createObjectURL(blob);\n\t\tvar worker = new Worker(blobUrl);\n\n\t\tworker.addEventListener(\"message\", function(){\n\t\t\t// tick the clock\n\t\t\tthis.emit(\"tick\");\n\t\t}.bind(this));\n\n\t\t//lag compensation\n\t\tworker.addEventListener(\"message\", function(){\n\t\t\tvar now = this.now();\n\t\t\tif (this.isNumber(this._lastUpdate)){\n\t\t\t\tvar diff = now - this._lastUpdate;\n\t\t\t\tthis._computedUpdateInterval = Math.max(diff, this._computedUpdateInterval * 0.97);\n\t\t\t}\n\t\t\tthis._lastUpdate = now;\n\t\t}.bind(this));\n\n\t\treturn worker;\n\t};\n\n\t/**\n\t * Generate a looped buffer at some constant value.\n\t * @param {Number} val\n\t * @return {BufferSourceNode}\n\t */\n\tTone.Context.prototype.getConstant = function(val){\n\t\tif (this._constants[val]){\n\t\t\treturn this._constants[val];\n\t\t} else {\n\t\t\tvar buffer = this._context.createBuffer(1, 128, this._context.sampleRate);\n\t\t\tvar arr = buffer.getChannelData(0);\n\t\t\tfor (var i = 0; i < arr.length; i++){\n\t\t\t\tarr[i] = val;\n\t\t\t}\n\t\t\tvar constant = this._context.createBufferSource();\n\t\t\tconstant.channelCount = 1;\n\t\t\tconstant.channelCountMode = \"explicit\";\n\t\t\tconstant.buffer = buffer;\n\t\t\tconstant.loop = true;\n\t\t\tconstant.start(0);\n\t\t\tthis._constants[val] = constant;\n\t\t\treturn constant;\n\t\t}\n\t};\n\n\t/**\n\t * This is the time that the clock is falling behind\n\t * the scheduled update interval. The Context automatically\n\t * adjusts for the lag and schedules further in advance.\n\t * @type {Number}\n\t * @memberOf Tone.Context\n\t * @name lag\n\t * @static\n\t * @readOnly\n\t */\n\tObject.defineProperty(Tone.Context.prototype, \"lag\", {\n\t\tget : function(){\n\t\t\tvar diff = this._computedUpdateInterval - this._updateInterval;\n\t\t\tdiff = Math.max(diff, 0);\n\t\t\treturn diff;\n\t\t}\n\t});\n\n\t/**\n\t * The amount of time in advance that events are scheduled.\n\t * The lookAhead will adjust slightly in response to the \n\t * measured update time to try to avoid clicks.\n\t * @type {Number}\n\t * @memberOf Tone.Context\n\t * @name lookAhead\n\t * @static\n\t */\n\tObject.defineProperty(Tone.Context.prototype, \"lookAhead\", {\n\t\tget : function(){\n\t\t\treturn this._lookAhead;\n\t\t},\n\t\tset : function(lA){\n\t\t\tthis._lookAhead = lA;\n\t\t}\n\t});\n\n\t/**\n\t * How often the Web Worker callback is invoked.\n\t * This number corresponds to how responsive the scheduling\n\t * can be. Context.updateInterval + Context.lookAhead gives you the\n\t * total latency between scheduling an event and hearing it.\n\t * @type {Number}\n\t * @memberOf Tone.Context\n\t * @name updateInterval\n\t * @static\n\t */\n\tObject.defineProperty(Tone.Context.prototype, \"updateInterval\", {\n\t\tget : function(){\n\t\t\treturn this._updateInterval;\n\t\t},\n\t\tset : function(interval){\n\t\t\tthis._updateInterval = Math.max(interval, Tone.prototype.blockTime);\n\t\t\tthis._worker.postMessage(Math.max(interval * 1000, 1));\n\t\t}\n\t});\n\n\t/**\n\t * The type of playback, which affects tradeoffs between audio \n\t * output latency and responsiveness. \n\t * \n\t * In addition to setting the value in seconds, the latencyHint also\n\t * accepts the strings \"interactive\" (prioritizes low latency), \n\t * \"playback\" (prioritizes sustained playback), \"balanced\" (balances\n\t * latency and performance), and \"fastest\" (lowest latency, might glitch more often). \n\t * @type {String|Seconds}\n\t * @memberOf Tone.Context#\n\t * @name latencyHint\n\t * @static\n\t * @example\n\t * //set the lookAhead to 0.3 seconds\n\t * Tone.context.latencyHint = 0.3;\n\t */\n\tObject.defineProperty(Tone.Context.prototype, \"latencyHint\", {\n\t\tget : function(){\n\t\t\treturn this._latencyHint;\n\t\t},\n\t\tset : function(hint){\n\t\t\tvar lookAhead = hint;\n\t\t\tthis._latencyHint = hint;\n\t\t\tif (this.isString(hint)){\n\t\t\t\tswitch(hint){\n\t\t\t\t\tcase \"interactive\" :\n\t\t\t\t\t\tlookAhead = 0.1;\n\t\t\t\t\t\tthis._context.latencyHint = hint;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase \"playback\" :\n\t\t\t\t\t\tlookAhead = 0.8;\n\t\t\t\t\t\tthis._context.latencyHint = hint;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase \"balanced\" :\n\t\t\t\t\t\tlookAhead = 0.25;\n\t\t\t\t\t\tthis._context.latencyHint = hint;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase \"fastest\" :\n\t\t\t\t\t\tlookAhead = 0.01;\n\t\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t\tthis.lookAhead = lookAhead;\n\t\t\tthis.updateInterval = lookAhead/3;\n\t\t}\n\t});\n\n\t/**\n\t * Shim all connect/disconnect and some deprecated methods which are still in\n\t * some older implementations.\n\t * @private\n\t */\n\tfunction shimConnect(){\n\n\t\tvar nativeConnect = AudioNode.prototype.connect;\n\t\tvar nativeDisconnect = AudioNode.prototype.disconnect;\n\n\t\t//replace the old connect method\n\t\tfunction toneConnect(B, outNum, inNum){\n\t\t\tif (B.input){\n\t\t\t\tif (Array.isArray(B.input)){\n\t\t\t\t\tif (Tone.prototype.isUndef(inNum)){\n\t\t\t\t\t\tinNum = 0;\n\t\t\t\t\t}\n\t\t\t\t\tthis.connect(B.input[inNum]);\n\t\t\t\t} else {\n\t\t\t\t\tthis.connect(B.input, outNum, inNum);\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\ttry {\n\t\t\t\t\tif (B instanceof AudioNode){\n\t\t\t\t\t\tnativeConnect.call(this, B, outNum, inNum);\n\t\t\t\t\t} else {\n\t\t\t\t\t\tnativeConnect.call(this, B, outNum);\n\t\t\t\t\t}\n\t\t\t\t} catch (e) {\n\t\t\t\t\tthrow new Error(\"error connecting to node: \"+B+\"\\n\"+e);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t//replace the old disconnect method\n\t\tfunction toneDisconnect(B, outNum, inNum){\n\t\t\tif (B && B.input && Array.isArray(B.input)){\n\t\t\t\tif (Tone.prototype.isUndef(inNum)){\n\t\t\t\t\tinNum = 0;\n\t\t\t\t}\n\t\t\t\tthis.disconnect(B.input[inNum], outNum, inNum);\n\t\t\t} else if (B && B.input){\n\t\t\t\tthis.disconnect(B.input, outNum, inNum);\n\t\t\t} else {\n\t\t\t\ttry {\n\t\t\t\t\tnativeDisconnect.apply(this, arguments);\n\t\t\t\t} catch (e) {\n\t\t\t\t\tthrow new Error(\"error disconnecting node: \"+B+\"\\n\"+e);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tif (AudioNode.prototype.connect !== toneConnect){\n\t\t\tAudioNode.prototype.connect = toneConnect;\n\t\t\tAudioNode.prototype.disconnect = toneDisconnect;\n\t\t}\n\t}\n\n\t// set the audio context initially\n\tif (Tone.supported){\n\t\tshimConnect();\n\t\tTone.context = new Tone.Context();\n\t} else {\n\t\tconsole.warn(\"This browser does not support Tone.js\");\n\t}\n\n\treturn Tone.Context;\n});","module.exports = {\n recorderProcessor: 'recorder-processor',\n soundFileProcessor: 'sound-file-processor',\n amplitudeProcessor: 'amplitude-processor'\n};\n","define([\"Tone/core/Tone\", \"Tone/signal/Add\", \"Tone/signal/Multiply\", \"Tone/signal/Signal\"], function(Tone){\n\n\t\"use strict\";\n\t\n\t/**\n\t * @class Performs a linear scaling on an input signal.\n\t * Scales a NormalRange input to between\n\t * outputMin and outputMax.\n\t *\n\t * @constructor\n\t * @extends {Tone.SignalBase}\n\t * @param {number} [outputMin=0] The output value when the input is 0. \n\t * @param {number} [outputMax=1]\tThe output value when the input is 1. \n\t * @example\n\t * var scale = new Tone.Scale(50, 100);\n\t * var signal = new Tone.Signal(0.5).connect(scale);\n\t * //the output of scale equals 75\n\t */\n\tTone.Scale = function(outputMin, outputMax){\n\n\t\t/** \n\t\t * @private\n\t\t * @type {number}\n\t\t */\n\t\tthis._outputMin = this.defaultArg(outputMin, 0);\n\n\t\t/** \n\t\t * @private\n\t\t * @type {number}\n\t\t */\n\t\tthis._outputMax = this.defaultArg(outputMax, 1);\n\n\n\t\t/** \n\t\t * @private\n\t\t * @type {Tone.Multiply}\n\t\t * @private\n\t\t */\n\t\tthis._scale = this.input = new Tone.Multiply(1);\n\t\t\n\t\t/** \n\t\t * @private\n\t\t * @type {Tone.Add}\n\t\t * @private\n\t\t */\n\t\tthis._add = this.output = new Tone.Add(0);\n\n\t\tthis._scale.connect(this._add);\n\t\tthis._setRange();\n\t};\n\n\tTone.extend(Tone.Scale, Tone.SignalBase);\n\n\t/**\n\t * The minimum output value. This number is output when \n\t * the value input value is 0. \n\t * @memberOf Tone.Scale#\n\t * @type {number}\n\t * @name min\n\t */\n\tObject.defineProperty(Tone.Scale.prototype, \"min\", {\n\t\tget : function(){\n\t\t\treturn this._outputMin;\n\t\t},\n\t\tset : function(min){\n\t\t\tthis._outputMin = min;\n\t\t\tthis._setRange();\n\t\t}\n\t});\n\n\t/**\n\t * The maximum output value. This number is output when \n\t * the value input value is 1. \n\t * @memberOf Tone.Scale#\n\t * @type {number}\n\t * @name max\n\t */\n\tObject.defineProperty(Tone.Scale.prototype, \"max\", {\n\t\tget : function(){\n\t\t\treturn this._outputMax;\n\t\t},\n\t\tset : function(max){\n\t\t\tthis._outputMax = max;\n\t\t\tthis._setRange();\n\t\t}\n\t});\n\n\t/**\n\t * set the values\n\t * @private\n\t */\n\tTone.Scale.prototype._setRange = function() {\n\t\tthis._add.value = this._outputMin;\n\t\tthis._scale.value = this._outputMax - this._outputMin;\n\t};\n\n\t/**\n\t * Clean up.\n\t * @returns {Tone.Scale} this\n\t */\n\tTone.Scale.prototype.dispose = function(){\n\t\tTone.prototype.dispose.call(this);\n\t\tthis._add.dispose();\n\t\tthis._add = null;\n\t\tthis._scale.dispose();\n\t\tthis._scale = null;\n\t\treturn this;\n\t}; \n\n\treturn Tone.Scale;\n});\n","define([\"Tone/core/Tone\", \"Tone/signal/Signal\", \"Tone/core/Timeline\"], function (Tone) {\n\n\t\"use strict\";\n\n\t/**\n\t * @class A signal which adds the method getValueAtTime. \n\t * Code and inspiration from https://github.com/jsantell/web-audio-automation-timeline\n\t * @extends {Tone.Param}\n\t * @param {Number=} value The initial value of the signal\n\t * @param {String=} units The conversion units of the signal.\n\t */\n\tTone.TimelineSignal = function(){\n\n\t\tvar options = this.optionsObject(arguments, [\"value\", \"units\"], Tone.Signal.defaults);\n\t\t\n\t\t/**\n\t\t * The scheduled events\n\t\t * @type {Tone.Timeline}\n\t\t * @private\n\t\t */\n\t\tthis._events = new Tone.Timeline(10);\n\n\t\t//constructors\n\t\tTone.Signal.apply(this, options);\n\t\toptions.param = this._param;\n\t\tTone.Param.call(this, options);\n\n\t\t/**\n\t\t * The initial scheduled value\n\t\t * @type {Number}\n\t\t * @private\n\t\t */\n\t\tthis._initial = this._fromUnits(this._param.value);\n\t};\n\n\tTone.extend(Tone.TimelineSignal, Tone.Param);\n\n\t/**\n\t * The event types of a schedulable signal.\n\t * @enum {String}\n\t * @private\n\t */\n\tTone.TimelineSignal.Type = {\n\t\tLinear : \"linear\",\n\t\tExponential : \"exponential\",\n\t\tTarget : \"target\",\n\t\tCurve : \"curve\",\n\t\tSet : \"set\"\n\t};\n\n\t/**\n\t * The current value of the signal. \n\t * @memberOf Tone.TimelineSignal#\n\t * @type {Number}\n\t * @name value\n\t */\n\tObject.defineProperty(Tone.TimelineSignal.prototype, \"value\", {\n\t\tget : function(){\n\t\t\tvar now = this.now();\n\t\t\tvar val = this.getValueAtTime(now);\n\t\t\treturn this._toUnits(val);\n\t\t},\n\t\tset : function(value){\n\t\t\tvar convertedVal = this._fromUnits(value);\n\t\t\tthis._initial = convertedVal;\n\t\t\tthis.cancelScheduledValues();\n\t\t\tthis._param.value = convertedVal;\n\t\t}\n\t});\n\n\t///////////////////////////////////////////////////////////////////////////\n\t//\tSCHEDULING\n\t///////////////////////////////////////////////////////////////////////////\n\n\t/**\n\t * Schedules a parameter value change at the given time.\n\t * @param {*}\tvalue The value to set the signal.\n\t * @param {Time} time The time when the change should occur.\n\t * @returns {Tone.TimelineSignal} this\n\t * @example\n\t * //set the frequency to \"G4\" in exactly 1 second from now. \n\t * freq.setValueAtTime(\"G4\", \"+1\");\n\t */\n\tTone.TimelineSignal.prototype.setValueAtTime = function (value, startTime) {\n\t\tvalue = this._fromUnits(value);\n\t\tstartTime = this.toSeconds(startTime);\n\t\tthis._events.add({\n\t\t\t\"type\" : Tone.TimelineSignal.Type.Set,\n\t\t\t\"value\" : value,\n\t\t\t\"time\" : startTime\n\t\t});\n\t\t//invoke the original event\n\t\tthis._param.setValueAtTime(value, startTime);\n\t\treturn this;\n\t};\n\n\t/**\n\t * Schedules a linear continuous change in parameter value from the \n\t * previous scheduled parameter value to the given value.\n\t * \n\t * @param {number} value \n\t * @param {Time} endTime \n\t * @returns {Tone.TimelineSignal} this\n\t */\n\tTone.TimelineSignal.prototype.linearRampToValueAtTime = function (value, endTime) {\n\t\tvalue = this._fromUnits(value);\n\t\tendTime = this.toSeconds(endTime);\n\t\tthis._events.add({\n\t\t\t\"type\" : Tone.TimelineSignal.Type.Linear,\n\t\t\t\"value\" : value,\n\t\t\t\"time\" : endTime\n\t\t});\n\t\tthis._param.linearRampToValueAtTime(value, endTime);\n\t\treturn this;\n\t};\n\n\t/**\n\t * Schedules an exponential continuous change in parameter value from \n\t * the previous scheduled parameter value to the given value.\n\t * \n\t * @param {number} value \n\t * @param {Time} endTime \n\t * @returns {Tone.TimelineSignal} this\n\t */\n\tTone.TimelineSignal.prototype.exponentialRampToValueAtTime = function (value, endTime) {\n\t\t//get the previous event and make sure it's not starting from 0\n\t\tendTime = this.toSeconds(endTime);\n\t\tvar beforeEvent = this._searchBefore(endTime);\n\t\tif (beforeEvent && beforeEvent.value === 0){\n\t\t\t//reschedule that event\n\t\t\tthis.setValueAtTime(this._minOutput, beforeEvent.time);\n\t\t}\n\t\tvalue = this._fromUnits(value);\n\t\tvar setValue = Math.max(value, this._minOutput);\n\t\tthis._events.add({\n\t\t\t\"type\" : Tone.TimelineSignal.Type.Exponential,\n\t\t\t\"value\" : setValue,\n\t\t\t\"time\" : endTime\n\t\t});\n\t\t//if the ramped to value is 0, make it go to the min output, and then set to 0.\n\t\tif (value < this._minOutput){\n\t\t\tthis._param.exponentialRampToValueAtTime(this._minOutput, endTime - this.sampleTime);\n\t\t\tthis.setValueAtTime(0, endTime);\n\t\t} else {\n\t\t\tthis._param.exponentialRampToValueAtTime(value, endTime);\n\t\t}\n\t\treturn this;\n\t};\n\n\t/**\n\t * Start exponentially approaching the target value at the given time with\n\t * a rate having the given time constant.\n\t * @param {number} value \n\t * @param {Time} startTime \n\t * @param {number} timeConstant \n\t * @returns {Tone.TimelineSignal} this \n\t */\n\tTone.TimelineSignal.prototype.setTargetAtTime = function (value, startTime, timeConstant) {\n\t\tvalue = this._fromUnits(value);\n\t\tvalue = Math.max(this._minOutput, value);\n\t\ttimeConstant = Math.max(this._minOutput, timeConstant);\n\t\tstartTime = this.toSeconds(startTime);\n\t\tthis._events.add({\n\t\t\t\"type\" : Tone.TimelineSignal.Type.Target,\n\t\t\t\"value\" : value,\n\t\t\t\"time\" : startTime,\n\t\t\t\"constant\" : timeConstant\n\t\t});\n\t\tthis._param.setTargetAtTime(value, startTime, timeConstant);\n\t\treturn this;\n\t};\n\n\t/**\n\t * Set an array of arbitrary values starting at the given time for the given duration.\n\t * @param {Float32Array} values \n\t * @param {Time} startTime \n\t * @param {Time} duration\n\t * @param {NormalRange} [scaling=1] If the values in the curve should be scaled by some value\n\t * @returns {Tone.TimelineSignal} this \n\t */\n\tTone.TimelineSignal.prototype.setValueCurveAtTime = function (values, startTime, duration, scaling) {\n\t\tscaling = this.defaultArg(scaling, 1);\n\t\t//copy the array\n\t\tvar floats = new Array(values.length);\n\t\tfor (var i = 0; i < floats.length; i++){\n\t\t\tfloats[i] = this._fromUnits(values[i]) * scaling;\n\t\t}\n\t\tstartTime = this.toSeconds(startTime);\n\t\tduration = this.toSeconds(duration);\n\t\tthis._events.add({\n\t\t\t\"type\" : Tone.TimelineSignal.Type.Curve,\n\t\t\t\"value\" : floats,\n\t\t\t\"time\" : startTime,\n\t\t\t\"duration\" : duration\n\t\t});\n\t\t//set the first value\n\t\tthis._param.setValueAtTime(floats[0], startTime);\n\t\t//schedule a lienar ramp for each of the segments\n\t\tfor (var j = 1; j < floats.length; j++){\n\t\t\tvar segmentTime = startTime + (j / (floats.length - 1) * duration);\n\t\t\tthis._param.linearRampToValueAtTime(floats[j], segmentTime);\n\t\t}\n\t\treturn this;\n\t};\n\n\t/**\n\t * Cancels all scheduled parameter changes with times greater than or \n\t * equal to startTime.\n\t * \n\t * @param {Time} startTime\n\t * @returns {Tone.TimelineSignal} this\n\t */\n\tTone.TimelineSignal.prototype.cancelScheduledValues = function (after) {\n\t\tafter = this.toSeconds(after);\n\t\tthis._events.cancel(after);\n\t\tthis._param.cancelScheduledValues(after);\n\t\treturn this;\n\t};\n\n\t/**\n\t * Sets the computed value at the given time. This provides\n\t * a point from which a linear or exponential curve\n\t * can be scheduled after. Will cancel events after \n\t * the given time and shorten the currently scheduled\n\t * linear or exponential ramp so that it ends at `time` .\n\t * This is to avoid discontinuities and clicks in envelopes. \n\t * @param {Time} time When to set the ramp point\n\t * @returns {Tone.TimelineSignal} this\n\t */\n\tTone.TimelineSignal.prototype.setRampPoint = function (time) {\n\t\ttime = this.toSeconds(time);\n\t\t//get the value at the given time\n\t\tvar val = this._toUnits(this.getValueAtTime(time));\n\t\t//if there is an event at the given time\n\t\t//and that even is not a \"set\"\n\t\tvar before = this._searchBefore(time);\n\t\tif (before && before.time === time){\n\t\t\t//remove everything after\n\t\t\tthis.cancelScheduledValues(time + this.sampleTime);\n\t\t} else if (before && \n\t\t\t\t before.type === Tone.TimelineSignal.Type.Curve &&\n\t\t\t\t before.time + before.duration > time){\n\t\t\t//if the curve is still playing\n\t\t\t//cancel the curve\n\t\t\tthis.cancelScheduledValues(time);\n\t\t\tthis.linearRampToValueAtTime(val, time);\n\t\t} else {\n\t\t\t//reschedule the next event to end at the given time\n\t\t\tvar after = this._searchAfter(time);\n\t\t\tif (after){\n\t\t\t\t//cancel the next event(s)\n\t\t\t\tthis.cancelScheduledValues(time);\n\t\t\t\tif (after.type === Tone.TimelineSignal.Type.Linear){\n\t\t\t\t\tthis.linearRampToValueAtTime(val, time);\n\t\t\t\t} else if (after.type === Tone.TimelineSignal.Type.Exponential){\n\t\t\t\t\tthis.exponentialRampToValueAtTime(val, time);\n\t\t\t\t}\n\t\t\t}\n\t\t\tthis.setValueAtTime(val, time);\n\t\t}\n\t\treturn this;\n\t};\n\n\t/**\n\t * Do a linear ramp to the given value between the start and finish times.\n\t * @param {Number} value The value to ramp to.\n\t * @param {Time} start The beginning anchor point to do the linear ramp\n\t * @param {Time} finish The ending anchor point by which the value of\n\t * the signal will equal the given value.\n\t * @returns {Tone.TimelineSignal} this\n\t */\n\tTone.TimelineSignal.prototype.linearRampToValueBetween = function (value, start, finish) {\n\t\tthis.setRampPoint(start);\n\t\tthis.linearRampToValueAtTime(value, finish);\n\t\treturn this;\n\t};\n\n\t/**\n\t * Do a exponential ramp to the given value between the start and finish times.\n\t * @param {Number} value The value to ramp to.\n\t * @param {Time} start The beginning anchor point to do the exponential ramp\n\t * @param {Time} finish The ending anchor point by which the value of\n\t * the signal will equal the given value.\n\t * @returns {Tone.TimelineSignal} this\n\t */\n\tTone.TimelineSignal.prototype.exponentialRampToValueBetween = function (value, start, finish) {\n\t\tthis.setRampPoint(start);\n\t\tthis.exponentialRampToValueAtTime(value, finish);\n\t\treturn this;\n\t};\n\n\t///////////////////////////////////////////////////////////////////////////\n\t//\tGETTING SCHEDULED VALUES\n\t///////////////////////////////////////////////////////////////////////////\n\n\t/**\n\t * Returns the value before or equal to the given time\n\t * @param {Number} time The time to query\n\t * @return {Object} The event at or before the given time.\n\t * @private\n\t */\n\tTone.TimelineSignal.prototype._searchBefore = function(time){\n\t\treturn this._events.get(time);\n\t};\n\n\t/**\n\t * The event after the given time\n\t * @param {Number} time The time to query.\n\t * @return {Object} The next event after the given time\n\t * @private\n\t */\n\tTone.TimelineSignal.prototype._searchAfter = function(time){\n\t\treturn this._events.getAfter(time);\n\t};\n\n\t/**\n\t * Get the scheduled value at the given time. This will\n\t * return the unconverted (raw) value.\n\t * @param {Number} time The time in seconds.\n\t * @return {Number} The scheduled value at the given time.\n\t */\n\tTone.TimelineSignal.prototype.getValueAtTime = function(time){\n\t\ttime = this.toSeconds(time);\n\t\tvar after = this._searchAfter(time);\n\t\tvar before = this._searchBefore(time);\n\t\tvar value = this._initial;\n\t\t//if it was set by\n\t\tif (before === null){\n\t\t\tvalue = this._initial;\n\t\t} else if (before.type === Tone.TimelineSignal.Type.Target){\n\t\t\tvar previous = this._events.getBefore(before.time);\n\t\t\tvar previouVal;\n\t\t\tif (previous === null){\n\t\t\t\tpreviouVal = this._initial;\n\t\t\t} else {\n\t\t\t\tpreviouVal = previous.value;\n\t\t\t}\n\t\t\tvalue = this._exponentialApproach(before.time, previouVal, before.value, before.constant, time);\n\t\t} else if (before.type === Tone.TimelineSignal.Type.Curve){\n\t\t\tvalue = this._curveInterpolate(before.time, before.value, before.duration, time);\n\t\t} else if (after === null){\n\t\t\tvalue = before.value;\n\t\t} else if (after.type === Tone.TimelineSignal.Type.Linear){\n\t\t\tvalue = this._linearInterpolate(before.time, before.value, after.time, after.value, time);\n\t\t} else if (after.type === Tone.TimelineSignal.Type.Exponential){\n\t\t\tvalue = this._exponentialInterpolate(before.time, before.value, after.time, after.value, time);\n\t\t} else {\n\t\t\tvalue = before.value;\n\t\t}\n\t\treturn value;\n\t};\n\n\t/**\n\t * When signals connect to other signals or AudioParams, \n\t * they take over the output value of that signal or AudioParam. \n\t * For all other nodes, the behavior is the same as a default connect. \n\t *\n\t * @override\n\t * @param {AudioParam|AudioNode|Tone.Signal|Tone} node \n\t * @param {number} [outputNumber=0] The output number to connect from.\n\t * @param {number} [inputNumber=0] The input number to connect to.\n\t * @returns {Tone.TimelineSignal} this\n\t * @method\n\t */\n\tTone.TimelineSignal.prototype.connect = Tone.SignalBase.prototype.connect;\n\n\n\t///////////////////////////////////////////////////////////////////////////\n\t//\tAUTOMATION CURVE CALCULATIONS\n\t//\tMIT License, copyright (c) 2014 Jordan Santell\n\t///////////////////////////////////////////////////////////////////////////\n\n\t/**\n\t * Calculates the the value along the curve produced by setTargetAtTime\n\t * @private\n\t */\n\tTone.TimelineSignal.prototype._exponentialApproach = function (t0, v0, v1, timeConstant, t) {\n\t\treturn v1 + (v0 - v1) * Math.exp(-(t - t0) / timeConstant);\n\t};\n\n\t/**\n\t * Calculates the the value along the curve produced by linearRampToValueAtTime\n\t * @private\n\t */\n\tTone.TimelineSignal.prototype._linearInterpolate = function (t0, v0, t1, v1, t) {\n\t\treturn v0 + (v1 - v0) * ((t - t0) / (t1 - t0));\n\t};\n\n\t/**\n\t * Calculates the the value along the curve produced by exponentialRampToValueAtTime\n\t * @private\n\t */\n\tTone.TimelineSignal.prototype._exponentialInterpolate = function (t0, v0, t1, v1, t) {\n\t\tv0 = Math.max(this._minOutput, v0);\n\t\treturn v0 * Math.pow(v1 / v0, (t - t0) / (t1 - t0));\n\t};\n\n\t/**\n\t * Calculates the the value along the curve produced by setValueCurveAtTime\n\t * @private\n\t */\n\tTone.TimelineSignal.prototype._curveInterpolate = function (start, curve, duration, time) {\n\t\tvar len = curve.length;\n\t\t// If time is after duration, return the last curve value\n\t\tif (time >= start + duration) {\n\t\t\treturn curve[len - 1];\n\t\t} else if (time <= start){\n\t\t\treturn curve[0];\n\t\t} else {\n\t\t\tvar progress = (time - start) / duration;\n\t\t\tvar lowerIndex = Math.floor((len - 1) * progress);\n\t\t\tvar upperIndex = Math.ceil((len - 1) * progress);\n\t\t\tvar lowerVal = curve[lowerIndex];\n\t\t\tvar upperVal = curve[upperIndex];\n\t\t\tif (upperIndex === lowerIndex){\n\t\t\t\treturn lowerVal;\n\t\t\t} else {\n\t\t\t\treturn this._linearInterpolate(lowerIndex, lowerVal, upperIndex, upperVal, progress * (len - 1));\n\t\t\t}\n\t\t}\n\t};\n\n\t/**\n\t * Clean up.\n\t * @return {Tone.TimelineSignal} this\n\t */\n\tTone.TimelineSignal.prototype.dispose = function(){\n\t\tTone.Signal.prototype.dispose.call(this);\n\t\tTone.Param.prototype.dispose.call(this);\n\t\tthis._events.dispose();\n\t\tthis._events = null;\n\t};\n\n\treturn Tone.TimelineSignal;\n});","'use strict';\n\ndefine(function (require) {\n var Effect = require('effect');\n\n /**\n *
A p5.Filter uses a Web Audio Biquad Filter to filter\n * the frequency response of an input source. Subclasses\n * include:
\n * p5.LowPass:\n * Allows frequencies below the cutoff frequency to pass through,\n * and attenuates frequencies above the cutoff. \n * p5.HighPass:\n * The opposite of a lowpass filter. \n * p5.BandPass:\n * Allows a range of frequencies to pass through and attenuates\n * the frequencies below and above this frequency range. \n *\n * The .res() method controls either width of the\n * bandpass, or resonance of the low/highpass cutoff frequency.\n *\n * This class extends p5.Effect.\n * Methods amp(), chain(),\n * drywet(), connect(), and\n * disconnect() are available.\n *\n * @class p5.Filter\n * @extends p5.Effect\n * @constructor\n * @param {String} [type] 'lowpass' (default), 'highpass', 'bandpass'\n * @example\n *
\n * var fft, noise, filter;\n *\n * function setup() {\n * fill(255, 40, 255);\n *\n * filter = new p5.BandPass();\n *\n * noise = new p5.Noise();\n * // disconnect unfiltered noise,\n * // and connect to filter\n * noise.disconnect();\n * noise.connect(filter);\n * noise.start();\n *\n * fft = new p5.FFT();\n * }\n *\n * function draw() {\n * background(30);\n *\n * // set the BandPass frequency based on mouseX\n * var freq = map(mouseX, 0, width, 20, 10000);\n * filter.freq(freq);\n * // give the filter a narrow band (lower res = wider bandpass)\n * filter.res(50);\n *\n * // draw filtered spectrum\n * var spectrum = fft.analyze();\n * noStroke();\n * for (var i = 0; i < spectrum.length; i++) {\n * var x = map(i, 0, spectrum.length, 0, width);\n * var h = -height + map(spectrum[i], 0, 255, height, 0);\n * rect(x, height, width/spectrum.length, h);\n * }\n *\n * isMouseOverCanvas();\n * }\n *\n * function isMouseOverCanvas() {\n * var mX = mouseX, mY = mouseY;\n * if (mX > 0 && mX < width && mY < height && mY > 0) {\n * noise.amp(0.5, 0.2);\n * } else {\n * noise.amp(0, 0.2);\n * }\n * }\n *
\n */\n p5.Filter = function (type) {\n\n Effect.call(this);\n //add extend Effect by adding a Biquad Filter\n\n /**\n * The p5.Filter is built with a\n * \n * Web Audio BiquadFilter Node.\n *\n * @property {DelayNode} biquadFilter\n\t */\n\n this.biquad = this.ac.createBiquadFilter();\n\n this.input.connect(this.biquad);\n\n this.biquad.connect(this.wet);\n\n if (type) {\n this.setType(type);\n }\n\n //Properties useful for the toggle method.\n this._on = true;\n this._untoggledType = this.biquad.type;\n };\n p5.Filter.prototype = Object.create(Effect.prototype);\n\n\n /**\n * Filter an audio signal according to a set\n * of filter parameters.\n *\n * @method process\n * @param {Object} Signal An object that outputs audio\n * @param {Number} [freq] Frequency in Hz, from 10 to 22050\n * @param {Number} [res] Resonance/Width of the filter frequency\n * from 0.001 to 1000\n */\n p5.Filter.prototype.process = function(src, freq, res, time) {\n src.connect(this.input);\n this.set(freq, res, time);\n };\n\n\n /**\n * Set the frequency and the resonance of the filter.\n *\n * @method set\n * @param {Number} [freq] Frequency in Hz, from 10 to 22050\n * @param {Number} [res] Resonance (Q) from 0.001 to 1000\n * @param {Number} [timeFromNow] schedule this event to happen\n * seconds from now\n */\n p5.Filter.prototype.set = function(freq, res, time) {\n if (freq) {\n this.freq(freq, time);\n }\n if (res) {\n this.res(res, time);\n }\n };\n\n /**\n * Set the filter frequency, in Hz, from 10 to 22050 (the range of\n * human hearing, although in reality most people hear in a narrower\n * range).\n *\n * @method freq\n * @param {Number} freq Filter Frequency\n * @param {Number} [timeFromNow] schedule this event to happen\n * seconds from now\n * @return {Number} value Returns the current frequency value\n */\n p5.Filter.prototype.freq = function(freq, time) {\n var t = time || 0;\n if (freq <= 0) {\n freq = 1;\n }\n if (typeof freq === 'number') {\n this.biquad.frequency.cancelScheduledValues(this.ac.currentTime + 0.01 + t);\n this.biquad.frequency.exponentialRampToValueAtTime(freq, this.ac.currentTime + 0.02 + t);\n } else if (freq) {\n freq.connect(this.biquad.frequency);\n }\n return this.biquad.frequency.value;\n };\n\n /**\n * Controls either width of a bandpass frequency,\n * or the resonance of a low/highpass cutoff frequency.\n *\n * @method res\n * @param {Number} res Resonance/Width of filter freq\n * from 0.001 to 1000\n * @param {Number} [timeFromNow] schedule this event to happen\n * seconds from now\n * @return {Number} value Returns the current res value\n */\n p5.Filter.prototype.res = function(res, time) {\n var t = time || 0;\n if (typeof res === 'number') {\n this.biquad.Q.value = res;\n this.biquad.Q.cancelScheduledValues(this.ac.currentTime + 0.01 + t);\n this.biquad.Q.linearRampToValueAtTime(res, this.ac.currentTime + 0.02 + t);\n } else if (res) {\n res.connect(this.biquad.Q);\n }\n return this.biquad.Q.value;\n };\n\n /**\n * Controls the gain attribute of a Biquad Filter.\n * This is distinctly different from .amp() which is inherited from p5.Effect\n * .amp() controls the volume via the output gain node\n * p5.Filter.gain() controls the gain parameter of a Biquad Filter node.\n *\n * @method gain\n * @param {Number} gain\n * @return {Number} Returns the current or updated gain value\n */\n p5.Filter.prototype.gain = function(gain, time) {\n var t = time || 0;\n if (typeof gain === 'number') {\n this.biquad.gain.value = gain;\n this.biquad.gain.cancelScheduledValues(this.ac.currentTime + 0.01 + t);\n this.biquad.gain.linearRampToValueAtTime(gain, this.ac.currentTime + 0.02 + t);\n } else if (gain) {\n gain.connect(this.biquad.gain);\n }\n return this.biquad.gain.value;\n };\n\n\n /**\n * Toggle function. Switches between the specified type and allpass\n *\n * @method toggle\n * @return {boolean} [Toggle value]\n */\n p5.Filter.prototype.toggle = function() {\n this._on = !this._on;\n\n if (this._on === true) {\n this.biquad.type = this._untoggledType;\n } else if (this._on === false) {\n this.biquad.type = 'allpass';\n }\n\n return this._on;\n };\n\n /**\n * Set the type of a p5.Filter. Possible types include:\n * \"lowpass\" (default), \"highpass\", \"bandpass\",\n * \"lowshelf\", \"highshelf\", \"peaking\", \"notch\",\n * \"allpass\".\n *\n * @method setType\n * @param {String} t\n */\n p5.Filter.prototype.setType = function(t) {\n this.biquad.type = t;\n this._untoggledType = this.biquad.type;\n };\n\n p5.Filter.prototype.dispose = function() {\n // remove reference from soundArray\n Effect.prototype.dispose.apply(this);\n if (this.biquad) {\n this.biquad.disconnect();\n delete this.biquad;\n }\n };\n\n /**\n * Constructor: new p5.LowPass() Filter.\n * This is the same as creating a p5.Filter and then calling\n * its method setType('lowpass').\n * See p5.Filter for methods.\n *\n * @class p5.LowPass\n * @constructor\n * @extends p5.Filter\n */\n p5.LowPass = function() {\n p5.Filter.call(this, 'lowpass');\n };\n p5.LowPass.prototype = Object.create(p5.Filter.prototype);\n\n /**\n * Constructor: new p5.HighPass() Filter.\n * This is the same as creating a p5.Filter and then calling\n * its method setType('highpass').\n * See p5.Filter for methods.\n *\n * @class p5.HighPass\n * @constructor\n * @extends p5.Filter\n */\n p5.HighPass = function() {\n p5.Filter.call(this, 'highpass');\n };\n p5.HighPass.prototype = Object.create(p5.Filter.prototype);\n\n /**\n * Constructor: new p5.BandPass() Filter.\n * This is the same as creating a p5.Filter and then calling\n * its method setType('bandpass').\n * See p5.Filter for methods.\n *\n * @class p5.BandPass\n * @constructor\n * @extends p5.Filter\n */\n p5.BandPass = function() {\n p5.Filter.call(this, 'bandpass');\n };\n p5.BandPass.prototype = Object.create(p5.Filter.prototype);\n\n return p5.Filter;\n});\n","define([\"Tone/core/Tone\", \"Tone/signal/Add\", \"Tone/signal/Negate\", \"Tone/signal/Signal\", \"Tone/core/Gain\"], function(Tone){\n\n\t\"use strict\";\n\n\t/**\n\t * @class Subtract the signal connected to input[1] from the signal connected \n\t * to input[0]. If an argument is provided in the constructor, the \n\t * signals .value will be subtracted from the incoming signal.\n\t *\n\t * @extends {Tone.Signal}\n\t * @constructor\n\t * @param {number=} value The value to subtract from the incoming signal. If the value\n\t * is omitted, it will subtract the second signal from the first.\n\t * @example\n\t * var sub = new Tone.Subtract(1);\n\t * var sig = new Tone.Signal(4).connect(sub);\n\t * //the output of sub is 3. \n\t * @example\n\t * var sub = new Tone.Subtract();\n\t * var sigA = new Tone.Signal(10);\n\t * var sigB = new Tone.Signal(2.5);\n\t * sigA.connect(sub, 0, 0);\n\t * sigB.connect(sub, 0, 1);\n\t * //output of sub is 7.5\n\t */\n\tTone.Subtract = function(value){\n\n\t\tthis.createInsOuts(2, 0);\n\n\t\t/**\n\t\t * the summing node\n\t\t * @type {GainNode}\n\t\t * @private\n\t\t */\n\t\tthis._sum = this.input[0] = this.output = new Tone.Gain();\n\n\t\t/**\n\t\t * negate the input of the second input before connecting it\n\t\t * to the summing node.\n\t\t * @type {Tone.Negate}\n\t\t * @private\n\t\t */\n\t\tthis._neg = new Tone.Negate();\n\n\t\t/**\n\t\t * the node where the value is set\n\t\t * @private\n\t\t * @type {Tone.Signal}\n\t\t */\n\t\tthis._param = this.input[1] = new Tone.Signal(value);\n\n\t\tthis._param.chain(this._neg, this._sum);\n\t};\n\n\tTone.extend(Tone.Subtract, Tone.Signal);\n\n\t/**\n\t * Clean up.\n\t * @returns {Tone.SignalBase} this\n\t */\n\tTone.Subtract.prototype.dispose = function(){\n\t\tTone.prototype.dispose.call(this);\n\t\tthis._neg.dispose();\n\t\tthis._neg = null;\n\t\tthis._sum.disconnect();\n\t\tthis._sum = null;\n\t\tthis._param.dispose();\n\t\tthis._param = null;\n\t\treturn this;\n\t};\n\n\treturn Tone.Subtract;\n});","'use strict';\n\nglobal.TONE_SILENCE_VERSION_LOGGING = true;\n\ndefine(['startaudiocontext', 'Tone/core/Context', 'Tone/core/Tone'], function (StartAudioContext, Context, Tone) {\n // Create the Audio Context\n const audiocontext = new window.AudioContext();\n\n // Tone and p5.sound share the same audio context\n Tone.context.dispose();\n Tone.setContext(audiocontext);\n\n /**\n *
Returns the Audio Context for this sketch. Useful for users\n * who would like to dig deeper into the Web Audio API\n * .
\n *\n *
Some browsers require users to startAudioContext\n * with a user gesture, such as touchStarted in the example below.
\n *\n * @method getAudioContext\n * @return {Object} AudioContext for this sketch\n * @example\n *
\n * function draw() {\n * background(255);\n * textAlign(CENTER);\n *\n * if (getAudioContext().state !== 'running') {\n * text('click to start audio', width/2, height/2);\n * } else {\n * text('audio is enabled', width/2, height/2);\n * }\n * }\n *\n * function touchStarted() {\n * if (getAudioContext().state !== 'running') {\n * getAudioContext().resume();\n * }\n * var synth = new p5.MonoSynth();\n * synth.play('A4', 0.5, 0, 0.2);\n * }\n *\n *
It is a good practice to give users control over starting audio playback.\n * This practice is enforced by Google Chrome's autoplay policy as of r70\n * (info), iOS Safari, and other browsers.\n *
\n *\n *
\n * userStartAudio() starts the Audio Context on a user gesture. It utilizes\n * the StartAudioContext library by\n * Yotam Mann (MIT Licence, 2016). Read more at https://github.com/tambien/StartAudioContext.\n *
\n *\n *
Starting the audio context on a user gesture can be as simple as userStartAudio().\n * Optional parameters let you decide on a specific element that will start the audio context,\n * and/or call a function once the audio context is started.
\n * @param {Element|Array} [element(s)] This argument can be an Element,\n * Selector String, NodeList, p5.Element,\n * jQuery Element, or an Array of any of those.\n * @param {Function} [callback] Callback to invoke when the AudioContext has started\n * @return {Promise} Returns a Promise which is resolved when\n * the AudioContext state is 'running'\n * @method userStartAudio\n * @for p5\n * @example\n *
\n * function setup() {\n * var myDiv = createDiv('click to start audio');\n * myDiv.position(0, 0);\n *\n * var mySynth = new p5.MonoSynth();\n *\n * // This won't play until the context has started\n * mySynth.play('A6');\n *\n * // Start the audio context on a click/touch event\n * userStartAudio().then(function() {\n * myDiv.remove();\n * });\n * }\n *
\n */\n p5.prototype.userStartAudio = function(elements, callback) {\n var elt = elements;\n if (elements instanceof p5.Element) {\n elt = elements.elt;\n } else if (elements instanceof Array && elements[0] instanceof p5.Element ) {\n elt = elements.map(function(e) { return e.elt});\n }\n return StartAudioContext(audiocontext, elt, callback);\n };\n\n return audiocontext;\n});\n","define([\"Tone/core/Tone\"], function (Tone) {\n\n\t\"use strict\";\n\n\t/**\n\t * @class Tone.Emitter gives classes which extend it\n\t * the ability to listen for and emit events. \n\t * Inspiration and reference from Jerome Etienne's [MicroEvent](https://github.com/jeromeetienne/microevent.js).\n\t * MIT (c) 2011 Jerome Etienne.\n\t * \n\t * @extends {Tone}\n\t */\n\tTone.Emitter = function(){\n\t\t/**\n\t\t * Contains all of the events.\n\t\t * @private\n\t\t * @type {Object}\n\t\t */\n\t\tthis._events = {};\n\t};\n\n\tTone.extend(Tone.Emitter);\n\n\t/**\n\t * Bind a callback to a specific event.\n\t * @param {String} event The name of the event to listen for.\n\t * @param {Function} callback The callback to invoke when the\n\t * event is emitted\n\t * @return {Tone.Emitter} this\n\t */\n\tTone.Emitter.prototype.on = function(event, callback){\n\t\t//split the event\n\t\tvar events = event.split(/\\W+/);\n\t\tfor (var i = 0; i < events.length; i++){\n\t\t\tvar eventName = events[i];\n\t\t\tif (!this._events.hasOwnProperty(eventName)){\n\t\t\t\tthis._events[eventName] = [];\n\t\t\t}\n\t\t\tthis._events[eventName].push(callback);\n\t\t}\n\t\treturn this;\n\t};\n\n\t/**\n\t * Remove the event listener.\n\t * @param {String} event The event to stop listening to.\n\t * @param {Function=} callback The callback which was bound to \n\t * the event with Tone.Emitter.on.\n\t * If no callback is given, all callbacks\n\t * events are removed.\n\t * @return {Tone.Emitter} this\n\t */\n\tTone.Emitter.prototype.off = function(event, callback){\n\t\tvar events = event.split(/\\W+/);\n\t\tfor (var ev = 0; ev < events.length; ev++){\n\t\t\tevent = events[ev];\n\t\t\tif (this._events.hasOwnProperty(event)){\n\t\t\t\tif (Tone.prototype.isUndef(callback)){\n\t\t\t\t\tthis._events[event] = [];\n\t\t\t\t} else {\n\t\t\t\t\tvar eventList = this._events[event];\n\t\t\t\t\tfor (var i = 0; i < eventList.length; i++){\n\t\t\t\t\t\tif (eventList[i] === callback){\n\t\t\t\t\t\t\teventList.splice(i, 1);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\treturn this;\n\t};\n\n\t/**\n\t * Invoke all of the callbacks bound to the event\n\t * with any arguments passed in. \n\t * @param {String} event The name of the event.\n\t * @param {*...} args The arguments to pass to the functions listening.\n\t * @return {Tone.Emitter} this\n\t */\n\tTone.Emitter.prototype.emit = function(event){\n\t\tif (this._events){\n\t\t\tvar args = Array.apply(null, arguments).slice(1);\n\t\t\tif (this._events.hasOwnProperty(event)){\n\t\t\t\tvar eventList = this._events[event];\n\t\t\t\tfor (var i = 0, len = eventList.length; i < len; i++){\n\t\t\t\t\teventList[i].apply(this, args);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\treturn this;\n\t};\n\n\t/**\n\t * Add Emitter functions (on/off/emit) to the object\n\t * @param {Object|Function} object The object or class to extend.\n\t */\n\tTone.Emitter.mixin = function(object){\n\t\tvar functions = [\"on\", \"off\", \"emit\"];\n\t\tobject._events = {};\n\t\tfor (var i = 0; i < functions.length; i++){\n\t\t\tvar func = functions[i];\n\t\t\tvar emitterFunc = Tone.Emitter.prototype[func];\n\t\t\tobject[func] = emitterFunc;\n\t\t}\n\t};\n\n\t/**\n\t * Clean up\n\t * @return {Tone.Emitter} this\n\t */\n\tTone.Emitter.prototype.dispose = function(){\n\t\tTone.prototype.dispose.call(this);\n\t\tthis._events = null;\n\t\treturn this;\n\t};\n\n\treturn Tone.Emitter;\n});","define([\"Tone/core/Tone\"], function(Tone){\n\n\t\"use strict\";\n\n\t/**\n\t * @class Base class for all Signals. Used Internally. \n\t *\n\t * @constructor\n\t * @extends {Tone}\n\t */\n\tTone.SignalBase = function(){};\n\n\tTone.extend(Tone.SignalBase);\n\n\t/**\n\t * When signals connect to other signals or AudioParams, \n\t * they take over the output value of that signal or AudioParam. \n\t * For all other nodes, the behavior is the same as a default connect. \n\t *\n\t * @override\n\t * @param {AudioParam|AudioNode|Tone.Signal|Tone} node \n\t * @param {number} [outputNumber=0] The output number to connect from.\n\t * @param {number} [inputNumber=0] The input number to connect to.\n\t * @returns {Tone.SignalBase} this\n\t */\n\tTone.SignalBase.prototype.connect = function(node, outputNumber, inputNumber){\n\t\t//zero it out so that the signal can have full control\n\t\tif ((Tone.Signal && Tone.Signal === node.constructor) || \n\t\t\t\t(Tone.Param && Tone.Param === node.constructor) || \n\t\t\t\t(Tone.TimelineSignal && Tone.TimelineSignal === node.constructor)){\n\t\t\t//cancel changes\n\t\t\tnode._param.cancelScheduledValues(0);\n\t\t\t//reset the value\n\t\t\tnode._param.value = 0;\n\t\t\t//mark the value as overridden\n\t\t\tnode.overridden = true;\n\t\t} else if (node instanceof AudioParam){\n\t\t\tnode.cancelScheduledValues(0);\n\t\t\tnode.value = 0;\n\t\t} \n\t\tTone.prototype.connect.call(this, node, outputNumber, inputNumber);\n\t\treturn this;\n\t};\n\n\treturn Tone.SignalBase;\n});","define([\"Tone/core/Tone\", \"Tone/type/TimeBase\"], function (Tone) {\n\n\t/**\n\t * @class Tone.Time is a primitive type for encoding Time values. \n\t * Eventually all time values are evaluated to seconds\n\t * using the `eval` method. Tone.Time can be constructed\n\t * with or without the `new` keyword. Tone.Time can be passed\n\t * into the parameter of any method which takes time as an argument. \n\t * @constructor\n\t * @extends {Tone.TimeBase}\n\t * @param {String|Number} val The time value.\n\t * @param {String=} units The units of the value.\n\t * @example\n\t * var t = Tone.Time(\"4n\");//encodes a quarter note\n\t * t.mult(4); // multiply that value by 4\n\t * t.toNotation(); //returns \"1m\"\n\t */\n\tTone.Time = function(val, units){\n\t\tif (this instanceof Tone.Time){\n\n\t\t\t/**\n\t\t\t * If the current clock time should\n\t\t\t * be added to the output\n\t\t\t * @type {Boolean}\n\t\t\t * @private\n\t\t\t */\n\t\t\tthis._plusNow = false;\n\t\t\t\n\t\t\tTone.TimeBase.call(this, val, units);\n\n\t\t} else {\n\t\t\treturn new Tone.Time(val, units);\n\t\t}\n\t};\n\n\tTone.extend(Tone.Time, Tone.TimeBase);\n\n\t//clone the expressions so that \n\t//we can add more without modifying the original\n\tTone.Time.prototype._unaryExpressions = Object.create(Tone.TimeBase.prototype._unaryExpressions);\n\n\t/*\n\t * Adds an additional unary expression\n\t * which quantizes values to the next subdivision\n\t * @type {Object}\n\t * @private\n\t */\n\tTone.Time.prototype._unaryExpressions.quantize = {\n\t\tregexp : /^@/,\n\t\tmethod : function(rh){\n\t\t\treturn Tone.Transport.nextSubdivision(rh());\n\t\t}\n\t};\n\n\t/*\n\t * Adds an additional unary expression\n\t * which adds the current clock time.\n\t * @type {Object}\n\t * @private\n\t */\n\tTone.Time.prototype._unaryExpressions.now = {\n\t\tregexp : /^\\+/,\n\t\tmethod : function(lh){\n\t\t\tthis._plusNow = true;\n\t\t\treturn lh();\n\t\t}\n\t};\n\n\t/**\n\t * Quantize the time by the given subdivision. Optionally add a\n\t * percentage which will move the time value towards the ideal\n\t * quantized value by that percentage. \n\t * @param {Number|Time} val The subdivision to quantize to\n\t * @param {NormalRange} [percent=1] Move the time value\n\t * towards the quantized value by\n\t * a percentage.\n\t * @return {Tone.Time} this\n\t * @example\n\t * Tone.Time(21).quantize(2) //returns 22\n\t * Tone.Time(0.6).quantize(\"4n\", 0.5) //returns 0.55\n\t */\n\tTone.Time.prototype.quantize = function(subdiv, percent){\n\t\tpercent = this.defaultArg(percent, 1);\n\t\tthis._expr = function(expr, subdivision, percent){\n\t\t\texpr = expr();\n\t\t\tsubdivision = subdivision.toSeconds();\n\t\t\tvar multiple = Math.round(expr / subdivision);\n\t\t\tvar ideal = multiple * subdivision;\n\t\t\tvar diff = ideal - expr;\n\t\t\treturn expr + diff * percent;\n\t\t}.bind(this, this._expr, new this.constructor(subdiv), percent);\n\t\treturn this;\n\t};\n\n\t/**\n\t * Adds the clock time to the time expression at the \n\t * moment of evaluation. \n\t * @return {Tone.Time} this\n\t */\n\tTone.Time.prototype.addNow = function(){\n\t\tthis._plusNow = true;\n\t\treturn this;\n\t};\n\n\t/**\n\t * @override\n\t * Override the default value return when no arguments are passed in.\n\t * The default value is 'now'\n\t * @private\n\t */\n\tTone.Time.prototype._defaultExpr = function(){\n\t\tthis._plusNow = true;\n\t\treturn this._noOp;\n\t};\n\n\t/**\n\t * Copies the value of time to this Time\n\t * @param {Tone.Time} time\n\t * @return {Time}\n\t */\n\tTone.Time.prototype.copy = function(time){\n\t\tTone.TimeBase.prototype.copy.call(this, time);\n\t\tthis._plusNow = time._plusNow;\n\t\treturn this;\n\t};\n\n\t//CONVERSIONS//////////////////////////////////////////////////////////////\n\n\t/**\n\t * Convert a Time to Notation. Values will be thresholded to the nearest 128th note. \n\t * @return {Notation} \n\t * @example\n\t * //if the Transport is at 120bpm:\n\t * Tone.Time(2).toNotation();//returns \"1m\"\n\t */\n\tTone.Time.prototype.toNotation = function(){\n\t\tvar time = this.toSeconds();\n\t\tvar testNotations = [\"1m\", \"2n\", \"4n\", \"8n\", \"16n\", \"32n\", \"64n\", \"128n\"];\n\t\tvar retNotation = this._toNotationHelper(time, testNotations);\n\t\t//try the same thing but with tripelets\n\t\tvar testTripletNotations = [\"1m\", \"2n\", \"2t\", \"4n\", \"4t\", \"8n\", \"8t\", \"16n\", \"16t\", \"32n\", \"32t\", \"64n\", \"64t\", \"128n\"];\n\t\tvar retTripletNotation = this._toNotationHelper(time, testTripletNotations);\n\t\t//choose the simpler expression of the two\n\t\tif (retTripletNotation.split(\"+\").length < retNotation.split(\"+\").length){\n\t\t\treturn retTripletNotation;\n\t\t} else {\n\t\t\treturn retNotation;\n\t\t}\n\t};\n\n\t/**\n\t * Helper method for Tone.toNotation\n\t * @param {Number} units \n\t * @param {Array} testNotations\n\t * @return {String}\n\t * @private\n\t */\n\tTone.Time.prototype._toNotationHelper = function(units, testNotations){\n\t\t//the threshold is the last value in the array\n\t\tvar threshold = this._notationToUnits(testNotations[testNotations.length - 1]);\n\t\tvar retNotation = \"\";\n\t\tfor (var i = 0; i < testNotations.length; i++){\n\t\t\tvar notationTime = this._notationToUnits(testNotations[i]);\n\t\t\t//account for floating point errors (i.e. round up if the value is 0.999999)\n\t\t\tvar multiple = units / notationTime;\n\t\t\tvar floatingPointError = 0.000001;\n\t\t\tif (1 - multiple % 1 < floatingPointError){\n\t\t\t\tmultiple += floatingPointError;\n\t\t\t}\n\t\t\tmultiple = Math.floor(multiple);\n\t\t\tif (multiple > 0){\n\t\t\t\tif (multiple === 1){\n\t\t\t\t\tretNotation += testNotations[i];\n\t\t\t\t} else {\n\t\t\t\t\tretNotation += multiple.toString() + \"*\" + testNotations[i];\n\t\t\t\t}\n\t\t\t\tunits -= multiple * notationTime;\n\t\t\t\tif (units < threshold){\n\t\t\t\t\tbreak;\n\t\t\t\t} else {\n\t\t\t\t\tretNotation += \" + \";\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tif (retNotation === \"\"){\n\t\t\tretNotation = \"0\";\n\t\t}\n\t\treturn retNotation;\n\t};\n\n\t/**\n\t * Convert a notation value to the current units\n\t * @param {Notation} notation \n\t * @return {Number} \n\t * @private\n\t */\n\tTone.Time.prototype._notationToUnits = function(notation){\n\t\tvar primaryExprs = this._primaryExpressions;\n\t\tvar notationExprs = [primaryExprs.n, primaryExprs.t, primaryExprs.m];\n\t\tfor (var i = 0; i < notationExprs.length; i++){\n\t\t\tvar expr = notationExprs[i];\n\t\t\tvar match = notation.match(expr.regexp);\n\t\t\tif (match){\n\t\t\t\treturn expr.method.call(this, match[1]);\n\t\t\t}\n\t\t}\n\t};\n\n\t/**\n\t * Return the time encoded as Bars:Beats:Sixteenths.\n\t * @return {BarsBeatsSixteenths}\n\t */\n\tTone.Time.prototype.toBarsBeatsSixteenths = function(){\n\t\tvar quarterTime = this._beatsToUnits(1);\n\t\tvar quarters = this.toSeconds() / quarterTime;\n\t\tvar measures = Math.floor(quarters / this._timeSignature());\n\t\tvar sixteenths = (quarters % 1) * 4;\n\t\tquarters = Math.floor(quarters) % this._timeSignature();\n\t\tsixteenths = sixteenths.toString();\n\t\tif (sixteenths.length > 3){\n\t\t\tsixteenths = parseFloat(sixteenths).toFixed(3);\n\t\t}\n\t\tvar progress = [measures, quarters, sixteenths];\n\t\treturn progress.join(\":\");\n\t};\n\n\t/**\n\t * Return the time in ticks.\n\t * @return {Ticks}\n\t */\n\tTone.Time.prototype.toTicks = function(){\n\t\tvar quarterTime = this._beatsToUnits(1);\n\t\tvar quarters = this.valueOf() / quarterTime;\n\t\treturn Math.floor(quarters * Tone.Transport.PPQ);\n\t};\n\n\t/**\n\t * Return the time in samples\n\t * @return {Samples} \n\t */\n\tTone.Time.prototype.toSamples = function(){\n\t\treturn this.toSeconds() * this.context.sampleRate;\n\t};\n\n\t/**\n\t * Return the time as a frequency value\n\t * @return {Frequency} \n\t * @example\n\t * Tone.Time(2).toFrequency(); //0.5\n\t */\n\tTone.Time.prototype.toFrequency = function(){\n\t\treturn 1/this.toSeconds();\n\t};\n\n\t/**\n\t * Return the time in seconds.\n\t * @return {Seconds} \n\t */\n\tTone.Time.prototype.toSeconds = function(){\n\t\treturn this.valueOf();\n\t};\n\n\t/**\n\t * Return the time in milliseconds.\n\t * @return {Milliseconds} \n\t */\n\tTone.Time.prototype.toMilliseconds = function(){\n\t\treturn this.toSeconds() * 1000;\n\t};\n\n\t/**\n\t * Return the time in seconds.\n\t * @return {Seconds} \n\t */\n\tTone.Time.prototype.valueOf = function(){\n\t\tvar val = this._expr();\n\t\treturn val + (this._plusNow?this.now():0);\n\t};\n\n\treturn Tone.Time;\n});","define([\"Tone/core/Tone\"], function (Tone) {\n\n\t/**\n\t * @class Tone.TimeBase is a flexible encoding of time\n\t * which can be evaluated to and from a string.\n\t * Parsing code modified from https://code.google.com/p/tapdigit/\n\t * Copyright 2011 2012 Ariya Hidayat, New BSD License\n\t * @extends {Tone}\n\t * @param {Time} val The time value as a number or string\n\t * @param {String=} units Unit values\n\t * @example\n\t * Tone.TimeBase(4, \"n\")\n\t * Tone.TimeBase(2, \"t\")\n\t * Tone.TimeBase(\"2t\").add(\"1m\")\n\t * Tone.TimeBase(\"2t + 1m\");\n\t */\n\tTone.TimeBase = function(val, units){\n\n\t\t//allows it to be constructed with or without 'new'\n\t\tif (this instanceof Tone.TimeBase) {\n\n\t\t\t/**\n\t\t\t * Any expressions parsed from the Time\n\t\t\t * @type {Array}\n\t\t\t * @private\n\t\t\t */\n\t\t\tthis._expr = this._noOp;\n\n\t\t\tif (val instanceof Tone.TimeBase){\n\t\t\t\tthis.copy(val);\n\t\t\t} else if (!this.isUndef(units) || this.isNumber(val)){\n\t\t\t\t//default units\n\t\t\t\tunits = this.defaultArg(units, this._defaultUnits);\n\t\t\t\tvar method = this._primaryExpressions[units].method;\n\t\t\t\tthis._expr = method.bind(this, val);\n\t\t\t} else if (this.isString(val)){\n\t\t\t\tthis.set(val);\n\t\t\t} else if (this.isUndef(val)){\n\t\t\t\t//default expression\n\t\t\t\tthis._expr = this._defaultExpr();\n\t\t\t}\n\t\t} else {\n\n\t\t\treturn new Tone.TimeBase(val, units);\n\t\t}\n\t};\n\n\tTone.extend(Tone.TimeBase);\n\n\t/**\n\t * Repalce the current time value with the value\n\t * given by the expression string.\n\t * @param {String} exprString\n\t * @return {Tone.TimeBase} this\n\t */\n\tTone.TimeBase.prototype.set = function(exprString){\n\t\tthis._expr = this._parseExprString(exprString);\n\t\treturn this;\n\t};\n\n\t/**\n\t * Return a clone of the TimeBase object.\n\t * @return {Tone.TimeBase} The new cloned Tone.TimeBase\n\t */\n\tTone.TimeBase.prototype.clone = function(){\n\t\tvar instance = new this.constructor();\n\t\tinstance.copy(this);\n\t\treturn instance;\n\t};\n\n\t/**\n\t * Copies the value of time to this Time\n\t * @param {Tone.TimeBase} time\n\t * @return {TimeBase}\n\t */\n\tTone.TimeBase.prototype.copy = function(time){\n\t\tvar val = time._expr();\n\t\treturn this.set(val);\n\t};\n\n\t///////////////////////////////////////////////////////////////////////////\n\t//\tABSTRACT SYNTAX TREE PARSER\n\t///////////////////////////////////////////////////////////////////////////\n\n\t/**\n\t * All the primary expressions.\n\t * @private\n\t * @type {Object}\n\t */\n\tTone.TimeBase.prototype._primaryExpressions = {\n\t\t\"n\" : {\n\t\t\tregexp : /^(\\d+)n/i,\n\t\t\tmethod : function(value){\n\t\t\t\tvalue = parseInt(value);\n\t\t\t\tif (value === 1){\n\t\t\t\t\treturn this._beatsToUnits(this._timeSignature());\n\t\t\t\t} else {\n\t\t\t\t\treturn this._beatsToUnits(4 / value);\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\t\t\"t\" : {\n\t\t\tregexp : /^(\\d+)t/i,\n\t\t\tmethod : function(value){\n\t\t\t\tvalue = parseInt(value);\n\t\t\t\treturn this._beatsToUnits(8 / (parseInt(value) * 3));\n\t\t\t}\n\t\t},\n\t\t\"m\" : {\n\t\t\tregexp : /^(\\d+)m/i,\n\t\t\tmethod : function(value){\n\t\t\t\treturn this._beatsToUnits(parseInt(value) * this._timeSignature());\n\t\t\t}\n\t\t},\n\t\t\"i\" : {\n\t\t\tregexp : /^(\\d+)i/i,\n\t\t\tmethod : function(value){\n\t\t\t\treturn this._ticksToUnits(parseInt(value));\n\t\t\t}\n\t\t},\n\t\t\"hz\" : {\n\t\t\tregexp : /^(\\d+(?:\\.\\d+)?)hz/i,\n\t\t\tmethod : function(value){\n\t\t\t\treturn this._frequencyToUnits(parseFloat(value));\n\t\t\t}\n\t\t},\n\t\t\"tr\" : {\n\t\t\tregexp : /^(\\d+(?:\\.\\d+)?):(\\d+(?:\\.\\d+)?):?(\\d+(?:\\.\\d+)?)?/,\n\t\t\tmethod : function(m, q, s){\n\t\t\t\tvar total = 0;\n\t\t\t\tif (m && m !== \"0\"){\n\t\t\t\t\ttotal += this._beatsToUnits(this._timeSignature() * parseFloat(m));\n\t\t\t\t}\n\t\t\t\tif (q && q !== \"0\"){\n\t\t\t\t\ttotal += this._beatsToUnits(parseFloat(q));\n\t\t\t\t}\n\t\t\t\tif (s && s !== \"0\"){\n\t\t\t\t\ttotal += this._beatsToUnits(parseFloat(s) / 4);\n\t\t\t\t}\n\t\t\t\treturn total;\n\t\t\t}\n\t\t},\n\t\t\"s\" : {\n\t\t\tregexp : /^(\\d+(?:\\.\\d+)?s)/,\n\t\t\tmethod : function(value){\n\t\t\t\treturn this._secondsToUnits(parseFloat(value));\n\t\t\t}\n\t\t},\n\t\t\"samples\" : {\n\t\t\tregexp : /^(\\d+)samples/,\n\t\t\tmethod : function(value){\n\t\t\t\treturn parseInt(value) / this.context.sampleRate;\n\t\t\t}\n\t\t},\n\t\t\"default\" : {\n\t\t\tregexp : /^(\\d+(?:\\.\\d+)?)/,\n\t\t\tmethod : function(value){\n\t\t\t\treturn this._primaryExpressions[this._defaultUnits].method.call(this, value);\n\t\t\t}\n\t\t}\n\t};\n\n\t/**\n\t * All the binary expressions that TimeBase can accept.\n\t * @private\n\t * @type {Object}\n\t */\n\tTone.TimeBase.prototype._binaryExpressions = {\n\t\t\"+\" : {\n\t\t\tregexp : /^\\+/,\n\t\t\tprecedence : 2,\n\t\t\tmethod : function(lh, rh){\n\t\t\t\treturn lh() + rh();\n\t\t\t}\n\t\t},\n\t\t\"-\" : {\n\t\t\tregexp : /^\\-/,\n\t\t\tprecedence : 2,\n\t\t\tmethod : function(lh, rh){\n\t\t\t\treturn lh() - rh();\n\t\t\t}\n\t\t},\n\t\t\"*\" : {\n\t\t\tregexp : /^\\*/,\n\t\t\tprecedence : 1,\n\t\t\tmethod : function(lh, rh){\n\t\t\t\treturn lh() * rh();\n\t\t\t}\n\t\t},\n\t\t\"/\" : {\n\t\t\tregexp : /^\\//,\n\t\t\tprecedence : 1,\n\t\t\tmethod : function(lh, rh){\n\t\t\t\treturn lh() / rh();\n\t\t\t}\n\t\t}\n\t};\n\n\t/**\n\t * All the unary expressions.\n\t * @private\n\t * @type {Object}\n\t */\n\tTone.TimeBase.prototype._unaryExpressions = {\n\t\t\"neg\" : {\n\t\t\tregexp : /^\\-/,\n\t\t\tmethod : function(lh){\n\t\t\t\treturn -lh();\n\t\t\t}\n\t\t}\n\t};\n\n\t/**\n\t * Syntactic glue which holds expressions together\n\t * @private\n\t * @type {Object}\n\t */\n\tTone.TimeBase.prototype._syntaxGlue = {\n\t\t\"(\" : {\n\t\t\tregexp : /^\\(/\n\t\t},\n\t\t\")\" : {\n\t\t\tregexp : /^\\)/\n\t\t}\n\t};\n\n\t/**\n\t * tokenize the expression based on the Expressions object\n\t * @param {string} expr \n\t * @return {Object} returns two methods on the tokenized list, next and peek\n\t * @private\n\t */\n\tTone.TimeBase.prototype._tokenize = function(expr){\n\t\tvar position = -1;\n\t\tvar tokens = [];\n\n\t\twhile(expr.length > 0){\n\t\t\texpr = expr.trim();\n\t\t\tvar token = getNextToken(expr, this);\n\t\t\ttokens.push(token);\n\t\t\texpr = expr.substr(token.value.length);\n\t\t}\n\n\t\tfunction getNextToken(expr, context){\n\t\t\tvar expressions = [\"_binaryExpressions\", \"_unaryExpressions\", \"_primaryExpressions\", \"_syntaxGlue\"];\n\t\t\tfor (var i = 0; i < expressions.length; i++){\n\t\t\t\tvar group = context[expressions[i]];\n\t\t\t\tfor (var opName in group){\n\t\t\t\t\tvar op = group[opName];\n\t\t\t\t\tvar reg = op.regexp;\n\t\t\t\t\tvar match = expr.match(reg);\n\t\t\t\t\tif (match !== null){\n\t\t\t\t\t\treturn {\n\t\t\t\t\t\t\tmethod : op.method,\n\t\t\t\t\t\t\tprecedence : op.precedence,\n\t\t\t\t\t\t\tregexp : op.regexp,\n\t\t\t\t\t\t\tvalue : match[0],\n\t\t\t\t\t\t};\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\tthrow new SyntaxError(\"Tone.TimeBase: Unexpected token \"+expr);\n\t\t}\n\n\t\treturn {\n\t\t\tnext : function(){\n\t\t\t\treturn tokens[++position];\n\t\t\t},\n\t\t\tpeek : function(){\n\t\t\t\treturn tokens[position + 1];\n\t\t\t}\n\t\t};\n\t};\n\n\t/**\n\t * Given a token, find the value within the groupName\n\t * @param {Object} token\n\t * @param {String} groupName\n\t * @param {Number} precedence\n\t * @private\n\t */\n\tTone.TimeBase.prototype._matchGroup = function(token, group, prec) {\n\t\tvar ret = false;\n\t\tif (!this.isUndef(token)){\n\t\t\tfor (var opName in group){\n\t\t\t\tvar op = group[opName];\n\t\t\t\tif (op.regexp.test(token.value)){\n\t\t\t\t\tif (!this.isUndef(prec)){\n\t\t\t\t\t\tif(op.precedence === prec){\t\n\t\t\t\t\t\t\treturn op;\n\t\t\t\t\t\t}\n\t\t\t\t\t} else {\n\t\t\t\t\t\treturn op;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\treturn ret;\n\t};\n\n\t/**\n\t * Match a binary expression given the token and the precedence\n\t * @param {Lexer} lexer\n\t * @param {Number} precedence\n\t * @private\n\t */\n\tTone.TimeBase.prototype._parseBinary = function(lexer, precedence){\n\t\tif (this.isUndef(precedence)){\n\t\t\tprecedence = 2;\n\t\t}\n\t\tvar expr;\n\t\tif (precedence < 0){\n\t\t\texpr = this._parseUnary(lexer);\n\t\t} else {\n\t\t\texpr = this._parseBinary(lexer, precedence - 1);\n\t\t}\n\t\tvar token = lexer.peek();\n\t\twhile (token && this._matchGroup(token, this._binaryExpressions, precedence)){\n\t\t\ttoken = lexer.next();\n\t\t\texpr = token.method.bind(this, expr, this._parseBinary(lexer, precedence - 1));\n\t\t\ttoken = lexer.peek();\n\t\t}\n\t\treturn expr;\n\t};\n\n\t/**\n\t * Match a unary expression.\n\t * @param {Lexer} lexer\n\t * @private\n\t */\n\tTone.TimeBase.prototype._parseUnary = function(lexer){\n\t\tvar token, expr;\n\t\ttoken = lexer.peek();\n\t\tvar op = this._matchGroup(token, this._unaryExpressions);\n\t\tif (op) {\n\t\t\ttoken = lexer.next();\n\t\t\texpr = this._parseUnary(lexer);\n\t\t\treturn op.method.bind(this, expr);\n\t\t}\n\t\treturn this._parsePrimary(lexer);\n\t};\n\n\t/**\n\t * Match a primary expression (a value).\n\t * @param {Lexer} lexer\n\t * @private\n\t */\n\tTone.TimeBase.prototype._parsePrimary = function(lexer){\n\t\tvar token, expr;\n\t\ttoken = lexer.peek();\n\t\tif (this.isUndef(token)) {\n\t\t\tthrow new SyntaxError(\"Tone.TimeBase: Unexpected end of expression\");\n\t\t}\n\t\tif (this._matchGroup(token, this._primaryExpressions)) {\n\t\t\ttoken = lexer.next();\n\t\t\tvar matching = token.value.match(token.regexp);\n\t\t\treturn token.method.bind(this, matching[1], matching[2], matching[3]);\n\t\t}\n\t\tif (token && token.value === \"(\"){\n\t\t\tlexer.next();\n\t\t\texpr = this._parseBinary(lexer);\n\t\t\ttoken = lexer.next();\n\t\t\tif (!(token && token.value === \")\")) {\n\t\t\t\tthrow new SyntaxError(\"Expected )\");\n\t\t\t}\n\t\t\treturn expr;\n\t\t}\n\t\tthrow new SyntaxError(\"Tone.TimeBase: Cannot process token \" + token.value);\n\t};\n\n\t/**\n\t * Recursively parse the string expression into a syntax tree.\n\t * @param {string} expr \n\t * @return {Function} the bound method to be evaluated later\n\t * @private\n\t */\n\tTone.TimeBase.prototype._parseExprString = function(exprString){\n\t\tif (!this.isString(exprString)){\n\t\t\texprString = exprString.toString();\n\t\t}\n\t\tvar lexer = this._tokenize(exprString);\n\t\tvar tree = this._parseBinary(lexer);\n\t\treturn tree;\n\t};\n\n\t///////////////////////////////////////////////////////////////////////////\n\t//\tDEFAULTS\n\t///////////////////////////////////////////////////////////////////////////\n\n\t/**\n\t * The initial expression value\n\t * @return {Number} The initial value 0\n\t * @private\n\t */\n\tTone.TimeBase.prototype._noOp = function(){\n\t\treturn 0;\n\t};\n\n\t/**\n\t * The default expression value if no arguments are given\n\t * @private\n\t */\n\tTone.TimeBase.prototype._defaultExpr = function(){\n\t\treturn this._noOp;\n\t};\n\n\t/**\n\t * The default units if none are given.\n\t * @private\n\t */\n\tTone.TimeBase.prototype._defaultUnits = \"s\";\n\n\t///////////////////////////////////////////////////////////////////////////\n\t//\tUNIT CONVERSIONS\n\t///////////////////////////////////////////////////////////////////////////\n\n\t/**\n\t * Returns the value of a frequency in the current units\n\t * @param {Frequency} freq\n\t * @return {Number}\n\t * @private\n\t */\n\tTone.TimeBase.prototype._frequencyToUnits = function(freq){\n\t\treturn 1/freq;\n\t};\n\n\t/**\n\t * Return the value of the beats in the current units\n\t * @param {Number} beats\n\t * @return {Number}\n\t * @private\n\t */\n\tTone.TimeBase.prototype._beatsToUnits = function(beats){\n\t\treturn (60 / Tone.Transport.bpm.value) * beats;\n\t};\n\n\t/**\n\t * Returns the value of a second in the current units\n\t * @param {Seconds} seconds\n\t * @return {Number}\n\t * @private\n\t */\n\tTone.TimeBase.prototype._secondsToUnits = function(seconds){\n\t\treturn seconds;\n\t};\n\n\t/**\n\t * Returns the value of a tick in the current time units\n\t * @param {Ticks} ticks\n\t * @return {Number}\n\t * @private\n\t */\n\tTone.TimeBase.prototype._ticksToUnits = function(ticks){\n\t\treturn ticks * (this._beatsToUnits(1) / Tone.Transport.PPQ);\n\t};\n\n\t/**\n\t * Return the time signature.\n\t * @return {Number}\n\t * @private\n\t */\n\tTone.TimeBase.prototype._timeSignature = function(){\n\t\treturn Tone.Transport.timeSignature;\n\t};\n\n\t///////////////////////////////////////////////////////////////////////////\n\t//\tEXPRESSIONS\n\t///////////////////////////////////////////////////////////////////////////\n\n\t/**\n\t * Push an expression onto the expression list\n\t * @param {Time} val\n\t * @param {String} type\n\t * @param {String} units\n\t * @return {Tone.TimeBase} \n\t * @private\n\t */\n\tTone.TimeBase.prototype._pushExpr = function(val, name, units){\n\t\t//create the expression\n\t\tif (!(val instanceof Tone.TimeBase)){\n\t\t\tval = new this.constructor(val, units);\n\t\t}\n\t\tthis._expr = this._binaryExpressions[name].method.bind(this, this._expr, val._expr);\n\t\treturn this;\n\t};\n\n\t/**\n\t * Add to the current value.\n\t * @param {Time} val The value to add\n\t * @param {String=} units Optional units to use with the value.\n\t * @return {Tone.TimeBase} this\n\t * @example\n\t * Tone.TimeBase(\"2m\").add(\"1m\"); //\"3m\"\n\t */\n\tTone.TimeBase.prototype.add = function(val, units){\n\t\treturn this._pushExpr(val, \"+\", units);\n\t};\n\n\t/**\n\t * Subtract the value from the current time.\n\t * @param {Time} val The value to subtract\n\t * @param {String=} units Optional units to use with the value.\n\t * @return {Tone.TimeBase} this\n\t * @example\n\t * Tone.TimeBase(\"2m\").sub(\"1m\"); //\"1m\"\n\t */\n\tTone.TimeBase.prototype.sub = function(val, units){\n\t\treturn this._pushExpr(val, \"-\", units);\n\t};\n\n\t/**\n\t * Multiply the current value by the given time.\n\t * @param {Time} val The value to multiply\n\t * @param {String=} units Optional units to use with the value.\n\t * @return {Tone.TimeBase} this\n\t * @example\n\t * Tone.TimeBase(\"2m\").mult(\"2\"); //\"4m\"\n\t */\n\tTone.TimeBase.prototype.mult = function(val, units){\n\t\treturn this._pushExpr(val, \"*\", units);\n\t};\n\n\t/**\n\t * Divide the current value by the given time.\n\t * @param {Time} val The value to divide by\n\t * @param {String=} units Optional units to use with the value.\n\t * @return {Tone.TimeBase} this\n\t * @example\n\t * Tone.TimeBase(\"2m\").div(2); //\"1m\"\n\t */\n\tTone.TimeBase.prototype.div = function(val, units){\n\t\treturn this._pushExpr(val, \"/\", units);\n\t};\n\n\t/**\n\t * Evaluate the time value. Returns the time\n\t * in seconds.\n\t * @return {Seconds} \n\t */\n\tTone.TimeBase.prototype.valueOf = function(){\n\t\treturn this._expr();\n\t};\n\n\t/**\n\t * Clean up\n\t * @return {Tone.TimeBase} this\n\t */\n\tTone.TimeBase.prototype.dispose = function(){\n\t\tthis._expr = null;\n\t};\n\n\treturn Tone.TimeBase;\n});","define([\"Tone/core/Tone\", \"Tone/type/Type\"], function(Tone){\n\n\t\"use strict\";\n\n\t/**\n\t * @class Tone.Param wraps the native Web Audio's AudioParam to provide\n\t * additional unit conversion functionality. It also\n\t * serves as a base-class for classes which have a single,\n\t * automatable parameter. \n\t * @extends {Tone}\n\t * @param {AudioParam} param The parameter to wrap.\n\t * @param {Tone.Type} units The units of the audio param.\n\t * @param {Boolean} convert If the param should be converted.\n\t */\n\tTone.Param = function(){\n\n\t\tvar options = this.optionsObject(arguments, [\"param\", \"units\", \"convert\"], Tone.Param.defaults);\n\n\t\t/**\n\t\t * The native parameter to control\n\t\t * @type {AudioParam}\n\t\t * @private\n\t\t */\n\t\tthis._param = this.input = options.param;\n\n\t\t/**\n\t\t * The units of the parameter\n\t\t * @type {Tone.Type}\n\t\t */\n\t\tthis.units = options.units;\n\n\t\t/**\n\t\t * If the value should be converted or not\n\t\t * @type {Boolean}\n\t\t */\n\t\tthis.convert = options.convert;\n\n\t\t/**\n\t\t * True if the signal value is being overridden by \n\t\t * a connected signal.\n\t\t * @readOnly\n\t\t * @type {boolean}\n\t\t * @private\n\t\t */\n\t\tthis.overridden = false;\n\n\t\t/**\n\t\t * If there is an LFO, this is where it is held.\n\t\t * @type {Tone.LFO}\n\t\t * @private\n\t\t */\n\t\tthis._lfo = null;\n\n\t\tif (this.isObject(options.lfo)){\n\t\t\tthis.value = options.lfo;\n\t\t} else if (!this.isUndef(options.value)){\n\t\t\tthis.value = options.value;\n\t\t}\n\t};\n\n\tTone.extend(Tone.Param);\n\t\n\t/**\n\t * Defaults\n\t * @type {Object}\n\t * @const\n\t */\n\tTone.Param.defaults = {\n\t\t\"units\" : Tone.Type.Default,\n\t\t\"convert\" : true,\n\t\t\"param\" : undefined\n\t};\n\n\t/**\n\t * The current value of the parameter. \n\t * @memberOf Tone.Param#\n\t * @type {Number}\n\t * @name value\n\t */\n\tObject.defineProperty(Tone.Param.prototype, \"value\", {\n\t\tget : function(){\n\t\t\treturn this._toUnits(this._param.value);\n\t\t},\n\t\tset : function(value){\n\t\t\tif (this.isObject(value)){\n\t\t\t\t//throw an error if the LFO needs to be included\n\t\t\t\tif (this.isUndef(Tone.LFO)){\n\t\t\t\t\tthrow new Error(\"Include 'Tone.LFO' to use an LFO as a Param value.\");\n\t\t\t\t}\n\t\t\t\t//remove the old one\n\t\t\t\tif (this._lfo){\n\t\t\t\t\tthis._lfo.dispose();\n\t\t\t\t}\n\t\t\t\tthis._lfo = new Tone.LFO(value).start();\n\t\t\t\tthis._lfo.connect(this.input);\n\t\t\t} else {\n\t\t\t\tvar convertedVal = this._fromUnits(value);\n\t\t\t\tthis._param.cancelScheduledValues(0);\n\t\t\t\tthis._param.value = convertedVal;\n\t\t\t}\n\t\t}\n\t});\n\n\t/**\n\t * Convert the given value from the type specified by Tone.Param.units\n\t * into the destination value (such as Gain or Frequency).\n\t * @private\n\t * @param {*} val the value to convert\n\t * @return {number} the number which the value should be set to\n\t */\n\tTone.Param.prototype._fromUnits = function(val){\n\t\tif (this.convert || this.isUndef(this.convert)){\n\t\t\tswitch(this.units){\n\t\t\t\tcase Tone.Type.Time: \n\t\t\t\t\treturn this.toSeconds(val);\n\t\t\t\tcase Tone.Type.Frequency: \n\t\t\t\t\treturn this.toFrequency(val);\n\t\t\t\tcase Tone.Type.Decibels: \n\t\t\t\t\treturn this.dbToGain(val);\n\t\t\t\tcase Tone.Type.NormalRange: \n\t\t\t\t\treturn Math.min(Math.max(val, 0), 1);\n\t\t\t\tcase Tone.Type.AudioRange: \n\t\t\t\t\treturn Math.min(Math.max(val, -1), 1);\n\t\t\t\tcase Tone.Type.Positive: \n\t\t\t\t\treturn Math.max(val, 0);\n\t\t\t\tdefault:\n\t\t\t\t\treturn val;\n\t\t\t}\n\t\t} else {\n\t\t\treturn val;\n\t\t}\n\t};\n\n\t/**\n\t * Convert the parameters value into the units specified by Tone.Param.units.\n\t * @private\n\t * @param {number} val the value to convert\n\t * @return {number}\n\t */\n\tTone.Param.prototype._toUnits = function(val){\n\t\tif (this.convert || this.isUndef(this.convert)){\n\t\t\tswitch(this.units){\n\t\t\t\tcase Tone.Type.Decibels: \n\t\t\t\t\treturn this.gainToDb(val);\n\t\t\t\tdefault:\n\t\t\t\t\treturn val;\n\t\t\t}\n\t\t} else {\n\t\t\treturn val;\n\t\t}\n\t};\n\n\t/**\n\t * the minimum output value\n\t * @type {Number}\n\t * @private\n\t */\n\tTone.Param.prototype._minOutput = 0.00001;\n\n\t/**\n\t * Schedules a parameter value change at the given time.\n\t * @param {*}\tvalue The value to set the signal.\n\t * @param {Time} time The time when the change should occur.\n\t * @returns {Tone.Param} this\n\t * @example\n\t * //set the frequency to \"G4\" in exactly 1 second from now. \n\t * freq.setValueAtTime(\"G4\", \"+1\");\n\t */\n\tTone.Param.prototype.setValueAtTime = function(value, time){\n\t\tvalue = this._fromUnits(value);\n\t\ttime = this.toSeconds(time);\n\t\tif (time <= this.now() + this.blockTime){\n\t\t\tthis._param.value = value;\n\t\t} else {\n\t\t\tthis._param.setValueAtTime(value, time);\n\t\t}\n\t\treturn this;\n\t};\n\n\t/**\n\t * Creates a schedule point with the current value at the current time.\n\t * This is useful for creating an automation anchor point in order to \n\t * schedule changes from the current value. \n\t *\n\t * @param {number=} now (Optionally) pass the now value in. \n\t * @returns {Tone.Param} this\n\t */\n\tTone.Param.prototype.setRampPoint = function(now){\n\t\tnow = this.defaultArg(now, this.now());\n\t\tvar currentVal = this._param.value;\n\t\t// exponentialRampToValueAt cannot ever ramp from or to 0\n\t\t// More info: https://bugzilla.mozilla.org/show_bug.cgi?id=1125600#c2\n\t\tif (currentVal === 0){\n\t\t\tcurrentVal = this._minOutput;\n\t\t}\n\t\tthis._param.setValueAtTime(currentVal, now);\n\t\treturn this;\n\t};\n\n\t/**\n\t * Schedules a linear continuous change in parameter value from the \n\t * previous scheduled parameter value to the given value.\n\t * \n\t * @param {number} value \n\t * @param {Time} endTime \n\t * @returns {Tone.Param} this\n\t */\n\tTone.Param.prototype.linearRampToValueAtTime = function(value, endTime){\n\t\tvalue = this._fromUnits(value);\n\t\tthis._param.linearRampToValueAtTime(value, this.toSeconds(endTime));\n\t\treturn this;\n\t};\n\n\t/**\n\t * Schedules an exponential continuous change in parameter value from \n\t * the previous scheduled parameter value to the given value.\n\t * \n\t * @param {number} value \n\t * @param {Time} endTime \n\t * @returns {Tone.Param} this\n\t */\n\tTone.Param.prototype.exponentialRampToValueAtTime = function(value, endTime){\n\t\tvalue = this._fromUnits(value);\n\t\tvalue = Math.max(this._minOutput, value);\n\t\tthis._param.exponentialRampToValueAtTime(value, this.toSeconds(endTime));\n\t\treturn this;\n\t};\n\n\t/**\n\t * Schedules an exponential continuous change in parameter value from \n\t * the current time and current value to the given value over the \n\t * duration of the rampTime.\n\t * \n\t * @param {number} value The value to ramp to.\n\t * @param {Time} rampTime the time that it takes the \n\t * value to ramp from it's current value\n\t * @param {Time}\t[startTime=now] \tWhen the ramp should start. \n\t * @returns {Tone.Param} this\n\t * @example\n\t * //exponentially ramp to the value 2 over 4 seconds. \n\t * signal.exponentialRampToValue(2, 4);\n\t */\n\tTone.Param.prototype.exponentialRampToValue = function(value, rampTime, startTime){\n\t\tstartTime = this.toSeconds(startTime);\n\t\tthis.setRampPoint(startTime);\n\t\tthis.exponentialRampToValueAtTime(value, startTime + this.toSeconds(rampTime));\n\t\treturn this;\n\t};\n\n\t/**\n\t * Schedules an linear continuous change in parameter value from \n\t * the current time and current value to the given value over the \n\t * duration of the rampTime.\n\t * \n\t * @param {number} value The value to ramp to.\n\t * @param {Time} rampTime the time that it takes the \n\t * value to ramp from it's current value\n\t * @param {Time}\t[startTime=now] \tWhen the ramp should start. \n\t * @returns {Tone.Param} this\n\t * @example\n\t * //linearly ramp to the value 4 over 3 seconds. \n\t * signal.linearRampToValue(4, 3);\n\t */\n\tTone.Param.prototype.linearRampToValue = function(value, rampTime, startTime){\n\t\tstartTime = this.toSeconds(startTime);\n\t\tthis.setRampPoint(startTime);\n\t\tthis.linearRampToValueAtTime(value, startTime + this.toSeconds(rampTime));\n\t\treturn this;\n\t};\n\n\t/**\n\t * Start exponentially approaching the target value at the given time with\n\t * a rate having the given time constant.\n\t * @param {number} value \n\t * @param {Time} startTime \n\t * @param {number} timeConstant \n\t * @returns {Tone.Param} this \n\t */\n\tTone.Param.prototype.setTargetAtTime = function(value, startTime, timeConstant){\n\t\tvalue = this._fromUnits(value);\n\t\t// The value will never be able to approach without timeConstant > 0.\n\t\t// http://www.w3.org/TR/webaudio/#dfn-setTargetAtTime, where the equation\n\t\t// is described. 0 results in a division by 0.\n\t\tvalue = Math.max(this._minOutput, value);\n\t\ttimeConstant = Math.max(this._minOutput, timeConstant);\n\t\tthis._param.setTargetAtTime(value, this.toSeconds(startTime), timeConstant);\n\t\treturn this;\n\t};\n\n\t/**\n\t * Sets an array of arbitrary parameter values starting at the given time\n\t * for the given duration.\n\t * \t\n\t * @param {Array} values \n\t * @param {Time} startTime \n\t * @param {Time} duration \n\t * @returns {Tone.Param} this\n\t */\n\tTone.Param.prototype.setValueCurveAtTime = function(values, startTime, duration){\n\t\tfor (var i = 0; i < values.length; i++){\n\t\t\tvalues[i] = this._fromUnits(values[i]);\n\t\t}\n\t\tthis._param.setValueCurveAtTime(values, this.toSeconds(startTime), this.toSeconds(duration));\n\t\treturn this;\n\t};\n\n\t/**\n\t * Cancels all scheduled parameter changes with times greater than or \n\t * equal to startTime.\n\t * \n\t * @param {Time} startTime\n\t * @returns {Tone.Param} this\n\t */\n\tTone.Param.prototype.cancelScheduledValues = function(startTime){\n\t\tthis._param.cancelScheduledValues(this.toSeconds(startTime));\n\t\treturn this;\n\t};\n\n\t/**\n\t * Ramps to the given value over the duration of the rampTime. \n\t * Automatically selects the best ramp type (exponential or linear)\n\t * depending on the `units` of the signal\n\t * \n\t * @param {number} value \n\t * @param {Time} rampTime \tThe time that it takes the \n\t * value to ramp from it's current value\n\t * @param {Time}\t[startTime=now] \tWhen the ramp should start. \n\t * @returns {Tone.Param} this\n\t * @example\n\t * //ramp to the value either linearly or exponentially \n\t * //depending on the \"units\" value of the signal\n\t * signal.rampTo(0, 10);\n\t * @example\n\t * //schedule it to ramp starting at a specific time\n\t * signal.rampTo(0, 10, 5)\n\t */\n\tTone.Param.prototype.rampTo = function(value, rampTime, startTime){\n\t\trampTime = this.defaultArg(rampTime, 0);\n\t\tif (this.units === Tone.Type.Frequency || this.units === Tone.Type.BPM || this.units === Tone.Type.Decibels){\n\t\t\tthis.exponentialRampToValue(value, rampTime, startTime);\n\t\t} else {\n\t\t\tthis.linearRampToValue(value, rampTime, startTime);\n\t\t}\n\t\treturn this;\n\t};\n\n\t/**\n\t * The LFO created by the signal instance. If none\n\t * was created, this is null.\n\t * @type {Tone.LFO}\n\t * @readOnly\n\t * @memberOf Tone.Param#\n\t * @name lfo\n\t */\n\tObject.defineProperty(Tone.Param.prototype, \"lfo\", {\n\t\tget : function(){\n\t\t\treturn this._lfo;\n\t\t}\n\t});\n\n\t/**\n\t * Clean up\n\t * @returns {Tone.Param} this\n\t */\n\tTone.Param.prototype.dispose = function(){\n\t\tTone.prototype.dispose.call(this);\n\t\tthis._param = null;\n\t\tif (this._lfo){\n\t\t\tthis._lfo.dispose();\n\t\t\tthis._lfo = null;\n\t\t}\n\t\treturn this;\n\t};\n\n\treturn Tone.Param;\n});","'use strict';\n\ndefine(function (require) {\n var p5sound = require('master');\n\n var Add = require('Tone/signal/Add');\n var Mult = require('Tone/signal/Multiply');\n var Scale = require('Tone/signal/Scale');\n\n /**\n *
Creates a signal that oscillates between -1.0 and 1.0.\n * By default, the oscillation takes the form of a sinusoidal\n * shape ('sine'). Additional types include 'triangle',\n * 'sawtooth' and 'square'. The frequency defaults to\n * 440 oscillations per second (440Hz, equal to the pitch of an\n * 'A' note).
\n *\n * @class p5.Oscillator\n * @constructor\n * @param {Number} [freq] frequency defaults to 440Hz\n * @param {String} [type] type of oscillator. Options:\n * 'sine' (default), 'triangle',\n * 'sawtooth', 'square'\n * @example\n *
\n * var osc;\n * var playing = false;\n *\n * function setup() {\n * backgroundColor = color(255,0,255);\n * textAlign(CENTER);\n *\n * osc = new p5.Oscillator();\n * osc.setType('sine');\n * osc.freq(240);\n * osc.amp(0);\n * osc.start();\n * }\n *\n * function draw() {\n * background(backgroundColor)\n * text('click to play', width/2, height/2);\n * }\n *\n * function mouseClicked() {\n * if (mouseX > 0 && mouseX < width && mouseY < height && mouseY > 0) {\n * if (!playing) {\n * // ramp amplitude to 0.5 over 0.05 seconds\n * osc.amp(0.5, 0.05);\n * playing = true;\n * backgroundColor = color(0,255,255);\n * } else {\n * // ramp amplitude to 0 over 0.5 seconds\n * osc.amp(0, 0.5);\n * playing = false;\n * backgroundColor = color(255,0,255);\n * }\n * }\n * }\n *
\n */\n p5.Oscillator = function(freq, type) {\n if (typeof freq === 'string') {\n var f = type;\n type = freq;\n freq = f;\n } if (typeof type === 'number') {\n var f = type;\n type = freq;\n freq = f;\n }\n this.started = false;\n\n // components\n this.phaseAmount = undefined;\n this.oscillator = p5sound.audiocontext.createOscillator();\n this.f = freq || 440.0; // frequency\n this.oscillator.type = type || 'sine';\n this.oscillator.frequency.setValueAtTime(this.f, p5sound.audiocontext.currentTime);\n\n // connections\n this.output = p5sound.audiocontext.createGain();\n\n this._freqMods = []; // modulators connected to this oscillator's frequency\n\n // set default output gain to 0.5\n this.output.gain.value = 0.5;\n this.output.gain.setValueAtTime(0.5, p5sound.audiocontext.currentTime);\n\n this.oscillator.connect(this.output);\n // stereo panning\n this.panPosition = 0.0;\n this.connection = p5sound.input; // connect to p5sound by default\n this.panner = new p5.Panner(this.output, this.connection, 1);\n\n //array of math operation signal chaining\n this.mathOps = [this.output];\n\n // add to the soundArray so we can dispose of the osc later\n p5sound.soundArray.push(this);\n };\n\n /**\n * Start an oscillator. Accepts an optional parameter to\n * determine how long (in seconds from now) until the\n * oscillator starts.\n *\n * @method start\n * @for p5.Oscillator\n * @param {Number} [time] startTime in seconds from now.\n * @param {Number} [frequency] frequency in Hz.\n */\n p5.Oscillator.prototype.start = function(time, f) {\n if (this.started) {\n var now = p5sound.audiocontext.currentTime;\n this.stop(now);\n }\n if (!this.started) {\n var freq = f || this.f;\n var type = this.oscillator.type;\n\n // set old osc free to be garbage collected (memory)\n if (this.oscillator) {\n this.oscillator.disconnect();\n delete this.oscillator;\n }\n\n // var detune = this.oscillator.frequency.value;\n this.oscillator = p5sound.audiocontext.createOscillator();\n this.oscillator.frequency.value = Math.abs(freq);\n this.oscillator.type = type;\n // this.oscillator.detune.value = detune;\n this.oscillator.connect(this.output);\n time = time || 0;\n this.oscillator.start(time + p5sound.audiocontext.currentTime);\n this.freqNode = this.oscillator.frequency;\n\n // if other oscillators are already connected to this osc's freq\n for (var i in this._freqMods) {\n if (typeof this._freqMods[i].connect !== 'undefined') {\n this._freqMods[i].connect(this.oscillator.frequency);\n }\n }\n\n this.started = true;\n }\n };\n\n /**\n * Stop an oscillator. Accepts an optional parameter\n * to determine how long (in seconds from now) until the\n * oscillator stops.\n *\n * @method stop\n * @for p5.Oscillator\n * @param {Number} secondsFromNow Time, in seconds from now.\n */\n p5.Oscillator.prototype.stop = function(time) {\n if (this.started) {\n var t = time || 0;\n var now = p5sound.audiocontext.currentTime;\n this.oscillator.stop(t + now);\n this.started = false;\n }\n };\n\n /**\n * Set the amplitude between 0 and 1.0. Or, pass in an object\n * such as an oscillator to modulate amplitude with an audio signal.\n *\n * @method amp\n * @for p5.Oscillator\n * @param {Number|Object} vol between 0 and 1.0\n * or a modulating signal/oscillator\n * @param {Number} [rampTime] create a fade that lasts rampTime\n * @param {Number} [timeFromNow] schedule this event to happen\n * seconds from now\n * @return {AudioParam} gain If no value is provided,\n * returns the Web Audio API\n * AudioParam that controls\n * this oscillator's\n * gain/amplitude/volume)\n */\n p5.Oscillator.prototype.amp = function(vol, rampTime, tFromNow) {\n var self = this;\n if (typeof vol === 'number') {\n var rampTime = rampTime || 0;\n var tFromNow = tFromNow || 0;\n var now = p5sound.audiocontext.currentTime;\n this.output.gain.linearRampToValueAtTime(vol, now + tFromNow + rampTime);\n }\n\n else if (vol) {\n vol.connect(self.output.gain);\n } else {\n // return the Gain Node\n return this.output.gain;\n }\n };\n\n // these are now the same thing\n p5.Oscillator.prototype.fade = p5.Oscillator.prototype.amp;\n\n p5.Oscillator.prototype.getAmp = function() {\n return this.output.gain.value;\n };\n\n /**\n * Set frequency of an oscillator to a value. Or, pass in an object\n * such as an oscillator to modulate the frequency with an audio signal.\n *\n * @method freq\n * @for p5.Oscillator\n * @param {Number|Object} Frequency Frequency in Hz\n * or modulating signal/oscillator\n * @param {Number} [rampTime] Ramp time (in seconds)\n * @param {Number} [timeFromNow] Schedule this event to happen\n * at x seconds from now\n * @return {AudioParam} Frequency If no value is provided,\n * returns the Web Audio API\n * AudioParam that controls\n * this oscillator's frequency\n * @example\n *
\n * var osc = new p5.Oscillator(300);\n * osc.start();\n * osc.freq(40, 10);\n *
\n */\n p5.Oscillator.prototype.freq = function(val, rampTime, tFromNow) {\n if (typeof val === 'number' && !isNaN(val)) {\n this.f = val;\n var now = p5sound.audiocontext.currentTime;\n var rampTime = rampTime || 0;\n var tFromNow = tFromNow || 0;\n var t = now + tFromNow + rampTime;\n // var currentFreq = this.oscillator.frequency.value;\n // this.oscillator.frequency.cancelScheduledValues(now);\n\n if (rampTime === 0) {\n this.oscillator.frequency.setValueAtTime(val, tFromNow + now);\n } else {\n if (val > 0 ) {\n this.oscillator.frequency.exponentialRampToValueAtTime(val, tFromNow + rampTime + now);\n } else {\n this.oscillator.frequency.linearRampToValueAtTime(val, tFromNow + rampTime + now);\n }\n }\n\n // reset phase if oscillator has a phase\n if (this.phaseAmount) {\n this.phase(this.phaseAmount);\n }\n\n } else if (val) {\n if (val.output) {\n val = val.output;\n }\n val.connect(this.oscillator.frequency);\n\n // keep track of what is modulating this param\n // so it can be re-connected if\n this._freqMods.push( val );\n } else {\n // return the Frequency Node\n return this.oscillator.frequency;\n }\n };\n\n p5.Oscillator.prototype.getFreq = function() {\n return this.oscillator.frequency.value;\n };\n\n /**\n * Set type to 'sine', 'triangle', 'sawtooth' or 'square'.\n *\n * @method setType\n * @for p5.Oscillator\n * @param {String} type 'sine', 'triangle', 'sawtooth' or 'square'.\n */\n p5.Oscillator.prototype.setType = function(type) {\n this.oscillator.type = type;\n };\n\n p5.Oscillator.prototype.getType = function() {\n return this.oscillator.type;\n };\n\n /**\n * Connect to a p5.sound / Web Audio object.\n *\n * @method connect\n * @for p5.Oscillator\n * @param {Object} unit A p5.sound or Web Audio object\n */\n p5.Oscillator.prototype.connect = function(unit) {\n if (!unit) {\n this.panner.connect(p5sound.input);\n }\n else if (unit.hasOwnProperty('input')) {\n this.panner.connect(unit.input);\n this.connection = unit.input;\n }\n else {\n this.panner.connect(unit);\n this.connection = unit;\n }\n };\n\n /**\n * Disconnect all outputs\n *\n * @method disconnect\n * @for p5.Oscillator\n */\n p5.Oscillator.prototype.disconnect = function() {\n if (this.output) {\n this.output.disconnect();\n }\n if (this.panner) {\n this.panner.disconnect();\n if (this.output) {\n this.output.connect(this.panner);\n }\n }\n this.oscMods = [];\n };\n\n /**\n * Pan between Left (-1) and Right (1)\n *\n * @method pan\n * @for p5.Oscillator\n * @param {Number} panning Number between -1 and 1\n * @param {Number} timeFromNow schedule this event to happen\n * seconds from now\n */\n p5.Oscillator.prototype.pan = function(pval, tFromNow) {\n this.panPosition = pval;\n this.panner.pan(pval, tFromNow);\n };\n\n p5.Oscillator.prototype.getPan = function() {\n return this.panPosition;\n };\n\n // get rid of the oscillator\n p5.Oscillator.prototype.dispose = function() {\n // remove reference from soundArray\n var index = p5sound.soundArray.indexOf(this);\n p5sound.soundArray.splice(index, 1);\n\n if (this.oscillator) {\n var now = p5sound.audiocontext.currentTime;\n this.stop(now);\n this.disconnect();\n this.panner = null;\n this.oscillator = null;\n }\n // if it is a Pulse\n if (this.osc2) {\n this.osc2.dispose();\n }\n };\n\n /**\n * Set the phase of an oscillator between 0.0 and 1.0.\n * In this implementation, phase is a delay time\n * based on the oscillator's current frequency.\n *\n * @method phase\n * @for p5.Oscillator\n * @param {Number} phase float between 0.0 and 1.0\n */\n p5.Oscillator.prototype.phase = function(p) {\n var delayAmt = p5.prototype.map(p, 0, 1.0, 0, 1/this.f);\n var now = p5sound.audiocontext.currentTime;\n\n this.phaseAmount = p;\n\n if (!this.dNode) {\n // create a delay node\n this.dNode = p5sound.audiocontext.createDelay();\n // put the delay node in between output and panner\n this.oscillator.disconnect();\n this.oscillator.connect(this.dNode);\n this.dNode.connect(this.output);\n }\n\n // set delay time to match phase:\n this.dNode.delayTime.setValueAtTime(delayAmt, now);\n };\n\n // ========================== //\n // SIGNAL MATH FOR MODULATION //\n // ========================== //\n\n // return sigChain(this, scale, thisChain, nextChain, Scale);\n var sigChain = function(o, mathObj, thisChain, nextChain, type) {\n var chainSource = o.oscillator;\n // if this type of math already exists in the chain, replace it\n for (var i in o.mathOps) {\n if (o.mathOps[i] instanceof type) {\n chainSource.disconnect();\n o.mathOps[i].dispose();\n thisChain = i;\n // assume nextChain is output gain node unless...\n if (thisChain < o.mathOps.length - 2) {\n nextChain = o.mathOps[i+1];\n }\n }\n }\n if (thisChain === o.mathOps.length - 1) {\n o.mathOps.push(nextChain);\n }\n // assume source is the oscillator unless i > 0\n if (i > 0) {\n chainSource = o.mathOps[i-1];\n }\n chainSource.disconnect();\n chainSource.connect(mathObj);\n mathObj.connect(nextChain);\n o.mathOps[thisChain] = mathObj;\n return o;\n };\n\n /**\n * Add a value to the p5.Oscillator's output amplitude,\n * and return the oscillator. Calling this method again\n * will override the initial add() with a new value.\n *\n * @method add\n * @for p5.Oscillator\n * @param {Number} number Constant number to add\n * @return {p5.Oscillator} Oscillator Returns this oscillator\n * with scaled output\n *\n */\n p5.Oscillator.prototype.add = function(num) {\n var add = new Add(num);\n var thisChain = this.mathOps.length-1;\n var nextChain = this.output;\n return sigChain(this, add, thisChain, nextChain, Add);\n };\n\n /**\n * Multiply the p5.Oscillator's output amplitude\n * by a fixed value (i.e. turn it up!). Calling this method\n * again will override the initial mult() with a new value.\n *\n * @method mult\n * @for p5.Oscillator\n * @param {Number} number Constant number to multiply\n * @return {p5.Oscillator} Oscillator Returns this oscillator\n * with multiplied output\n */\n p5.Oscillator.prototype.mult = function(num) {\n var mult = new Mult(num);\n var thisChain = this.mathOps.length-1;\n var nextChain = this.output;\n return sigChain(this, mult, thisChain, nextChain, Mult);\n };\n\n /**\n * Scale this oscillator's amplitude values to a given\n * range, and return the oscillator. Calling this method\n * again will override the initial scale() with new values.\n *\n * @method scale\n * @for p5.Oscillator\n * @param {Number} inMin input range minumum\n * @param {Number} inMax input range maximum\n * @param {Number} outMin input range minumum\n * @param {Number} outMax input range maximum\n * @return {p5.Oscillator} Oscillator Returns this oscillator\n * with scaled output\n */\n p5.Oscillator.prototype.scale = function(inMin, inMax, outMin, outMax) {\n var mapOutMin, mapOutMax;\n if (arguments.length === 4) {\n mapOutMin = p5.prototype.map(outMin, inMin, inMax, 0, 1) - 0.5;\n mapOutMax = p5.prototype.map(outMax, inMin, inMax, 0, 1) - 0.5;\n }\n else {\n mapOutMin = arguments[0];\n mapOutMax = arguments[1];\n }\n var scale = new Scale(mapOutMin, mapOutMax);\n var thisChain = this.mathOps.length-1;\n var nextChain = this.output;\n return sigChain(this, scale, thisChain, nextChain, Scale);\n\n // this.output.disconnect();\n // this.output.connect(scale)\n };\n\n // ============================== //\n // SinOsc, TriOsc, SqrOsc, SawOsc //\n // ============================== //\n\n /**\n * Constructor: new p5.SinOsc().\n * This creates a Sine Wave Oscillator and is\n * equivalent to new p5.Oscillator('sine')\n * or creating a p5.Oscillator and then calling\n * its method setType('sine').\n * See p5.Oscillator for methods.\n *\n * @class p5.SinOsc\n * @constructor\n * @extends p5.Oscillator\n * @param {Number} [freq] Set the frequency\n */\n p5.SinOsc = function(freq) {\n p5.Oscillator.call(this, freq, 'sine');\n };\n\n p5.SinOsc.prototype = Object.create(p5.Oscillator.prototype);\n\n /**\n * Constructor: new p5.TriOsc().\n * This creates a Triangle Wave Oscillator and is\n * equivalent to new p5.Oscillator('triangle')\n * or creating a p5.Oscillator and then calling\n * its method setType('triangle').\n * See p5.Oscillator for methods.\n *\n * @class p5.TriOsc\n * @constructor\n * @extends p5.Oscillator\n * @param {Number} [freq] Set the frequency\n */\n p5.TriOsc = function(freq) {\n p5.Oscillator.call(this, freq, 'triangle');\n };\n\n p5.TriOsc.prototype = Object.create(p5.Oscillator.prototype);\n\n /**\n * Constructor: new p5.SawOsc().\n * This creates a SawTooth Wave Oscillator and is\n * equivalent to new p5.Oscillator('sawtooth')\n * or creating a p5.Oscillator and then calling\n * its method setType('sawtooth').\n * See p5.Oscillator for methods.\n *\n * @class p5.SawOsc\n * @constructor\n * @extends p5.Oscillator\n * @param {Number} [freq] Set the frequency\n */\n p5.SawOsc = function(freq) {\n p5.Oscillator.call(this, freq, 'sawtooth');\n };\n\n p5.SawOsc.prototype = Object.create(p5.Oscillator.prototype);\n\n /**\n * Constructor: new p5.SqrOsc().\n * This creates a Square Wave Oscillator and is\n * equivalent to new p5.Oscillator('square')\n * or creating a p5.Oscillator and then calling\n * its method setType('square').\n * See p5.Oscillator for methods.\n *\n * @class p5.SqrOsc\n * @constructor\n * @extends p5.Oscillator\n * @param {Number} [freq] Set the frequency\n */\n p5.SqrOsc = function(freq) {\n p5.Oscillator.call(this, freq, 'square');\n };\n\n p5.SqrOsc.prototype = Object.create(p5.Oscillator.prototype);\n\n});\n","define([\"Tone/core/Tone\", \"Tone/type/Type\"], function (Tone) {\n\n\t\"use strict\";\n\n\t/**\n\t * @class A Timeline class for scheduling and maintaining state\n\t * along a timeline. All events must have a \"time\" property. \n\t * Internally, events are stored in time order for fast \n\t * retrieval.\n\t * @extends {Tone}\n\t * @param {Positive} [memory=Infinity] The number of previous events that are retained.\n\t */\n\tTone.Timeline = function(){\n\n\t\tvar options = this.optionsObject(arguments, [\"memory\"], Tone.Timeline.defaults);\n\n\t\t/**\n\t\t * The array of scheduled timeline events\n\t\t * @type {Array}\n\t\t * @private\n\t\t */\n\t\tthis._timeline = [];\n\n\t\t/**\n\t\t * An array of items to remove from the list. \n\t\t * @type {Array}\n\t\t * @private\n\t\t */\n\t\tthis._toRemove = [];\n\n\t\t/**\n\t\t * Flag if the tieline is mid iteration\n\t\t * @private\n\t\t * @type {Boolean}\n\t\t */\n\t\tthis._iterating = false;\n\n\t\t/**\n\t\t * The memory of the timeline, i.e.\n\t\t * how many events in the past it will retain\n\t\t * @type {Positive}\n\t\t */\n\t\tthis.memory = options.memory;\n\t};\n\n\tTone.extend(Tone.Timeline);\n\n\t/**\n\t * the default parameters\n\t * @static\n\t * @const\n\t */\n\tTone.Timeline.defaults = {\n\t\t\"memory\" : Infinity\n\t};\n\n\t/**\n\t * The number of items in the timeline.\n\t * @type {Number}\n\t * @memberOf Tone.Timeline#\n\t * @name length\n\t * @readOnly\n\t */\n\tObject.defineProperty(Tone.Timeline.prototype, \"length\", {\n\t\tget : function(){\n\t\t\treturn this._timeline.length;\n\t\t}\n\t});\n\n\t/**\n\t * Insert an event object onto the timeline. Events must have a \"time\" attribute.\n\t * @param {Object} event The event object to insert into the \n\t * timeline. \n\t * @returns {Tone.Timeline} this\n\t */\n\tTone.Timeline.prototype.add = function(event){\n\t\t//the event needs to have a time attribute\n\t\tif (this.isUndef(event.time)){\n\t\t\tthrow new Error(\"Tone.Timeline: events must have a time attribute\");\n\t\t}\n\t\tif (this._timeline.length){\n\t\t\tvar index = this._search(event.time);\n\t\t\tthis._timeline.splice(index + 1, 0, event);\n\t\t} else {\n\t\t\tthis._timeline.push(event);\t\t\t\n\t\t}\n\t\t//if the length is more than the memory, remove the previous ones\n\t\tif (this.length > this.memory){\n\t\t\tvar diff = this.length - this.memory;\n\t\t\tthis._timeline.splice(0, diff);\n\t\t}\n\t\treturn this;\n\t};\n\n\t/**\n\t * Remove an event from the timeline.\n\t * @param {Object} event The event object to remove from the list.\n\t * @returns {Tone.Timeline} this\n\t */\n\tTone.Timeline.prototype.remove = function(event){\n\t\tif (this._iterating){\n\t\t\tthis._toRemove.push(event);\n\t\t} else {\n\t\t\tvar index = this._timeline.indexOf(event);\n\t\t\tif (index !== -1){\n\t\t\t\tthis._timeline.splice(index, 1);\n\t\t\t}\n\t\t}\n\t\treturn this;\n\t};\n\n\t/**\n\t * Get the nearest event whose time is less than or equal to the given time.\n\t * @param {Number} time The time to query.\n\t * @returns {Object} The event object set after that time.\n\t */\n\tTone.Timeline.prototype.get = function(time){\n\t\tvar index = this._search(time);\n\t\tif (index !== -1){\n\t\t\treturn this._timeline[index];\n\t\t} else {\n\t\t\treturn null;\n\t\t}\n\t};\n\n\t/**\n\t * Return the first event in the timeline without removing it\n\t * @returns {Object} The first event object\n\t */\n\tTone.Timeline.prototype.peek = function(){\n\t\treturn this._timeline[0];\n\t};\n\n\t/**\n\t * Return the first event in the timeline and remove it\n\t * @returns {Object} The first event object\n\t */\n\tTone.Timeline.prototype.shift = function(){\n\t\treturn this._timeline.shift();\n\t};\n\n\t/**\n\t * Get the event which is scheduled after the given time.\n\t * @param {Number} time The time to query.\n\t * @returns {Object} The event object after the given time\n\t */\n\tTone.Timeline.prototype.getAfter = function(time){\n\t\tvar index = this._search(time);\n\t\tif (index + 1 < this._timeline.length){\n\t\t\treturn this._timeline[index + 1];\n\t\t} else {\n\t\t\treturn null;\n\t\t}\n\t};\n\n\t/**\n\t * Get the event before the event at the given time.\n\t * @param {Number} time The time to query.\n\t * @returns {Object} The event object before the given time\n\t */\n\tTone.Timeline.prototype.getBefore = function(time){\n\t\tvar len = this._timeline.length;\n\t\t//if it's after the last item, return the last item\n\t\tif (len > 0 && this._timeline[len - 1].time < time){\n\t\t\treturn this._timeline[len - 1];\n\t\t}\n\t\tvar index = this._search(time);\n\t\tif (index - 1 >= 0){\n\t\t\treturn this._timeline[index - 1];\n\t\t} else {\n\t\t\treturn null;\n\t\t}\n\t};\n\n\t/**\n\t * Cancel events after the given time\n\t * @param {Number} time The time to query.\n\t * @returns {Tone.Timeline} this\n\t */\n\tTone.Timeline.prototype.cancel = function(after){\n\t\tif (this._timeline.length > 1){\n\t\t\tvar index = this._search(after);\n\t\t\tif (index >= 0){\n\t\t\t\tif (this._timeline[index].time === after){\n\t\t\t\t\t//get the first item with that time\n\t\t\t\t\tfor (var i = index; i >= 0; i--){\n\t\t\t\t\t\tif (this._timeline[i].time === after){\n\t\t\t\t\t\t\tindex = i;\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tthis._timeline = this._timeline.slice(0, index);\n\t\t\t\t} else {\n\t\t\t\t\tthis._timeline = this._timeline.slice(0, index + 1);\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tthis._timeline = [];\n\t\t\t}\n\t\t} else if (this._timeline.length === 1){\n\t\t\t//the first item's time\n\t\t\tif (this._timeline[0].time >= after){\n\t\t\t\tthis._timeline = [];\n\t\t\t}\n\t\t}\n\t\treturn this;\n\t};\n\n\t/**\n\t * Cancel events before or equal to the given time.\n\t * @param {Number} time The time to cancel before.\n\t * @returns {Tone.Timeline} this\n\t */\n\tTone.Timeline.prototype.cancelBefore = function(time){\n\t\tif (this._timeline.length){\n\t\t\tvar index = this._search(time);\n\t\t\tif (index >= 0){\n\t\t\t\tthis._timeline = this._timeline.slice(index + 1);\n\t\t\t}\n\t\t}\n\t\treturn this;\n\t};\n\n\t/**\n\t * Does a binary serach on the timeline array and returns the \n\t * nearest event index whose time is after or equal to the given time.\n\t * If a time is searched before the first index in the timeline, -1 is returned.\n\t * If the time is after the end, the index of the last item is returned.\n\t * @param {Number} time \n\t * @return {Number} the index in the timeline array \n\t * @private\n\t */\n\tTone.Timeline.prototype._search = function(time){\n\t\tvar beginning = 0;\n\t\tvar len = this._timeline.length;\n\t\tvar end = len;\n\t\tif (len > 0 && this._timeline[len - 1].time <= time){\n\t\t\treturn len - 1;\n\t\t}\n\t\twhile (beginning < end){\n\t\t\t// calculate the midpoint for roughly equal partition\n\t\t\tvar midPoint = Math.floor(beginning + (end - beginning) / 2);\n\t\t\tvar event = this._timeline[midPoint];\n\t\t\tvar nextEvent = this._timeline[midPoint + 1];\n\t\t\tif (event.time === time){\n\t\t\t\t//choose the last one that has the same time\n\t\t\t\tfor (var i = midPoint; i < this._timeline.length; i++){\n\t\t\t\t\tvar testEvent = this._timeline[i];\n\t\t\t\t\tif (testEvent.time === time){\n\t\t\t\t\t\tmidPoint = i;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\treturn midPoint;\n\t\t\t} else if (event.time < time && nextEvent.time > time){\n\t\t\t\treturn midPoint;\n\t\t\t} else if (event.time > time){\n\t\t\t\t//search lower\n\t\t\t\tend = midPoint;\n\t\t\t} else if (event.time < time){\n\t\t\t\t//search upper\n\t\t\t\tbeginning = midPoint + 1;\n\t\t\t} \n\t\t}\n\t\treturn -1;\n\t};\n\n\t/**\n\t * Internal iterator. Applies extra safety checks for \n\t * removing items from the array. \n\t * @param {Function} callback \n\t * @param {Number=} lowerBound \n\t * @param {Number=} upperBound \n\t * @private\n\t */\n\tTone.Timeline.prototype._iterate = function(callback, lowerBound, upperBound){\n\t\tthis._iterating = true;\n\t\tlowerBound = this.defaultArg(lowerBound, 0);\n\t\tupperBound = this.defaultArg(upperBound, this._timeline.length - 1);\n\t\tfor (var i = lowerBound; i <= upperBound; i++){\n\t\t\tcallback(this._timeline[i]);\n\t\t}\n\t\tthis._iterating = false;\n\t\tif (this._toRemove.length > 0){\n\t\t\tfor (var j = 0; j < this._toRemove.length; j++){\n\t\t\t\tvar index = this._timeline.indexOf(this._toRemove[j]);\n\t\t\t\tif (index !== -1){\n\t\t\t\t\tthis._timeline.splice(index, 1);\n\t\t\t\t}\n\t\t\t}\n\t\t\tthis._toRemove = [];\n\t\t}\n\t};\n\n\t/**\n\t * Iterate over everything in the array\n\t * @param {Function} callback The callback to invoke with every item\n\t * @returns {Tone.Timeline} this\n\t */\n\tTone.Timeline.prototype.forEach = function(callback){\n\t\tthis._iterate(callback);\n\t\treturn this;\n\t};\n\n\t/**\n\t * Iterate over everything in the array at or before the given time.\n\t * @param {Number} time The time to check if items are before\n\t * @param {Function} callback The callback to invoke with every item\n\t * @returns {Tone.Timeline} this\n\t */\n\tTone.Timeline.prototype.forEachBefore = function(time, callback){\n\t\t//iterate over the items in reverse so that removing an item doesn't break things\n\t\tvar upperBound = this._search(time);\n\t\tif (upperBound !== -1){\n\t\t\tthis._iterate(callback, 0, upperBound);\n\t\t}\n\t\treturn this;\n\t};\n\n\t/**\n\t * Iterate over everything in the array after the given time.\n\t * @param {Number} time The time to check if items are before\n\t * @param {Function} callback The callback to invoke with every item\n\t * @returns {Tone.Timeline} this\n\t */\n\tTone.Timeline.prototype.forEachAfter = function(time, callback){\n\t\t//iterate over the items in reverse so that removing an item doesn't break things\n\t\tvar lowerBound = this._search(time);\n\t\tthis._iterate(callback, lowerBound + 1);\n\t\treturn this;\n\t};\n\n\t/**\n\t * Iterate over everything in the array at or after the given time. Similar to \n\t * forEachAfter, but includes the item(s) at the given time.\n\t * @param {Number} time The time to check if items are before\n\t * @param {Function} callback The callback to invoke with every item\n\t * @returns {Tone.Timeline} this\n\t */\n\tTone.Timeline.prototype.forEachFrom = function(time, callback){\n\t\t//iterate over the items in reverse so that removing an item doesn't break things\n\t\tvar lowerBound = this._search(time);\n\t\t//work backwards until the event time is less than time\n\t\twhile (lowerBound >= 0 && this._timeline[lowerBound].time >= time){\n\t\t\tlowerBound--;\n\t\t}\n\t\tthis._iterate(callback, lowerBound + 1);\n\t\treturn this;\n\t};\n\n\t/**\n\t * Iterate over everything in the array at the given time\n\t * @param {Number} time The time to check if items are before\n\t * @param {Function} callback The callback to invoke with every item\n\t * @returns {Tone.Timeline} this\n\t */\n\tTone.Timeline.prototype.forEachAtTime = function(time, callback){\n\t\t//iterate over the items in reverse so that removing an item doesn't break things\n\t\tvar upperBound = this._search(time);\n\t\tif (upperBound !== -1){\n\t\t\tthis._iterate(function(event){\n\t\t\t\tif (event.time === time){\n\t\t\t\t\tcallback(event);\n\t\t\t\t} \n\t\t\t}, 0, upperBound);\n\t\t}\n\t\treturn this;\n\t};\n\n\t/**\n\t * Clean up.\n\t * @return {Tone.Timeline} this\n\t */\n\tTone.Timeline.prototype.dispose = function(){\n\t\tTone.prototype.dispose.call(this);\n\t\tthis._timeline = null;\n\t\tthis._toRemove = null;\n\t};\n\n\treturn Tone.Timeline;\n});","define([\"Tone/core/Tone\", \"Tone/signal/Multiply\", \"Tone/signal/Signal\"], function(Tone){\n\n\t\"use strict\";\n\n\t/**\n\t * @class Negate the incoming signal. i.e. an input signal of 10 will output -10\n\t *\n\t * @constructor\n\t * @extends {Tone.SignalBase}\n\t * @example\n\t * var neg = new Tone.Negate();\n\t * var sig = new Tone.Signal(-2).connect(neg);\n\t * //output of neg is positive 2. \n\t */\n\tTone.Negate = function(){\n\t\t/**\n\t\t * negation is done by multiplying by -1\n\t\t * @type {Tone.Multiply}\n\t\t * @private\n\t\t */\n\t\tthis._multiply = this.input = this.output = new Tone.Multiply(-1);\n\t};\n\n\tTone.extend(Tone.Negate, Tone.SignalBase);\n\n\t/**\n\t * clean up\n\t * @returns {Tone.Negate} this\n\t */\n\tTone.Negate.prototype.dispose = function(){\n\t\tTone.prototype.dispose.call(this);\n\t\tthis._multiply.dispose();\n\t\tthis._multiply = null;\n\t\treturn this;\n\t}; \n\n\treturn Tone.Negate;\n});","define([\"Tone/core/Tone\", \"Tone/signal/Signal\", \"Tone/signal/Multiply\", \"Tone/signal/WaveShaper\"], \nfunction(Tone){\n\n\t\"use strict\";\n\n\t/**\n\t * @class GreaterThanZero outputs 1 when the input is strictly greater than zero\n\t * \n\t * @constructor\n\t * @extends {Tone.SignalBase}\n\t * @example\n\t * var gt0 = new Tone.GreaterThanZero();\n\t * var sig = new Tone.Signal(0.01).connect(gt0);\n\t * //the output of gt0 is 1. \n\t * sig.value = 0;\n\t * //the output of gt0 is 0. \n\t */\n\tTone.GreaterThanZero = function(){\n\t\t\n\t\t/**\n\t\t * @type {Tone.WaveShaper}\n\t\t * @private\n\t\t */\n\t\tthis._thresh = this.output = new Tone.WaveShaper(function(val){\n\t\t\tif (val <= 0){\n\t\t\t\treturn 0;\n\t\t\t} else {\n\t\t\t\treturn 1;\n\t\t\t}\n\t\t}, 127);\n\n\t\t/**\n\t\t * scale the first thresholded signal by a large value.\n\t\t * this will help with values which are very close to 0\n\t\t * @type {Tone.Multiply}\n\t\t * @private\n\t\t */\n\t\tthis._scale = this.input = new Tone.Multiply(10000);\n\n\t\t//connections\n\t\tthis._scale.connect(this._thresh);\n\t};\n\n\tTone.extend(Tone.GreaterThanZero, Tone.SignalBase);\n\n\t/**\n\t * dispose method\n\t * @returns {Tone.GreaterThanZero} this\n\t */\n\tTone.GreaterThanZero.prototype.dispose = function(){\n\t\tTone.prototype.dispose.call(this);\n\t\tthis._scale.dispose();\n\t\tthis._scale = null;\n\t\tthis._thresh.dispose();\n\t\tthis._thresh = null;\n\t\treturn this;\n\t};\n\n\treturn Tone.GreaterThanZero;\n});","define([\"Tone/core/Tone\", \"Tone/signal/TimelineSignal\", \"Tone/core/TimelineState\", \n\t\"Tone/core/Emitter\", \"Tone/core/Context\"], function (Tone) {\n\n\t\"use strict\";\n\n\t/**\n\t * @class A sample accurate clock which provides a callback at the given rate. \n\t * While the callback is not sample-accurate (it is still susceptible to\n\t * loose JS timing), the time passed in as the argument to the callback\n\t * is precise. For most applications, it is better to use Tone.Transport\n\t * instead of the Clock by itself since you can synchronize multiple callbacks.\n\t *\n\t * \t@constructor\n\t * @extends {Tone.Emitter}\n\t * \t@param {function} callback The callback to be invoked with the time of the audio event\n\t * \t@param {Frequency} frequency The rate of the callback\n\t * \t@example\n\t * //the callback will be invoked approximately once a second\n\t * //and will print the time exactly once a second apart.\n\t * var clock = new Tone.Clock(function(time){\n\t * \tconsole.log(time);\n\t * }, 1);\n\t */\n\tTone.Clock = function(){\n\n\t\tTone.Emitter.call(this);\n\n\t\tvar options = this.optionsObject(arguments, [\"callback\", \"frequency\"], Tone.Clock.defaults);\n\n\t\t/**\n\t\t * The callback function to invoke at the scheduled tick.\n\t\t * @type {Function}\n\t\t */\n\t\tthis.callback = options.callback;\n\n\t\t/**\n\t\t * The next time the callback is scheduled.\n\t\t * @type {Number}\n\t\t * @private\n\t\t */\n\t\tthis._nextTick = 0;\n\n\t\t/**\n\t\t * The last state of the clock.\n\t\t * @type {State}\n\t\t * @private\n\t\t */\n\t\tthis._lastState = Tone.State.Stopped;\n\n\t\t/**\n\t\t * The rate the callback function should be invoked. \n\t\t * @type {BPM}\n\t\t * @signal\n\t\t */\n\t\tthis.frequency = new Tone.TimelineSignal(options.frequency, Tone.Type.Frequency);\n\t\tthis._readOnly(\"frequency\");\n\n\t\t/**\n\t\t * The number of times the callback was invoked. Starts counting at 0\n\t\t * and increments after the callback was invoked. \n\t\t * @type {Ticks}\n\t\t * @readOnly\n\t\t */\n\t\tthis.ticks = 0;\n\n\t\t/**\n\t\t * The state timeline\n\t\t * @type {Tone.TimelineState}\n\t\t * @private\n\t\t */\n\t\tthis._state = new Tone.TimelineState(Tone.State.Stopped);\n\n\t\t/**\n\t\t * The loop function bound to its context. \n\t\t * This is necessary to remove the event in the end.\n\t\t * @type {Function}\n\t\t * @private\n\t\t */\n\t\tthis._boundLoop = this._loop.bind(this);\n\n\t\t//bind a callback to the worker thread\n \tthis.context.on(\"tick\", this._boundLoop);\n\t};\n\n\tTone.extend(Tone.Clock, Tone.Emitter);\n\n\t/**\n\t * The defaults\n\t * @const\n\t * @type {Object}\n\t */\n\tTone.Clock.defaults = {\n\t\t\"callback\" : Tone.noOp,\n\t\t\"frequency\" : 1,\n\t\t\"lookAhead\" : \"auto\",\n\t};\n\n\t/**\n\t * Returns the playback state of the source, either \"started\", \"stopped\" or \"paused\".\n\t * @type {Tone.State}\n\t * @readOnly\n\t * @memberOf Tone.Clock#\n\t * @name state\n\t */\n\tObject.defineProperty(Tone.Clock.prototype, \"state\", {\n\t\tget : function(){\n\t\t\treturn this._state.getValueAtTime(this.now());\n\t\t}\n\t});\n\n\t/**\n\t * Start the clock at the given time. Optionally pass in an offset\n\t * of where to start the tick counter from.\n\t * @param {Time} time The time the clock should start\n\t * @param {Ticks=} offset Where the tick counter starts counting from.\n\t * @return {Tone.Clock} this\n\t */\n\tTone.Clock.prototype.start = function(time, offset){\n\t\ttime = this.toSeconds(time);\n\t\tif (this._state.getValueAtTime(time) !== Tone.State.Started){\n\t\t\tthis._state.add({\n\t\t\t\t\"state\" : Tone.State.Started, \n\t\t\t\t\"time\" : time,\n\t\t\t\t\"offset\" : offset\n\t\t\t});\n\t\t}\n\t\treturn this;\t\n\t};\n\n\t/**\n\t * Stop the clock. Stopping the clock resets the tick counter to 0.\n\t * @param {Time} [time=now] The time when the clock should stop.\n\t * @returns {Tone.Clock} this\n\t * @example\n\t * clock.stop();\n\t */\n\tTone.Clock.prototype.stop = function(time){\n\t\ttime = this.toSeconds(time);\n\t\tthis._state.cancel(time);\n\t\tthis._state.setStateAtTime(Tone.State.Stopped, time);\n\t\treturn this;\t\n\t};\n\n\n\t/**\n\t * Pause the clock. Pausing does not reset the tick counter.\n\t * @param {Time} [time=now] The time when the clock should stop.\n\t * @returns {Tone.Clock} this\n\t */\n\tTone.Clock.prototype.pause = function(time){\n\t\ttime = this.toSeconds(time);\n\t\tif (this._state.getValueAtTime(time) === Tone.State.Started){\n\t\t\tthis._state.setStateAtTime(Tone.State.Paused, time);\n\t\t}\n\t\treturn this;\t\n\t};\n\n\t/**\n\t * The scheduling loop.\n\t * @param {Number} time The current page time starting from 0\n\t * when the page was loaded.\n\t * @private\n\t */\n\tTone.Clock.prototype._loop = function(){\n\t\t//get the frequency value to compute the value of the next loop\n\t\tvar now = this.now();\n\t\t//if it's started\n\t\tvar lookAhead = this.context.lookAhead;\n\t\tvar updateInterval = this.context.updateInterval;\n\t\tvar lagCompensation = this.context.lag * 2;\n\t\tvar loopInterval = now + lookAhead + updateInterval + lagCompensation;\n\t\twhile (loopInterval > this._nextTick && this._state){\n\t\t\tvar currentState = this._state.getValueAtTime(this._nextTick);\n\t\t\tif (currentState !== this._lastState){\n\t\t\t\tthis._lastState = currentState;\n\t\t\t\tvar event = this._state.get(this._nextTick);\n\t\t\t\t// emit an event\n\t\t\t\tif (currentState === Tone.State.Started){\n\t\t\t\t\t//correct the time\n\t\t\t\t\tthis._nextTick = event.time;\n\t\t\t\t\tif (!this.isUndef(event.offset)){\n\t\t\t\t\t\tthis.ticks = event.offset;\n\t\t\t\t\t}\n\t\t\t\t\tthis.emit(\"start\", event.time, this.ticks);\n\t\t\t\t} else if (currentState === Tone.State.Stopped){\n\t\t\t\t\tthis.ticks = 0;\n\n\t\t\t\t\tthis.emit(\"stop\", event.time);\n\t\t\t\t} else if (currentState === Tone.State.Paused){\n\t\t\t\t\tthis.emit(\"pause\", event.time);\n\t\t\t\t}\n\t\t\t}\n\t\t\tvar tickTime = this._nextTick;\n\t\t\tif (this.frequency){\n\t\t\t\tthis._nextTick += 1 / this.frequency.getValueAtTime(this._nextTick);\n\t\t\t\tif (currentState === Tone.State.Started){\n\t\t\t\t\tthis.callback(tickTime);\n\t\t\t\t\tthis.ticks++;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t};\n\n\t/**\n\t * Returns the scheduled state at the given time.\n\t * @param {Time} time The time to query.\n\t * @return {String} The name of the state input in setStateAtTime.\n\t * @example\n\t * clock.start(\"+0.1\");\n\t * clock.getStateAtTime(\"+0.1\"); //returns \"started\"\n\t */\n\tTone.Clock.prototype.getStateAtTime = function(time){\n\t\ttime = this.toSeconds(time);\n\t\treturn this._state.getValueAtTime(time);\n\t};\n\n\t/**\n\t * Clean up\n\t * @returns {Tone.Clock} this\n\t */\n\tTone.Clock.prototype.dispose = function(){\n\t\tTone.Emitter.prototype.dispose.call(this);\n\t\tthis.context.off(\"tick\", this._boundLoop);\n\t\tthis._writable(\"frequency\");\n\t\tthis.frequency.dispose();\n\t\tthis.frequency = null;\n\t\tthis._boundLoop = null;\n\t\tthis._nextTick = Infinity;\n\t\tthis.callback = null;\n\t\tthis._state.dispose();\n\t\tthis._state = null;\n\t};\n\n\treturn Tone.Clock;\n});","'use strict';\ndefine(function (require) {\n\n var p5sound = require('master');\n var AudioVoice = require('audioVoice');\n var noteToFreq = require('helpers').noteToFreq;\n\n var DEFAULT_SUSTAIN = 0.15;\n\n /**\n * A MonoSynth is used as a single voice for sound synthesis.\n * This is a class to be used in conjunction with the PolySynth\n * class. Custom synthetisers should be built inheriting from\n * this class.\n *\n * @class p5.MonoSynth\n * @constructor\n * @example\n *
\n * var monoSynth;\n *\n * function setup() {\n * var cnv = createCanvas(100, 100);\n * cnv.mousePressed(playSynth);\n *\n * monoSynth = new p5.MonoSynth();\n *\n * textAlign(CENTER);\n * text('click to play', width/2, height/2);\n * }\n *\n * function playSynth() {\n * // time from now (in seconds)\n * var time = 0;\n * // note duration (in seconds)\n * var dur = 0.25;\n * // velocity (volume, from 0 to 1)\n * var v = 0.2;\n *\n * monoSynth.play(\"G3\", v, time, dur);\n * monoSynth.play(\"C4\", v, time += dur, dur);\n *\n * background(random(255), random(255), 255);\n * text('click to play', width/2, height/2);\n * }\n *
\n **/\n\n p5.MonoSynth = function () {\n AudioVoice.call(this);\n\n this.oscillator = new p5.Oscillator();\n\n this.env = new p5.Envelope();\n this.env.setRange(1, 0);\n this.env.setExp(true);\n\n //set params\n this.setADSR(0.02, 0.25, 0.05, 0.35);\n\n // oscillator --> env --> this.output (gain) --> p5.soundOut\n this.oscillator.disconnect();\n this.oscillator.connect(this.output);\n\n this.env.disconnect();\n this.env.setInput(this.output.gain);\n\n // reset oscillator gain to 1.0\n this.oscillator.output.gain.value = 1.0;\n\n this.oscillator.start();\n this.connect();\n\n p5sound.soundArray.push(this);\n };\n\n p5.MonoSynth.prototype = Object.create(p5.AudioVoice.prototype);\n\n /**\n * Play tells the MonoSynth to start playing a note. This method schedules\n * the calling of .triggerAttack and .triggerRelease.\n *\n * @method play\n * @for p5.MonoSynth\n * @param {String | Number} note the note you want to play, specified as a\n * frequency in Hertz (Number) or as a midi\n * value in Note/Octave format (\"C4\", \"Eb3\"...etc\")\n * See \n * Tone. Defaults to 440 hz.\n * @param {Number} [velocity] velocity of the note to play (ranging from 0 to 1)\n * @param {Number} [secondsFromNow] time from now (in seconds) at which to play\n * @param {Number} [sustainTime] time to sustain before releasing the envelope\n * @example\n *
\n * var monoSynth;\n *\n * function setup() {\n * var cnv = createCanvas(100, 100);\n * cnv.mousePressed(playSynth);\n *\n * monoSynth = new p5.MonoSynth();\n *\n * textAlign(CENTER);\n * text('click to play', width/2, height/2);\n * }\n *\n * function playSynth() {\n * // time from now (in seconds)\n * var time = 0;\n * // note duration (in seconds)\n * var dur = 1/6;\n * // note velocity (volume, from 0 to 1)\n * var v = random();\n *\n * monoSynth.play(\"Fb3\", v, 0, dur);\n * monoSynth.play(\"Gb3\", v, time += dur, dur);\n *\n * background(random(255), random(255), 255);\n * text('click to play', width/2, height/2);\n * }\n *
\n *\n */\n p5.MonoSynth.prototype.play = function (note, velocity, secondsFromNow, susTime) {\n this.triggerAttack(note, velocity, ~~secondsFromNow);\n this.triggerRelease(~~secondsFromNow + (susTime || DEFAULT_SUSTAIN));\n };\n\n /**\n * Trigger the Attack, and Decay portion of the Envelope.\n * Similar to holding down a key on a piano, but it will\n * hold the sustain level until you let go.\n *\n * @param {String | Number} note the note you want to play, specified as a\n * frequency in Hertz (Number) or as a midi\n * value in Note/Octave format (\"C4\", \"Eb3\"...etc\")\n * See \n * Tone. Defaults to 440 hz\n * @param {Number} [velocity] velocity of the note to play (ranging from 0 to 1)\n * @param {Number} [secondsFromNow] time from now (in seconds) at which to play\n * @method triggerAttack\n * @for p5.MonoSynth\n * @example\n *
\n * var monoSynth = new p5.MonoSynth();\n *\n * function mousePressed() {\n * monoSynth.triggerAttack(\"E3\");\n * }\n *\n * function mouseReleased() {\n * monoSynth.triggerRelease();\n * }\n *
\n */\n p5.MonoSynth.prototype.triggerAttack = function (note, velocity, secondsFromNow) {\n var secondsFromNow = ~~secondsFromNow;\n var freq = noteToFreq(note);\n var vel = velocity || 0.1;\n this.oscillator.freq(freq, 0, secondsFromNow);\n this.env.ramp(this.output.gain, secondsFromNow, vel);\n };\n\n /**\n * Trigger the release of the Envelope. This is similar to releasing\n * the key on a piano and letting the sound fade according to the\n * release level and release time.\n *\n * @param {Number} secondsFromNow time to trigger the release\n * @method triggerRelease\n * @for p5.MonoSynth\n * @example\n *
\n * var monoSynth = new p5.MonoSynth();\n *\n * function mousePressed() {\n * monoSynth.triggerAttack(\"E3\");\n * }\n *\n * function mouseReleased() {\n * monoSynth.triggerRelease();\n * }\n *
\n */\n p5.MonoSynth.prototype.triggerRelease = function (secondsFromNow) {\n var secondsFromNow = secondsFromNow || 0;\n this.env.ramp(this.output.gain, secondsFromNow, 0);\n };\n\n /**\n * Set values like a traditional\n * \n * ADSR envelope\n * .\n *\n * @method setADSR\n * @for p5.MonoSynth\n * @param {Number} attackTime Time (in seconds before envelope\n * reaches Attack Level\n * @param {Number} [decayTime] Time (in seconds) before envelope\n * reaches Decay/Sustain Level\n * @param {Number} [susRatio] Ratio between attackLevel and releaseLevel, on a scale from 0 to 1,\n * where 1.0 = attackLevel, 0.0 = releaseLevel.\n * The susRatio determines the decayLevel and the level at which the\n * sustain portion of the envelope will sustain.\n * For example, if attackLevel is 0.4, releaseLevel is 0,\n * and susAmt is 0.5, the decayLevel would be 0.2. If attackLevel is\n * increased to 1.0 (using setRange),\n * then decayLevel would increase proportionally, to become 0.5.\n * @param {Number} [releaseTime] Time in seconds from now (defaults to 0)\n */\n p5.MonoSynth.prototype.setADSR = function (attack,decay,sustain,release) {\n this.env.setADSR(attack, decay, sustain, release);\n };\n\n\n /**\n * Getters and Setters\n * @property {Number} attack\n * @for p5.MonoSynth\n */\n /**\n * @property {Number} decay\n * @for p5.MonoSynth\n */\n /**\n * @property {Number} sustain\n * @for p5.MonoSynth\n */\n /**\n * @property {Number} release\n * @for p5.MonoSynth\n */\n Object.defineProperties(p5.MonoSynth.prototype, {\n 'attack': {\n get : function() {\n return this.env.aTime;\n },\n set : function(attack) {\n this.env.setADSR(attack, this.env.dTime,\n this.env.sPercent, this.env.rTime);\n }\n },\n 'decay': {\n get : function() {\n return this.env.dTime;\n },\n set : function(decay) {\n this.env.setADSR(this.env.aTime, decay,\n this.env.sPercent, this.env.rTime);\n }\n },\n 'sustain': {\n get : function() {\n return this.env.sPercent;\n },\n set : function(sustain) {\n this.env.setADSR(this.env.aTime, this.env.dTime,\n sustain, this.env.rTime);\n }\n },\n 'release': {\n get : function() {\n return this.env.rTime;\n },\n set : function(release) {\n this.env.setADSR(this.env.aTime, this.env.dTime,\n this.env.sPercent, release);\n }\n },\n });\n\n\n /**\n * MonoSynth amp\n * @method amp\n * @for p5.MonoSynth\n * @param {Number} vol desired volume\n * @param {Number} [rampTime] Time to reach new volume\n * @return {Number} new volume value\n */\n p5.MonoSynth.prototype.amp = function(vol, rampTime) {\n var t = rampTime || 0;\n if (typeof vol !== 'undefined') {\n this.oscillator.amp(vol, t);\n }\n return this.oscillator.amp().value;\n };\n\n /**\n * Connect to a p5.sound / Web Audio object.\n *\n * @method connect\n * @for p5.MonoSynth\n * @param {Object} unit A p5.sound or Web Audio object\n */\n\n p5.MonoSynth.prototype.connect = function(unit) {\n var u = unit || p5sound.input;\n this.output.connect(u.input ? u.input : u);\n };\n\n /**\n * Disconnect all outputs\n *\n * @method disconnect\n * @for p5.MonoSynth\n */\n p5.MonoSynth.prototype.disconnect = function() {\n if (this.output) {\n this.output.disconnect();\n }\n };\n\n\n /**\n * Get rid of the MonoSynth and free up its resources / memory.\n *\n * @method dispose\n * @for p5.MonoSynth\n */\n p5.MonoSynth.prototype.dispose = function() {\n AudioVoice.prototype.dispose.apply(this);\n\n if (this.env) {\n this.env.dispose();\n }\n if (this.oscillator) {\n this.oscillator.dispose();\n }\n };\n\n});\n","'use strict';\ndefine(function() {\n var p5sound = require('master');\n\n /**\n * Base class for monophonic synthesizers. Any extensions of this class\n * should follow the API and implement the methods below in order to\n * remain compatible with p5.PolySynth();\n *\n * @class p5.AudioVoice\n * @constructor\n */\n p5.AudioVoice = function () {\n\t this.ac = p5sound.audiocontext;\n\t this.output = this.ac.createGain();\n\t this.connect();\n\t p5sound.soundArray.push(this);\n };\n\n p5.AudioVoice.prototype.play = function (note, velocity, secondsFromNow, sustime) {\n };\n\n p5.AudioVoice.prototype.triggerAttack = function (note, velocity, secondsFromNow) {\n };\n\n p5.AudioVoice.prototype.triggerRelease = function (secondsFromNow) {\n };\n\n p5.AudioVoice.prototype.amp = function(vol, rampTime) {\n };\n\n /**\n * Connect to p5 objects or Web Audio Nodes\n * @method connect\n * @for p5.AudioVoice\n * @param {Object} unit\n */\n p5.AudioVoice.prototype.connect = function(unit) {\n var u = unit || p5sound.input;\n this.output.connect(u.input ? u.input : u);\n };\n\n /**\n * Disconnect from soundOut\n * @method disconnect\n * @for p5.AudioVoice\n */\n p5.AudioVoice.prototype.disconnect = function() {\n this.output.disconnect();\n };\n\n p5.AudioVoice.prototype.dispose = function() {\n if (this.output) {\n this.output.disconnect();\n delete this.output;\n }\n };\n\n return p5.AudioVoice;\n});\n","'use strict';\ndefine(function (require) {\n\n var p5sound = require('master');\n var TimelineSignal = require('Tone/signal/TimelineSignal');\n var noteToFreq = require('helpers').noteToFreq;\n\n /**\n * An AudioVoice is used as a single voice for sound synthesis.\n * The PolySynth class holds an array of AudioVoice, and deals\n * with voices allocations, with setting notes to be played, and\n * parameters to be set.\n *\n * @class p5.PolySynth\n * @constructor\n *\n * @param {Number} [synthVoice] A monophonic synth voice inheriting\n * the AudioVoice class. Defaults to p5.MonoSynth\n * @param {Number} [maxVoices] Number of voices, defaults to 8;\n * @example\n *
\n * var polySynth;\n *\n * function setup() {\n * var cnv = createCanvas(100, 100);\n * cnv.mousePressed(playSynth);\n *\n * polySynth = new p5.PolySynth();\n *\n * textAlign(CENTER);\n * text('click to play', width/2, height/2);\n * }\n *\n * function playSynth() {\n * // note duration (in seconds)\n * var dur = 1.5;\n *\n * // time from now (in seconds)\n * var time = 0;\n *\n * // velocity (volume, from 0 to 1)\n * var vel = 0.1;\n *\n * // notes can overlap with each other\n * polySynth.play(\"G2\", vel, 0, dur);\n * polySynth.play(\"C3\", vel, time += 1/3, dur);\n * polySynth.play(\"G3\", vel, time += 1/3, dur);\n *\n * background(random(255), random(255), 255);\n * text('click to play', width/2, height/2);\n * }\n *
\n **/\n p5.PolySynth = function(audioVoice, maxVoices) {\n //audiovoices will contain maxVoices many monophonic synths\n this.audiovoices = [];\n\n /**\n * An object that holds information about which notes have been played and\n * which notes are currently being played. New notes are added as keys\n * on the fly. While a note has been attacked, but not released, the value of the\n * key is the audiovoice which is generating that note. When notes are released,\n * the value of the key becomes undefined.\n * @property notes\n */\n this.notes = {};\n\n //indices of the most recently used, and least recently used audiovoice\n this._newest = 0;\n this._oldest = 0;\n\n /**\n * A PolySynth must have at least 1 voice, defaults to 8\n * @property polyvalue\n */\n this.maxVoices = maxVoices || 8;\n\n /**\n * Monosynth that generates the sound for each note that is triggered. The\n * p5.PolySynth defaults to using the p5.MonoSynth as its voice.\n * @property AudioVoice\n */\n this.AudioVoice = audioVoice === undefined ? p5.MonoSynth : audioVoice;\n\n /**\n * This value must only change as a note is attacked or released. Due to delay\n * and sustain times, Tone.TimelineSignal is required to schedule the change in value.\n\t * @private\n * @property {Tone.TimelineSignal} _voicesInUse\n */\n this._voicesInUse = new TimelineSignal(0);\n\n this.output = p5sound.audiocontext.createGain();\n this.connect();\n\n //Construct the appropriate number of audiovoices\n this._allocateVoices();\n p5sound.soundArray.push(this);\n };\n\n /**\n * Construct the appropriate number of audiovoices\n * @private\n * @for p5.PolySynth\n * @method _allocateVoices\n */\n p5.PolySynth.prototype._allocateVoices = function() {\n for(var i = 0; i< this.maxVoices; i++) {\n this.audiovoices.push(new this.AudioVoice());\n this.audiovoices[i].disconnect();\n this.audiovoices[i].connect(this.output);\n }\n };\n\n /**\n * Play a note by triggering noteAttack and noteRelease with sustain time\n *\n * @method play\n * @for p5.PolySynth\n * @param {Number} [note] midi note to play (ranging from 0 to 127 - 60 being a middle C)\n * @param {Number} [velocity] velocity of the note to play (ranging from 0 to 1)\n * @param {Number} [secondsFromNow] time from now (in seconds) at which to play\n * @param {Number} [sustainTime] time to sustain before releasing the envelope\n * @example\n *
\n * var polySynth;\n *\n * function setup() {\n * var cnv = createCanvas(100, 100);\n * cnv.mousePressed(playSynth);\n *\n * polySynth = new p5.PolySynth();\n *\n * textAlign(CENTER);\n * text('click to play', width/2, height/2);\n * }\n *\n * function playSynth() {\n * // note duration (in seconds)\n * var dur = 0.1;\n *\n * // time from now (in seconds)\n * var time = 0;\n *\n * // velocity (volume, from 0 to 1)\n * var vel = 0.1;\n *\n * polySynth.play(\"G2\", vel, 0, dur);\n * polySynth.play(\"C3\", vel, 0, dur);\n * polySynth.play(\"G3\", vel, 0, dur);\n *\n * background(random(255), random(255), 255);\n * text('click to play', width/2, height/2);\n * }\n *
\n */\n p5.PolySynth.prototype.play = function (note,velocity, secondsFromNow, susTime) {\n var susTime = susTime || 1;\n this.noteAttack(note, velocity, secondsFromNow);\n this.noteRelease(note, secondsFromNow + susTime);\n };\n\n\n /**\n * noteADSR sets the envelope for a specific note that has just been triggered.\n * Using this method modifies the envelope of whichever audiovoice is being used\n * to play the desired note. The envelope should be reset before noteRelease is called\n * in order to prevent the modified envelope from being used on other notes.\n *\n * @method noteADSR\n * @for p5.PolySynth\n * @param {Number} [note] Midi note on which ADSR should be set.\n * @param {Number} [attackTime] Time (in seconds before envelope\n * reaches Attack Level\n * @param {Number} [decayTime] Time (in seconds) before envelope\n * reaches Decay/Sustain Level\n * @param {Number} [susRatio] Ratio between attackLevel and releaseLevel, on a scale from 0 to 1,\n * where 1.0 = attackLevel, 0.0 = releaseLevel.\n * The susRatio determines the decayLevel and the level at which the\n * sustain portion of the envelope will sustain.\n * For example, if attackLevel is 0.4, releaseLevel is 0,\n * and susAmt is 0.5, the decayLevel would be 0.2. If attackLevel is\n * increased to 1.0 (using setRange),\n * then decayLevel would increase proportionally, to become 0.5.\n * @param {Number} [releaseTime] Time in seconds from now (defaults to 0)\n **/\n\n p5.PolySynth.prototype.noteADSR = function (note,a,d,s,r,timeFromNow) {\n var now = p5sound.audiocontext.currentTime;\n var timeFromNow = timeFromNow || 0;\n var t = now + timeFromNow\n this.audiovoices[ this.notes[note].getValueAtTime(t) ].setADSR(a,d,s,r);\n };\n\n\n /**\n * Set the PolySynths global envelope. This method modifies the envelopes of each\n * monosynth so that all notes are played with this envelope.\n *\n * @method setADSR\n * @for p5.PolySynth\n * @param {Number} [attackTime] Time (in seconds before envelope\n * reaches Attack Level\n * @param {Number} [decayTime] Time (in seconds) before envelope\n * reaches Decay/Sustain Level\n * @param {Number} [susRatio] Ratio between attackLevel and releaseLevel, on a scale from 0 to 1,\n * where 1.0 = attackLevel, 0.0 = releaseLevel.\n * The susRatio determines the decayLevel and the level at which the\n * sustain portion of the envelope will sustain.\n * For example, if attackLevel is 0.4, releaseLevel is 0,\n * and susAmt is 0.5, the decayLevel would be 0.2. If attackLevel is\n * increased to 1.0 (using setRange),\n * then decayLevel would increase proportionally, to become 0.5.\n * @param {Number} [releaseTime] Time in seconds from now (defaults to 0)\n **/\n p5.PolySynth.prototype.setADSR = function(a,d,s,r) {\n this.audiovoices.forEach(function(voice) {\n voice.setADSR(a,d,s,r);\n });\n };\n\n /**\n * Trigger the Attack, and Decay portion of a MonoSynth.\n * Similar to holding down a key on a piano, but it will\n * hold the sustain level until you let go.\n *\n * @method noteAttack\n * @for p5.PolySynth\n * @param {Number} [note] midi note on which attack should be triggered.\n * @param {Number} [velocity] velocity of the note to play (ranging from 0 to 1)/\n * @param {Number} [secondsFromNow] time from now (in seconds)\n * @example\n *
\n * var polySynth = new p5.PolySynth();\n * var pitches = [\"G\", \"D\", \"G\", \"C\"];\n * var octaves = [2, 3, 4];\n *\n * function mousePressed() {\n * // play a chord: multiple notes at the same time\n * for (var i = 0; i < 4; i++) {\n * var note = random(pitches) + random(octaves);\n * polySynth.noteAttack(note, 0.1);\n * }\n * }\n *\n * function mouseReleased() {\n * // release all voices\n * polySynth.noteRelease();\n * }\n *
\n */\n p5.PolySynth.prototype.noteAttack = function (_note, _velocity, secondsFromNow) {\n //this value goes to the audiovoices which handle their own scheduling\n var secondsFromNow = ~~secondsFromNow;\n\n //this value is used by this._voicesInUse\n var acTime = p5sound.audiocontext.currentTime + secondsFromNow;\n\n //Convert note to frequency if necessary. This is because entries into this.notes\n //should be based on frequency for the sake of consistency.\n var note = noteToFreq(_note);\n var velocity = _velocity || 0.1;\n\n var currentVoice;\n\n //Release the note if it is already playing\n if (this.notes[note] && this.notes[note].getValueAtTime(acTime) !== null) {\n this.noteRelease(note, 0);\n }\n\n //Check to see how many voices are in use at the time the note will start\n if (this._voicesInUse.getValueAtTime(acTime) < this.maxVoices) {\n currentVoice = Math.max(~~this._voicesInUse.getValueAtTime(acTime), 0);\n }\n //If we are exceeding the polyvalue, bump off the oldest notes and replace\n //with a new note\n else {\n currentVoice = this._oldest;\n\n var oldestNote = p5.prototype.freqToMidi(this.audiovoices[this._oldest].oscillator.freq().value);\n this.noteRelease(oldestNote);\n this._oldest = ( this._oldest + 1 ) % (this.maxVoices - 1);\n }\n\n //Overrite the entry in the notes object. A note (frequency value)\n //corresponds to the index of the audiovoice that is playing it\n this.notes[note] = new TimelineSignal();\n this.notes[note].setValueAtTime(currentVoice, acTime);\n\n //Find the scheduled change in this._voicesInUse that will be previous to this new note\n //Add 1 and schedule this value at time 't', when this note will start playing\n var previousVal = this._voicesInUse._searchBefore(acTime) === null ? 0 : this._voicesInUse._searchBefore(acTime).value;\n this._voicesInUse.setValueAtTime(previousVal + 1, acTime);\n\n //Then update all scheduled values that follow to increase by 1\n this._updateAfter(acTime, 1);\n\n this._newest = currentVoice;\n //The audiovoice handles the actual scheduling of the note\n if (typeof velocity === 'number') {\n var maxRange = 1 / this._voicesInUse.getValueAtTime(acTime) * 2;\n velocity = velocity > maxRange ? maxRange : velocity;\n }\n this.audiovoices[currentVoice].triggerAttack(note, velocity, secondsFromNow);\n };\n\n /**\n * Private method to ensure accurate values of this._voicesInUse\n * Any time a new value is scheduled, it is necessary to increment all subsequent\n * scheduledValues after attack, and decrement all subsequent\n * scheduledValues after release\n *\n * @private\n * @for p5.PolySynth\n * @param {[type]} time [description]\n * @param {[type]} value [description]\n * @return {[type]} [description]\n */\n p5.PolySynth.prototype._updateAfter = function(time, value) {\n if(this._voicesInUse._searchAfter(time) === null) {\n return;\n } else{\n this._voicesInUse._searchAfter(time).value += value;\n var nextTime = this._voicesInUse._searchAfter(time).time;\n this._updateAfter(nextTime, value);\n }\n };\n\n\n /**\n * Trigger the Release of an AudioVoice note. This is similar to releasing\n * the key on a piano and letting the sound fade according to the\n * release level and release time.\n *\n * @method noteRelease\n * @for p5.PolySynth\n * @param {Number} [note] midi note on which attack should be triggered.\n * If no value is provided, all notes will be released.\n * @param {Number} [secondsFromNow] time to trigger the release\n * @example\n *
\n * var pitches = [\"G\", \"D\", \"G\", \"C\"];\n * var octaves = [2, 3, 4];\n * var polySynth = new p5.PolySynth();\n *\n * function mousePressed() {\n * // play a chord: multiple notes at the same time\n * for (var i = 0; i < 4; i++) {\n * var note = random(pitches) + random(octaves);\n * polySynth.noteAttack(note, 0.1);\n * }\n * }\n *\n * function mouseReleased() {\n * // release all voices\n * polySynth.noteRelease();\n * }\n *
\n *\n */\n p5.PolySynth.prototype.noteRelease = function (_note,secondsFromNow) {\n var now = p5sound.audiocontext.currentTime;\n var tFromNow = secondsFromNow || 0;\n var t = now + tFromNow;\n\n // if a note value is not provided, release all voices\n if (!_note) {\n this.audiovoices.forEach(function(voice) {\n voice.triggerRelease(tFromNow)\n });\n this._voicesInUse.setValueAtTime(0, t);\n for (var n in this.notes) {\n this.notes[n].dispose();\n delete this.notes[n];\n }\n return;\n }\n\n //Make sure note is in frequency inorder to query the this.notes object\n var note = noteToFreq(_note);\n\n if (!this.notes[note] || this.notes[note].getValueAtTime(t) === null) {\n console.warn('Cannot release a note that is not already playing');\n } else {\n //Find the scheduled change in this._voicesInUse that will be previous to this new note\n //subtract 1 and schedule this value at time 't', when this note will stop playing\n var previousVal = Math.max(~~this._voicesInUse.getValueAtTime(t).value, 1);\n this._voicesInUse.setValueAtTime(previousVal - 1, t);\n //Then update all scheduled values that follow to decrease by 1 but never go below 0\n if (previousVal > 0) {\n this._updateAfter(t, -1);\n }\n\n this.audiovoices[ this.notes[note].getValueAtTime(t) ].triggerRelease(tFromNow);\n this.notes[note].dispose();\n delete this.notes[note];\n\n this._newest = this._newest === 0 ? 0 : (this._newest - 1) % (this.maxVoices - 1);\n }\n\n };\n\n /**\n * Connect to a p5.sound / Web Audio object.\n *\n * @method connect\n * @for p5.PolySynth\n * @param {Object} unit A p5.sound or Web Audio object\n */\n p5.PolySynth.prototype.connect = function (unit) {\n var u = unit || p5sound.input;\n this.output.connect(u.input ? u.input : u);\n };\n\n /**\n * Disconnect all outputs\n *\n * @method disconnect\n * @for p5.PolySynth\n */\n p5.PolySynth.prototype.disconnect = function() {\n if (this.output) {\n this.output.disconnect();\n }\n };\n\n /**\n * Get rid of the MonoSynth and free up its resources / memory.\n *\n * @method dispose\n * @for p5.PolySynth\n */\n p5.PolySynth.prototype.dispose = function() {\n this.audiovoices.forEach(function(voice) {\n voice.dispose();\n });\n\n if (this.output) {\n this.output.disconnect();\n delete this.output;\n }\n };\n\n});\n","'use strict';\n\ndefine(function (require) {\n\n require('audioworklet-polyfill');\n require('shims');\n require('audiocontext');\n var p5SOUND = require('master');\n require('helpers');\n require('errorHandler');\n require('audioWorklet');\n require('panner');\n require('soundfile');\n require('amplitude');\n require('fft');\n require('signal');\n require('oscillator');\n require('envelope');\n require('pulse');\n require('noise');\n require('audioin');\n require('filter');\n require('eq');\n require('panner3d');\n require('listener3d');\n require('delay');\n require('reverb');\n require('metro');\n require('looper');\n require('soundLoop');\n require('compressor');\n require('soundRecorder');\n require('peakDetect');\n require('gain');\n require('monosynth');\n require('polysynth');\n require('distortion');\n require('audioVoice');\n require('monosynth');\n require('polysynth');\n\n return p5SOUND;\n\n});\n","!function(){var e,t=[];function r(e){var r=this,n={},i=-1;this.parameters.forEach(function(e,o){var s=t[++i]||(t[i]=new Float32Array(r.bufferSize));s.fill(e.value),n[o]=s}),this.processor.realm.exec(\"self.sampleRate=sampleRate=\"+this.context.sampleRate+\";self.currentTime=currentTime=\"+this.context.currentTime);var s=o(e.inputBuffer),a=o(e.outputBuffer);this.instance.process([s],[a],n)}function o(e){for(var t=[],r=0;r= this.sampleLimit) {\\n this.stop();\\n return true;\\n }\\n\\n var input = inputs[0];\\n var output = outputs[0];\\n\\n for (var channel = 0; channel < output.length; ++channel) {\\n var inputChannel = input[channel];\\n\\n if (channel === 0) {\\n this.leftBuffers.push(inputChannel);\\n\\n if (this.numInputChannels === 1) {\\n this.rightBuffers.push(inputChannel);\\n }\\n } else if (channel === 1 && this.numInputChannels > 1) {\\n this.rightBuffers.push(inputChannel);\\n }\\n }\\n\\n this.recordedSamples += output[0].length;\\n return true;\\n }\\n }, {\\n key: \\\"record\\\",\\n value: function record(duration) {\\n if (duration) {\\n this.sampleLimit = Math.round(duration * sampleRate);\\n }\\n\\n this.recording = true;\\n }\\n }, {\\n key: \\\"stop\\\",\\n value: function stop() {\\n this.recording = false;\\n var buffers = this.getBuffers();\\n var leftBuffer = buffers[0].buffer;\\n var rightBuffer = buffers[1].buffer;\\n this.port.postMessage({\\n name: 'buffers',\\n leftBuffer: leftBuffer,\\n rightBuffer: rightBuffer\\n }, [leftBuffer, rightBuffer]);\\n this.clear();\\n }\\n }, {\\n key: \\\"getBuffers\\\",\\n value: function getBuffers() {\\n var buffers = [];\\n buffers.push(this.mergeBuffers(this.leftBuffers));\\n buffers.push(this.mergeBuffers(this.rightBuffers));\\n return buffers;\\n }\\n }, {\\n key: \\\"mergeBuffers\\\",\\n value: function mergeBuffers(channelBuffer) {\\n var result = new Float32Array(this.recordedSamples);\\n var offset = 0;\\n var lng = channelBuffer.length;\\n\\n for (var i = 0; i < lng; i++) {\\n var buffer = channelBuffer[i];\\n result.set(buffer, offset);\\n offset += buffer.length;\\n }\\n\\n return result;\\n }\\n }, {\\n key: \\\"clear\\\",\\n value: function clear() {\\n this.leftBuffers = [];\\n this.rightBuffers = [];\\n this.recordedSamples = 0;\\n this.sampleLimit = null;\\n }\\n }]);\\n\\n return RecorderProcessor;\\n}(_wrapNativeSuper(AudioWorkletProcessor));\\n\\nregisterProcessor(processorNames.recorderProcessor, RecorderProcessor);\"","export default \"function _typeof(obj) { if (typeof Symbol === \\\"function\\\" && typeof Symbol.iterator === \\\"symbol\\\") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === \\\"function\\\" && obj.constructor === Symbol && obj !== Symbol.prototype ? \\\"symbol\\\" : typeof obj; }; } return _typeof(obj); }\\n\\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\\\"Cannot call a class as a function\\\"); } }\\n\\nfunction _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if (\\\"value\\\" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }\\n\\nfunction _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }\\n\\nfunction _possibleConstructorReturn(self, call) { if (call && (_typeof(call) === \\\"object\\\" || typeof call === \\\"function\\\")) { return call; } return _assertThisInitialized(self); }\\n\\nfunction _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError(\\\"this hasn't been initialised - super() hasn't been called\\\"); } return self; }\\n\\nfunction _inherits(subClass, superClass) { if (typeof superClass !== \\\"function\\\" && superClass !== null) { throw new TypeError(\\\"Super expression must either be null or a function\\\"); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, writable: true, configurable: true } }); if (superClass) _setPrototypeOf(subClass, superClass); }\\n\\nfunction _wrapNativeSuper(Class) { var _cache = typeof Map === \\\"function\\\" ? new Map() : undefined; _wrapNativeSuper = function _wrapNativeSuper(Class) { if (Class === null || !_isNativeFunction(Class)) return Class; if (typeof Class !== \\\"function\\\") { throw new TypeError(\\\"Super expression must either be null or a function\\\"); } if (typeof _cache !== \\\"undefined\\\") { if (_cache.has(Class)) return _cache.get(Class); _cache.set(Class, Wrapper); } function Wrapper() { return _construct(Class, arguments, _getPrototypeOf(this).constructor); } Wrapper.prototype = Object.create(Class.prototype, { constructor: { value: Wrapper, enumerable: false, writable: true, configurable: true } }); return _setPrototypeOf(Wrapper, Class); }; return _wrapNativeSuper(Class); }\\n\\nfunction isNativeReflectConstruct() { if (typeof Reflect === \\\"undefined\\\" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === \\\"function\\\") return true; try { Date.prototype.toString.call(Reflect.construct(Date, [], function () {})); return true; } catch (e) { return false; } }\\n\\nfunction _construct(Parent, args, Class) { if (isNativeReflectConstruct()) { _construct = Reflect.construct; } else { _construct = function _construct(Parent, args, Class) { var a = [null]; a.push.apply(a, args); var Constructor = Function.bind.apply(Parent, a); var instance = new Constructor(); if (Class) _setPrototypeOf(instance, Class.prototype); return instance; }; } return _construct.apply(null, arguments); }\\n\\nfunction _isNativeFunction(fn) { return Function.toString.call(fn).indexOf(\\\"[native code]\\\") !== -1; }\\n\\nfunction _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); }\\n\\nfunction _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); }; return _getPrototypeOf(o); }\\n\\n// import processor name via preval.require so that it's available as a value at compile time\\nvar processorNames = {\\n \\\"recorderProcessor\\\": \\\"recorder-processor\\\",\\n \\\"soundFileProcessor\\\": \\\"sound-file-processor\\\",\\n \\\"amplitudeProcessor\\\": \\\"amplitude-processor\\\"\\n};\\n\\nvar SoundFileProcessor =\\n/*#__PURE__*/\\nfunction (_AudioWorkletProcesso) {\\n _inherits(SoundFileProcessor, _AudioWorkletProcesso);\\n\\n function SoundFileProcessor() {\\n _classCallCheck(this, SoundFileProcessor);\\n\\n return _possibleConstructorReturn(this, _getPrototypeOf(SoundFileProcessor).apply(this, arguments));\\n }\\n\\n _createClass(SoundFileProcessor, [{\\n key: \\\"process\\\",\\n value: function process(inputs) {\\n var input = inputs[0];\\n var inputChannel = input[0];\\n var position = inputChannel[inputChannel.length - 1] || 0;\\n this.port.postMessage({\\n name: 'position',\\n position: position\\n });\\n return true;\\n }\\n }]);\\n\\n return SoundFileProcessor;\\n}(_wrapNativeSuper(AudioWorkletProcessor));\\n\\nregisterProcessor(processorNames.soundFileProcessor, SoundFileProcessor);\"","export default \"function _typeof(obj) { if (typeof Symbol === \\\"function\\\" && typeof Symbol.iterator === \\\"symbol\\\") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === \\\"function\\\" && obj.constructor === Symbol && obj !== Symbol.prototype ? \\\"symbol\\\" : typeof obj; }; } return _typeof(obj); }\\n\\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\\\"Cannot call a class as a function\\\"); } }\\n\\nfunction _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if (\\\"value\\\" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }\\n\\nfunction _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }\\n\\nfunction _possibleConstructorReturn(self, call) { if (call && (_typeof(call) === \\\"object\\\" || typeof call === \\\"function\\\")) { return call; } return _assertThisInitialized(self); }\\n\\nfunction _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError(\\\"this hasn't been initialised - super() hasn't been called\\\"); } return self; }\\n\\nfunction _inherits(subClass, superClass) { if (typeof superClass !== \\\"function\\\" && superClass !== null) { throw new TypeError(\\\"Super expression must either be null or a function\\\"); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, writable: true, configurable: true } }); if (superClass) _setPrototypeOf(subClass, superClass); }\\n\\nfunction _wrapNativeSuper(Class) { var _cache = typeof Map === \\\"function\\\" ? new Map() : undefined; _wrapNativeSuper = function _wrapNativeSuper(Class) { if (Class === null || !_isNativeFunction(Class)) return Class; if (typeof Class !== \\\"function\\\") { throw new TypeError(\\\"Super expression must either be null or a function\\\"); } if (typeof _cache !== \\\"undefined\\\") { if (_cache.has(Class)) return _cache.get(Class); _cache.set(Class, Wrapper); } function Wrapper() { return _construct(Class, arguments, _getPrototypeOf(this).constructor); } Wrapper.prototype = Object.create(Class.prototype, { constructor: { value: Wrapper, enumerable: false, writable: true, configurable: true } }); return _setPrototypeOf(Wrapper, Class); }; return _wrapNativeSuper(Class); }\\n\\nfunction isNativeReflectConstruct() { if (typeof Reflect === \\\"undefined\\\" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === \\\"function\\\") return true; try { Date.prototype.toString.call(Reflect.construct(Date, [], function () {})); return true; } catch (e) { return false; } }\\n\\nfunction _construct(Parent, args, Class) { if (isNativeReflectConstruct()) { _construct = Reflect.construct; } else { _construct = function _construct(Parent, args, Class) { var a = [null]; a.push.apply(a, args); var Constructor = Function.bind.apply(Parent, a); var instance = new Constructor(); if (Class) _setPrototypeOf(instance, Class.prototype); return instance; }; } return _construct.apply(null, arguments); }\\n\\nfunction _isNativeFunction(fn) { return Function.toString.call(fn).indexOf(\\\"[native code]\\\") !== -1; }\\n\\nfunction _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); }\\n\\nfunction _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); }; return _getPrototypeOf(o); }\\n\\n// import processor name via preval.require so that it's available as a value at compile time\\nvar processorNames = {\\n \\\"recorderProcessor\\\": \\\"recorder-processor\\\",\\n \\\"soundFileProcessor\\\": \\\"sound-file-processor\\\",\\n \\\"amplitudeProcessor\\\": \\\"amplitude-processor\\\"\\n};\\n\\nvar AmplitudeProcessor =\\n/*#__PURE__*/\\nfunction (_AudioWorkletProcesso) {\\n _inherits(AmplitudeProcessor, _AudioWorkletProcesso);\\n\\n function AmplitudeProcessor(options) {\\n var _this;\\n\\n _classCallCheck(this, AmplitudeProcessor);\\n\\n _this = _possibleConstructorReturn(this, _getPrototypeOf(AmplitudeProcessor).call(this));\\n var processorOptions = options.processorOptions || {};\\n _this.smoothing = processorOptions.smoothing || 0;\\n _this.normalize = processorOptions.normalize || false;\\n _this.stereoVol = [0, 0];\\n _this.stereoVolNorm = [0, 0];\\n _this.volMax = 0.001;\\n\\n _this.port.onmessage = function (event) {\\n var data = event.data;\\n\\n if (data.name === 'toggleNormalize') {\\n _this.normalize = data.normalize;\\n } else if (data.name === 'smoothing') {\\n _this.smoothing = Math.max(0, Math.min(1, data.smoothing));\\n }\\n };\\n\\n return _this;\\n } // TO DO make this stereo / dependent on # of audio channels\\n\\n\\n _createClass(AmplitudeProcessor, [{\\n key: \\\"process\\\",\\n value: function process(inputs, outputs) {\\n var input = inputs[0];\\n var output = outputs[0];\\n var smoothing = this.smoothing;\\n\\n for (var channel = 0; channel < input.length; ++channel) {\\n var inputBuffer = input[channel];\\n var bufLength = inputBuffer.length;\\n var sum = 0;\\n\\n for (var i = 0; i < bufLength; i++) {\\n var x = inputBuffer[i];\\n\\n if (this.normalize) {\\n sum += Math.max(Math.min(x / this.volMax, 1), -1) * Math.max(Math.min(x / this.volMax, 1), -1);\\n } else {\\n sum += x * x;\\n }\\n } // ... then take the square root of the sum.\\n\\n\\n var rms = Math.sqrt(sum / bufLength);\\n this.stereoVol[channel] = Math.max(rms, this.stereoVol[channel] * smoothing);\\n this.volMax = Math.max(this.stereoVol[channel], this.volMax);\\n } // calculate stero normalized volume and add volume from all channels together\\n\\n\\n var volSum = 0;\\n\\n for (var index = 0; index < this.stereoVol.length; index++) {\\n this.stereoVolNorm[index] = Math.max(Math.min(this.stereoVol[index] / this.volMax, 1), 0);\\n volSum += this.stereoVol[index];\\n } // volume is average of channels\\n\\n\\n var volume = volSum / this.stereoVol.length; // normalized value\\n\\n var volNorm = Math.max(Math.min(volume / this.volMax, 1), 0);\\n this.port.postMessage({\\n name: 'amplitude',\\n volume: volume,\\n volNorm: volNorm,\\n stereoVol: this.stereoVol,\\n stereoVolNorm: this.stereoVolNorm\\n }); // pass input through to output\\n\\n for (var _channel = 0; _channel < output.length; ++_channel) {\\n output[_channel].set(input[_channel]);\\n }\\n\\n return true;\\n }\\n }]);\\n\\n return AmplitudeProcessor;\\n}(_wrapNativeSuper(AudioWorkletProcessor));\\n\\nregisterProcessor(processorNames.amplitudeProcessor, AmplitudeProcessor);\"","'use strict';\n\ndefine(function (require) {\n\n var p5sound = require('master');\n var ac = p5sound.audiocontext;\n\n // Stereo panner\n // if there is a stereo panner node use it\n if(typeof ac.createStereoPanner !== 'undefined') {\n p5.Panner = function (input, output) {\n this.stereoPanner = this.input = ac.createStereoPanner();\n input.connect(this.stereoPanner);\n this.stereoPanner.connect(output);\n };\n\n p5.Panner.prototype.pan = function(val, tFromNow) {\n var time = tFromNow || 0;\n var t = ac.currentTime + time;\n\n this.stereoPanner.pan.linearRampToValueAtTime(val, t);\n };\n\n //not implemented because stereopanner\n //node does not require this and will automatically\n //convert single channel or multichannel to stereo.\n //tested with single and stereo, not with (>2) multichannel\n p5.Panner.prototype.inputChannels = function() {};\n\n p5.Panner.prototype.connect = function(obj) {\n this.stereoPanner.connect(obj);\n };\n\n p5.Panner.prototype.disconnect = function() {\n if (this.stereoPanner) {\n this.stereoPanner.disconnect();\n }\n };\n\n } else {\n // if there is no createStereoPanner object\n // such as in safari 7.1.7 at the time of writing this\n // use this method to create the effect\n p5.Panner = function(input, output, numInputChannels) {\n this.input = ac.createGain();\n input.connect(this.input);\n\n this.left = ac.createGain();\n this.right = ac.createGain();\n this.left.channelInterpretation = 'discrete';\n this.right.channelInterpretation = 'discrete';\n\n // if input is stereo\n if (numInputChannels > 1) {\n this.splitter = ac.createChannelSplitter(2);\n this.input.connect(this.splitter);\n\n this.splitter.connect(this.left, 1);\n this.splitter.connect(this.right, 0);\n }\n else {\n this.input.connect(this.left);\n this.input.connect(this.right);\n }\n\n this.output = ac.createChannelMerger(2);\n this.left.connect(this.output, 0, 1);\n this.right.connect(this.output, 0, 0);\n this.output.connect(output);\n };\n\n // -1 is left, +1 is right\n p5.Panner.prototype.pan = function(val, tFromNow) {\n var time = tFromNow || 0;\n var t = ac.currentTime + time;\n var v = (val + 1) / 2;\n var rightVal = Math.cos(v*Math.PI/2);\n var leftVal = Math.sin(v * Math.PI/2);\n this.left.gain.linearRampToValueAtTime(leftVal, t);\n this.right.gain.linearRampToValueAtTime(rightVal, t);\n };\n\n p5.Panner.prototype.inputChannels = function(numChannels) {\n if (numChannels === 1) {\n this.input.disconnect();\n this.input.connect(this.left);\n this.input.connect(this.right);\n } else if (numChannels === 2) {\n if (typeof(this.splitter === 'undefined')) {\n this.splitter = ac.createChannelSplitter(2);\n }\n this.input.disconnect();\n this.input.connect(this.splitter);\n this.splitter.connect(this.left, 1);\n this.splitter.connect(this.right, 0);\n }\n };\n\n p5.Panner.prototype.connect = function(obj) {\n this.output.connect(obj);\n };\n\n p5.Panner.prototype.disconnect = function() {\n if (this.output) {\n this.output.disconnect();\n }\n };\n }\n});\n","'use strict';\n\ndefine(function (require) {\n\n var CustomError = require('errorHandler');\n var p5sound = require('master');\n var ac = p5sound.audiocontext;\n var midiToFreq = require('helpers').midiToFreq;\n var convertToWav = require('helpers').convertToWav;\n var processorNames = require('./audioWorklet/processorNames');\n\n /**\n *
SoundFile object with a path to a file.
\n *\n *
The p5.SoundFile may not be available immediately because\n * it loads the file information asynchronously.
\n *\n *
To do something with the sound as soon as it loads\n * pass the name of a function as the second parameter.
\n *\n *
Only one file path is required. However, audio file formats\n * (i.e. mp3, ogg, wav and m4a/aac) are not supported by all\n * web browsers. If you want to ensure compatability, instead of a single\n * file path, you may include an Array of filepaths, and the browser will\n * choose a format that works.
\n *\n * @class p5.SoundFile\n * @constructor\n * @param {String|Array} path path to a sound file (String). Optionally,\n * you may include multiple file formats in\n * an array. Alternately, accepts an object\n * from the HTML5 File API, or a p5.File.\n * @param {Function} [successCallback] Name of a function to call once file loads\n * @param {Function} [errorCallback] Name of a function to call if file fails to\n * load. This function will receive an error or\n * XMLHttpRequest object with information\n * about what went wrong.\n * @param {Function} [whileLoadingCallback] Name of a function to call while file\n * is loading. That function will\n * receive progress of the request to\n * load the sound file\n * (between 0 and 1) as its first\n * parameter. This progress\n * does not account for the additional\n * time needed to decode the audio data.\n *\n * @example\n *
\n */\n p5.SoundFile = function(paths, onload, onerror, whileLoading) {\n if (typeof paths !== 'undefined') {\n if (typeof paths === 'string' || typeof paths[0] === 'string') {\n var path = p5.prototype._checkFileFormats(paths);\n this.url = path;\n }\n else if(typeof paths === 'object') {\n if (!(window.File && window.FileReader && window.FileList && window.Blob)) {\n // The File API isn't supported in this browser\n throw 'Unable to load file because the File API is not supported';\n }\n }\n\n // if type is a p5.File...get the actual file\n if (paths.file) {\n paths = paths.file;\n }\n\n this.file = paths;\n }\n\n // private _onended callback, set by the method: onended(callback)\n this._onended = function() {};\n\n this._looping = false;\n this._playing = false;\n this._paused = false;\n this._pauseTime = 0;\n\n // cues for scheduling events with addCue() removeCue()\n this._cues = [];\n this._cueIDCounter = 0;\n\n // position of the most recently played sample\n this._lastPos = 0;\n this._counterNode = null;\n this._workletNode = null;\n\n // array of sources so that they can all be stopped!\n this.bufferSourceNodes = [];\n\n // current source\n this.bufferSourceNode = null;\n\n this.buffer = null;\n this.playbackRate = 1;\n\n this.input = p5sound.audiocontext.createGain();\n this.output = p5sound.audiocontext.createGain();\n\n this.reversed = false;\n\n // start and end of playback / loop\n this.startTime = 0;\n this.endTime = null;\n this.pauseTime = 0;\n\n // \"restart\" would stop playback before retriggering\n this.mode = 'sustain';\n\n // time that playback was started, in millis\n this.startMillis = null;\n\n // stereo panning\n this.panPosition = 0.0;\n this.panner = new p5.Panner(this.output, p5sound.input, 2);\n\n // it is possible to instantiate a soundfile with no path\n if (this.url || this.file) {\n this.load(onload, onerror);\n }\n\n // add this p5.SoundFile to the soundArray\n p5sound.soundArray.push(this);\n\n if (typeof whileLoading === 'function') {\n this._whileLoading = whileLoading;\n } else {\n this._whileLoading = function() {};\n }\n\n this._clearOnEnd = _clearOnEnd.bind(this);\n };\n\n // register preload handling of loadSound\n p5.prototype.registerPreloadMethod('loadSound', p5.prototype);\n\n /**\n * loadSound() returns a new p5.SoundFile from a specified\n * path. If called during preload(), the p5.SoundFile will be ready\n * to play in time for setup() and draw(). If called outside of\n * preload, the p5.SoundFile will not be ready immediately, so\n * loadSound accepts a callback as the second parameter. Using a\n * \n * local server is recommended when loading external files.\n *\n * @method loadSound\n * @for p5\n * @param {String|Array} path Path to the sound file, or an array with\n * paths to soundfiles in multiple formats\n * i.e. ['sound.ogg', 'sound.mp3'].\n * Alternately, accepts an object: either\n * from the HTML5 File API, or a p5.File.\n * @param {Function} [successCallback] Name of a function to call once file loads\n * @param {Function} [errorCallback] Name of a function to call if there is\n * an error loading the file.\n * @param {Function} [whileLoading] Name of a function to call while file is loading.\n * This function will receive the percentage loaded\n * so far, from 0.0 to 1.0.\n * @return {SoundFile} Returns a p5.SoundFile\n * @example\n *
\n */\n p5.prototype.loadSound = function(path, callback, onerror, whileLoading) {\n // if loading locally without a server\n if (window.location.origin.indexOf('file://') > -1 && window.cordova === 'undefined' ) {\n window.alert('This sketch may require a server to load external files. Please see http://bit.ly/1qcInwS');\n }\n\n var self = this;\n var s = new p5.SoundFile(path, function() {\n if(typeof callback === 'function') {\n callback.apply(self, arguments);\n }\n\n if (typeof self._decrementPreload === 'function') {\n self._decrementPreload();\n }\n }, onerror, whileLoading);\n\n return s;\n };\n\n /**\n * This is a helper function that the p5.SoundFile calls to load\n * itself. Accepts a callback (the name of another function)\n * as an optional parameter.\n *\n * @private\n * @for p5.SoundFile\n * @param {Function} [successCallback] Name of a function to call once file loads\n * @param {Function} [errorCallback] Name of a function to call if there is an error\n */\n p5.SoundFile.prototype.load = function(callback, errorCallback) {\n var self = this;\n var errorTrace = new Error().stack;\n\n if (this.url !== undefined && this.url !== '') {\n var request = new XMLHttpRequest();\n request.addEventListener('progress', function(evt) {\n self._updateProgress(evt);\n }, false);\n request.open('GET', this.url, true);\n request.responseType = 'arraybuffer';\n\n request.onload = function() {\n if (request.status === 200) {\n // on sucess loading file:\n if (!self.panner) return;\n ac.decodeAudioData(request.response,\n // success decoding buffer:\n function(buff) {\n if (!self.panner) return;\n self.buffer = buff;\n self.panner.inputChannels(buff.numberOfChannels);\n if (callback) {\n callback(self);\n }\n },\n // error decoding buffer. \"e\" is undefined in Chrome 11/22/2015\n function() {\n if (!self.panner) return;\n var err = new CustomError('decodeAudioData', errorTrace, self.url);\n var msg = 'AudioContext error at decodeAudioData for ' + self.url;\n if (errorCallback) {\n err.msg = msg;\n errorCallback(err);\n } else {\n console.error(msg +'\\n The error stack trace includes: \\n' + err.stack);\n }\n }\n );\n }\n // if request status != 200, it failed\n else {\n if (!self.panner) return;\n var err = new CustomError('loadSound', errorTrace, self.url);\n var msg = 'Unable to load ' + self.url + '. The request status was: ' +\n request.status + ' (' + request.statusText + ')';\n\n if (errorCallback) {\n err.message = msg;\n errorCallback(err);\n } else {\n console.error(msg +'\\n The error stack trace includes: \\n' + err.stack);\n }\n }\n };\n\n // if there is another error, aside from 404...\n request.onerror = function() {\n var err = new CustomError('loadSound', errorTrace, self.url);\n var msg = 'There was no response from the server at ' + self.url + '. Check the url and internet connectivity.';\n\n if (errorCallback) {\n err.message = msg;\n errorCallback(err);\n } else {\n console.error(msg +'\\n The error stack trace includes: \\n' + err.stack);\n }\n };\n\n request.send();\n }\n else if (this.file !== undefined) {\n var reader = new FileReader();\n reader.onload = function() {\n if (!self.panner) return;\n ac.decodeAudioData(reader.result, function(buff) {\n if (!self.panner) return;\n self.buffer = buff;\n self.panner.inputChannels(buff.numberOfChannels);\n if (callback) {\n callback(self);\n }\n });\n };\n reader.onerror = function(e) {\n if (!self.panner) return;\n if (onerror) {\n onerror(e);\n }\n };\n reader.readAsArrayBuffer(this.file);\n }\n };\n\n // TO DO: use this method to create a loading bar that shows progress during file upload/decode.\n p5.SoundFile.prototype._updateProgress = function(evt) {\n if (evt.lengthComputable) {\n var percentComplete = evt.loaded / evt.total * 0.99;\n this._whileLoading(percentComplete, evt);\n // ...\n } else {\n // Unable to compute progress information since the total size is unknown\n this._whileLoading('size unknown');\n }\n };\n\n /**\n * Returns true if the sound file finished loading successfully.\n *\n * @method isLoaded\n * @for p5.SoundFile\n * @return {Boolean}\n */\n p5.SoundFile.prototype.isLoaded = function() {\n if (this.buffer) {\n return true;\n } else {\n return false;\n }\n };\n\n /**\n * Play the p5.SoundFile\n *\n * @method play\n * @for p5.SoundFile\n * @param {Number} [startTime] (optional) schedule playback to start (in seconds from now).\n * @param {Number} [rate] (optional) playback rate\n * @param {Number} [amp] (optional) amplitude (volume)\n * of playback\n * @param {Number} [cueStart] (optional) cue start time in seconds\n * @param {Number} [duration] (optional) duration of playback in seconds\n */\n p5.SoundFile.prototype.play = function(startTime, rate, amp, _cueStart, duration) {\n if (!this.output) {\n console.warn('SoundFile.play() called after dispose');\n return;\n }\n\n var now = p5sound.audiocontext.currentTime;\n var cueStart, cueEnd;\n var time = startTime || 0;\n if (time < 0) {\n time = 0;\n }\n\n time = time + now;\n\n if (typeof rate !== 'undefined') {\n this.rate(rate);\n }\n\n if (typeof amp !== 'undefined') {\n this.setVolume(amp);\n }\n\n // TO DO: if already playing, create array of buffers for easy stop()\n if (this.buffer) {\n // reset the pause time (if it was paused)\n this._pauseTime = 0;\n\n // handle restart playmode\n if (this.mode === 'restart' && this.buffer && this.bufferSourceNode) {\n this.bufferSourceNode.stop(time);\n this._counterNode.stop(time);\n }\n\n //dont create another instance if already playing\n if (this.mode === 'untildone' && this.isPlaying()) {\n return;\n }\n // make a new source and counter. They are automatically assigned playbackRate and buffer\n this.bufferSourceNode = this._initSourceNode();\n\n // garbage collect counterNode and create a new one\n delete this._counterNode;\n this._counterNode = this._initCounterNode();\n\n if (_cueStart) {\n if (_cueStart >=0 && _cueStart < this.buffer.duration) {\n // this.startTime = cueStart;\n cueStart = _cueStart;\n } else { throw 'start time out of range'; }\n } else {\n cueStart = 0;\n }\n\n if (duration) {\n // if duration is greater than buffer.duration, just play entire file anyway rather than throw an error\n duration = duration <= this.buffer.duration - cueStart ? duration : this.buffer.duration;\n }\n\n // if it was paused, play at the pause position\n if (this._paused) {\n this.bufferSourceNode.start(time, this.pauseTime, duration);\n this._counterNode.start(time, this.pauseTime, duration);\n } else {\n this.bufferSourceNode.start(time, cueStart, duration);\n this._counterNode.start(time, cueStart, duration);\n }\n\n this._playing = true;\n this._paused = false;\n\n // add source to sources array, which is used in stopAll()\n this.bufferSourceNodes.push(this.bufferSourceNode);\n this.bufferSourceNode._arrayIndex = this.bufferSourceNodes.length - 1;\n\n this.bufferSourceNode.addEventListener('ended', this._clearOnEnd);\n }\n // If soundFile hasn't loaded the buffer yet, throw an error\n else {\n throw 'not ready to play file, buffer has yet to load. Try preload()';\n }\n\n // if looping, will restart at original time\n this.bufferSourceNode.loop = this._looping;\n this._counterNode.loop = this._looping;\n\n if (this._looping === true) {\n cueEnd = duration ? duration : cueStart - 0.000000000000001;\n this.bufferSourceNode.loopStart = cueStart;\n this.bufferSourceNode.loopEnd = cueEnd;\n this._counterNode.loopStart = cueStart;\n this._counterNode.loopEnd = cueEnd;\n }\n\n };\n\n\n /**\n * p5.SoundFile has two play modes: restart and\n * sustain. Play Mode determines what happens to a\n * p5.SoundFile if it is triggered while in the middle of playback.\n * In sustain mode, playback will continue simultaneous to the\n * new playback. In restart mode, play() will stop playback\n * and start over. With untilDone, a sound will play only if it's\n * not already playing. Sustain is the default mode.\n *\n * @method playMode\n * @for p5.SoundFile\n * @param {String} str 'restart' or 'sustain' or 'untilDone'\n * @example\n *
\n * var mySound;\n * function preload(){\n * mySound = loadSound('assets/Damscray_DancingTiger.mp3');\n * }\n * function mouseClicked() {\n * mySound.playMode('sustain');\n * mySound.play();\n * }\n * function keyPressed() {\n * mySound.playMode('restart');\n * mySound.play();\n * }\n *\n *
\n */\n p5.SoundFile.prototype.playMode = function(str) {\n var s = str.toLowerCase();\n\n // if restart, stop all other sounds from playing\n if (s === 'restart' && this.buffer && this.bufferSourceNode) {\n for (var i = 0; i < this.bufferSourceNodes.length - 1; i++) {\n var now = p5sound.audiocontext.currentTime;\n this.bufferSourceNodes[i].stop(now);\n }\n }\n\n // set play mode to effect future playback\n if (s === 'restart' || s === 'sustain' || s === 'untildone') {\n this.mode = s;\n } else {\n throw 'Invalid play mode. Must be either \"restart\" or \"sustain\"';\n }\n };\n\n /**\n * Pauses a file that is currently playing. If the file is not\n * playing, then nothing will happen.\n *\n * After pausing, .play() will resume from the paused\n * position.\n * If p5.SoundFile had been set to loop before it was paused,\n * it will continue to loop after it is unpaused with .play().\n *\n * @method pause\n * @for p5.SoundFile\n * @param {Number} [startTime] (optional) schedule event to occur\n * seconds from now\n * @example\n *
\n */\n p5.SoundFile.prototype.pause = function(startTime) {\n var now = p5sound.audiocontext.currentTime;\n var time = startTime || 0;\n var pTime = time + now;\n\n if (this.isPlaying() && this.buffer && this.bufferSourceNode) {\n this._paused = true;\n this._playing = false;\n\n this.pauseTime = this.currentTime();\n this.bufferSourceNode.stop(pTime);\n this._counterNode.stop(pTime);\n\n this._pauseTime = this.currentTime();\n // TO DO: make sure play() still starts from orig start position\n } else {\n this._pauseTime = 0;\n }\n };\n\n /**\n * Loop the p5.SoundFile. Accepts optional parameters to set the\n * playback rate, playback volume, loopStart, loopEnd.\n *\n * @method loop\n * @for p5.SoundFile\n * @param {Number} [startTime] (optional) schedule event to occur\n * seconds from now\n * @param {Number} [rate] (optional) playback rate\n * @param {Number} [amp] (optional) playback volume\n * @param {Number} [cueLoopStart] (optional) startTime in seconds\n * @param {Number} [duration] (optional) loop duration in seconds\n */\n p5.SoundFile.prototype.loop = function(startTime, rate, amp, loopStart, duration) {\n this._looping = true;\n this.play(startTime, rate, amp, loopStart, duration);\n };\n\n /**\n * Set a p5.SoundFile's looping flag to true or false. If the sound\n * is currently playing, this change will take effect when it\n * reaches the end of the current playback.\n *\n * @method setLoop\n * @for p5.SoundFile\n * @param {Boolean} Boolean set looping to true or false\n */\n p5.SoundFile.prototype.setLoop = function(bool) {\n if (bool === true) {\n this._looping = true;\n }\n else if (bool === false) {\n this._looping = false;\n }\n else {\n throw 'Error: setLoop accepts either true or false';\n }\n if (this.bufferSourceNode) {\n this.bufferSourceNode.loop = this._looping;\n this._counterNode.loop = this._looping;\n }\n };\n\n /**\n * Returns 'true' if a p5.SoundFile is currently looping and playing, 'false' if not.\n *\n * @method isLooping\n * @for p5.SoundFile\n * @return {Boolean}\n */\n p5.SoundFile.prototype.isLooping = function() {\n if (!this.bufferSourceNode) {\n return false;\n }\n if (this._looping === true && this.isPlaying() === true) {\n return true;\n }\n return false;\n };\n\n /**\n * Returns true if a p5.SoundFile is playing, false if not (i.e.\n * paused or stopped).\n *\n * @method isPlaying\n * @for p5.SoundFile\n * @return {Boolean}\n */\n p5.SoundFile.prototype.isPlaying = function() {\n return this._playing;\n };\n\n /**\n * Returns true if a p5.SoundFile is paused, false if not (i.e.\n * playing or stopped).\n *\n * @method isPaused\n * @for p5.SoundFile\n * @return {Boolean}\n */\n p5.SoundFile.prototype.isPaused = function() {\n return this._paused;\n };\n\n /**\n * Stop soundfile playback.\n *\n * @method stop\n * @for p5.SoundFile\n * @param {Number} [startTime] (optional) schedule event to occur\n * in seconds from now\n */\n p5.SoundFile.prototype.stop = function(timeFromNow) {\n var time = timeFromNow || 0;\n\n if (this.mode === 'sustain' || this.mode === 'untildone') {\n this.stopAll(time);\n this._playing = false;\n this.pauseTime = 0;\n this._paused = false;\n }\n else if (this.buffer && this.bufferSourceNode) {\n var now = p5sound.audiocontext.currentTime;\n var t = time || 0;\n this.pauseTime = 0;\n this.bufferSourceNode.stop(now + t);\n this._counterNode.stop(now + t);\n this._playing = false;\n this._paused = false;\n }\n };\n\n /**\n * Stop playback on all of this soundfile's sources.\n * @private\n */\n p5.SoundFile.prototype.stopAll = function(_time) {\n var now = p5sound.audiocontext.currentTime;\n var time = _time || 0;\n if (this.buffer && this.bufferSourceNode) {\n for (var i in this.bufferSourceNodes) {\n const bufferSourceNode = this.bufferSourceNodes[i];\n if (!!bufferSourceNode) {\n try {\n bufferSourceNode.stop(now + time);\n } catch(e) {\n // this was throwing errors only on Safari\n }\n }\n }\n this._counterNode.stop(now + time);\n this._onended(this);\n }\n };\n\n /**\n * Multiply the output volume (amplitude) of a sound file\n * between 0.0 (silence) and 1.0 (full volume).\n * 1.0 is the maximum amplitude of a digital sound, so multiplying\n * by greater than 1.0 may cause digital distortion. To\n * fade, provide a rampTime parameter. For more\n * complex fades, see the Envelope class.\n *\n * Alternately, you can pass in a signal source such as an\n * oscillator to modulate the amplitude with an audio signal.\n *\n * @method setVolume\n * @for p5.SoundFile\n * @param {Number|Object} volume Volume (amplitude) between 0.0\n * and 1.0 or modulating signal/oscillator\n * @param {Number} [rampTime] Fade for t seconds\n * @param {Number} [timeFromNow] Schedule this event to happen at\n * t seconds in the future\n */\n p5.SoundFile.prototype.setVolume = function(vol, _rampTime, _tFromNow) {\n if (typeof vol === 'number') {\n var rampTime = _rampTime || 0;\n var tFromNow = _tFromNow || 0;\n var now = p5sound.audiocontext.currentTime;\n var currentVol = this.output.gain.value;\n this.output.gain.cancelScheduledValues(now + tFromNow);\n this.output.gain.linearRampToValueAtTime(currentVol, now + tFromNow);\n this.output.gain.linearRampToValueAtTime(vol, now + tFromNow + rampTime);\n }\n else if (vol) {\n vol.connect(this.output.gain);\n } else {\n // return the Gain Node\n return this.output.gain;\n }\n };\n\n // same as setVolume, to match Processing Sound\n p5.SoundFile.prototype.amp = p5.SoundFile.prototype.setVolume;\n\n // these are the same thing\n p5.SoundFile.prototype.fade = p5.SoundFile.prototype.setVolume;\n\n p5.SoundFile.prototype.getVolume = function() {\n return this.output.gain.value;\n };\n\n /**\n * Set the stereo panning of a p5.sound object to\n * a floating point number between -1.0 (left) and 1.0 (right).\n * Default is 0.0 (center).\n *\n * @method pan\n * @for p5.SoundFile\n * @param {Number} [panValue] Set the stereo panner\n * @param {Number} [timeFromNow] schedule this event to happen\n * seconds from now\n * @example\n *
\n *\n * var ball = {};\n * var soundFile;\n *\n * function preload() {\n * soundFormats('ogg', 'mp3');\n * soundFile = loadSound('assets/beatbox.mp3');\n * }\n *\n * function draw() {\n * background(0);\n * ball.x = constrain(mouseX, 0, width);\n * ellipse(ball.x, height/2, 20, 20)\n * }\n *\n * function mousePressed(){\n * // map the ball's x location to a panning degree\n * // between -1.0 (left) and 1.0 (right)\n * var panning = map(ball.x, 0., width,-1.0, 1.0);\n * soundFile.pan(panning);\n * soundFile.play();\n * }\n *
\n */\n p5.SoundFile.prototype.pan = function(pval, tFromNow) {\n this.panPosition = pval;\n this.panner.pan(pval, tFromNow);\n };\n\n /**\n * Returns the current stereo pan position (-1.0 to 1.0)\n *\n * @method getPan\n * @for p5.SoundFile\n * @return {Number} Returns the stereo pan setting of the Oscillator\n * as a number between -1.0 (left) and 1.0 (right).\n * 0.0 is center and default.\n */\n p5.SoundFile.prototype.getPan = function() {\n return this.panPosition;\n };\n\n /**\n * Set the playback rate of a sound file. Will change the speed and the pitch.\n * Values less than zero will reverse the audio buffer.\n *\n * @method rate\n * @for p5.SoundFile\n * @param {Number} [playbackRate] Set the playback rate. 1.0 is normal,\n * .5 is half-speed, 2.0 is twice as fast.\n * Values less than zero play backwards.\n * @example\n *
\n * var song;\n *\n * function preload() {\n * song = loadSound('assets/Damscray_DancingTiger.mp3');\n * }\n *\n * function setup() {\n * song.loop();\n * }\n *\n * function draw() {\n * background(200);\n *\n * // Set the rate to a range between 0.1 and 4\n * // Changing the rate also alters the pitch\n * var speed = map(mouseY, 0.1, height, 0, 2);\n * speed = constrain(speed, 0.01, 4);\n * song.rate(speed);\n *\n * // Draw a circle to show what is going on\n * stroke(0);\n * fill(51, 100);\n * ellipse(mouseX, 100, 48, 48);\n * }\n *\n * \n *
\n *\n */\n p5.SoundFile.prototype.rate = function(playbackRate) {\n var reverse = false;\n if (typeof playbackRate === 'undefined') {\n return this.playbackRate;\n }\n\n this.playbackRate = playbackRate;\n\n if (playbackRate === 0) {\n playbackRate = 0.0000000000001;\n }\n\n else if (playbackRate < 0 && !this.reversed) {\n playbackRate = Math.abs(playbackRate);\n reverse = true;\n }\n\n else if (playbackRate > 0 && this.reversed) {\n reverse = true;\n }\n\n if (this.bufferSourceNode) {\n var now = p5sound.audiocontext.currentTime;\n this.bufferSourceNode.playbackRate.cancelScheduledValues(now);\n this.bufferSourceNode.playbackRate.linearRampToValueAtTime(Math.abs(playbackRate), now);\n this._counterNode.playbackRate.cancelScheduledValues(now);\n this._counterNode.playbackRate.linearRampToValueAtTime(Math.abs(playbackRate), now);\n }\n\n if (reverse) {\n this.reverseBuffer();\n }\n return this.playbackRate;\n };\n\n // TO DO: document this\n p5.SoundFile.prototype.setPitch = function(num) {\n var newPlaybackRate = midiToFreq(num) / midiToFreq(60);\n this.rate(newPlaybackRate);\n };\n\n p5.SoundFile.prototype.getPlaybackRate = function() {\n return this.playbackRate;\n };\n\n /**\n * Returns the duration of a sound file in seconds.\n *\n * @method duration\n * @for p5.SoundFile\n * @return {Number} The duration of the soundFile in seconds.\n */\n p5.SoundFile.prototype.duration = function() {\n // Return Duration\n if (this.buffer) {\n return this.buffer.duration;\n } else {\n return 0;\n }\n };\n\n /**\n * Return the current position of the p5.SoundFile playhead, in seconds.\n * Time is relative to the normal buffer direction, so if `reverseBuffer`\n * has been called, currentTime will count backwards.\n *\n * @method currentTime\n * @for p5.SoundFile\n * @return {Number} currentTime of the soundFile in seconds.\n */\n p5.SoundFile.prototype.currentTime = function() {\n return this.reversed\n ? Math.abs(this._lastPos - this.buffer.length) / ac.sampleRate\n : this._lastPos / ac.sampleRate;\n };\n\n /**\n * Move the playhead of the song to a position, in seconds. Start timing\n * and playback duration. If none are given, will reset the file to play\n * entire duration from start to finish.\n *\n * @method jump\n * @for p5.SoundFile\n * @param {Number} cueTime cueTime of the soundFile in seconds.\n * @param {Number} duration duration in seconds.\n */\n p5.SoundFile.prototype.jump = function(cueTime, duration) {\n if (cueTime < 0 || cueTime > this.buffer.duration) {\n throw 'jump time out of range';\n }\n if (duration > this.buffer.duration - cueTime) {\n throw 'end time out of range';\n }\n\n var cTime = cueTime || 0;\n var dur = duration || undefined;\n if (this.isPlaying()) {\n this.stop(0);\n }\n this.play(0, this.playbackRate, this.output.gain.value, cTime, dur);\n };\n\n /**\n * Return the number of channels in a sound file.\n * For example, Mono = 1, Stereo = 2.\n *\n * @method channels\n * @for p5.SoundFile\n * @return {Number} [channels]\n */\n p5.SoundFile.prototype.channels = function() {\n return this.buffer.numberOfChannels;\n };\n\n /**\n * Return the sample rate of the sound file.\n *\n * @method sampleRate\n * @for p5.SoundFile\n * @return {Number} [sampleRate]\n */\n p5.SoundFile.prototype.sampleRate = function() {\n return this.buffer.sampleRate;\n };\n\n /**\n * Return the number of samples in a sound file.\n * Equal to sampleRate * duration.\n *\n * @method frames\n * @for p5.SoundFile\n * @return {Number} [sampleCount]\n */\n p5.SoundFile.prototype.frames = function() {\n return this.buffer.length;\n };\n\n /**\n * Returns an array of amplitude peaks in a p5.SoundFile that can be\n * used to draw a static waveform. Scans through the p5.SoundFile's\n * audio buffer to find the greatest amplitudes. Accepts one\n * parameter, 'length', which determines size of the array.\n * Larger arrays result in more precise waveform visualizations.\n *\n * Inspired by Wavesurfer.js.\n *\n * @method getPeaks\n * @for p5.SoundFile\n * @params {Number} [length] length is the size of the returned array.\n * Larger length results in more precision.\n * Defaults to 5*width of the browser window.\n * @returns {Float32Array} Array of peaks.\n */\n p5.SoundFile.prototype.getPeaks = function(length) {\n\n if (this.buffer) {\n // set length to window's width if no length is provided\n if (!length) {\n length = window.width*5;\n }\n if (this.buffer) {\n var buffer = this.buffer;\n var sampleSize = buffer.length / length;\n var sampleStep = ~~(sampleSize / 10) || 1;\n var channels = buffer.numberOfChannels;\n var peaks = new Float32Array(Math.round(length));\n\n for (var c = 0; c < channels; c++) {\n var chan = buffer.getChannelData(c);\n for (var i = 0; i < length; i++) {\n var start = ~~(i*sampleSize);\n var end = ~~(start + sampleSize);\n var max = 0;\n for (var j = start; j < end; j+= sampleStep) {\n var value = chan[j];\n if (value > max) {\n max = value;\n // faster than Math.abs\n } else if (-value > max) {\n max = value;\n }\n }\n if (c === 0 || Math.abs(max) > peaks[i]) {\n peaks[i] = max;\n }\n }\n }\n\n return peaks;\n }\n }\n\n else {\n throw 'Cannot load peaks yet, buffer is not loaded';\n }\n };\n\n /**\n * Reverses the p5.SoundFile's buffer source.\n * Playback must be handled separately (see example).\n *\n * @method reverseBuffer\n * @for p5.SoundFile\n * @example\n *
\n * var drum;\n *\n * function preload() {\n * drum = loadSound('assets/drum.mp3');\n * }\n *\n * function setup() {\n * drum.reverseBuffer();\n * drum.play();\n * }\n *\n * \n *
\n */\n p5.SoundFile.prototype.reverseBuffer = function() {\n if (this.buffer) {\n var currentPos = this._lastPos / ac.sampleRate;\n var curVol = this.getVolume();\n this.setVolume(0, 0.001);\n\n const numChannels = this.buffer.numberOfChannels;\n for (var i = 0; i < numChannels; i++) {\n this.buffer.getChannelData(i).reverse();\n }\n // set reversed flag\n this.reversed = !this.reversed;\n\n if (currentPos) {\n this.jump(this.duration() - currentPos);\n }\n this.setVolume(curVol, 0.001);\n } else {\n throw 'SoundFile is not done loading';\n }\n };\n\n /**\n * Schedule an event to be called when the soundfile\n * reaches the end of a buffer. If the soundfile is\n * playing through once, this will be called when it\n * ends. If it is looping, it will be called when\n * stop is called.\n *\n * @method onended\n * @for p5.SoundFile\n * @param {Function} callback function to call when the\n * soundfile has ended.\n */\n p5.SoundFile.prototype.onended = function(callback) {\n this._onended = callback;\n return this;\n };\n\n p5.SoundFile.prototype.add = function() {\n // TO DO\n };\n\n p5.SoundFile.prototype.dispose = function() {\n var now = p5sound.audiocontext.currentTime;\n\n // remove reference to soundfile\n var index = p5sound.soundArray.indexOf(this);\n p5sound.soundArray.splice(index, 1);\n\n this.stop(now);\n if (this.buffer && this.bufferSourceNode) {\n for (var i = 0; i < this.bufferSourceNodes.length - 1; i++) {\n if (this.bufferSourceNodes[i] !== null) {\n this.bufferSourceNodes[i].disconnect();\n try {\n this.bufferSourceNodes[i].stop(now);\n } catch(e) {\n console.warning('no buffer source node to dispose');\n }\n this.bufferSourceNodes[i] = null;\n }\n }\n if ( this.isPlaying() ) {\n try {\n this._counterNode.stop(now);\n } catch(e) {\n console.log(e);\n }\n this._counterNode = null;\n }\n }\n if (this.output) {\n this.output.disconnect();\n this.output = null;\n }\n if (this.panner) {\n this.panner.disconnect();\n this.panner = null;\n }\n };\n\n /**\n * Connects the output of a p5sound object to input of another\n * p5.sound object. For example, you may connect a p5.SoundFile to an\n * FFT or an Effect. If no parameter is given, it will connect to\n * the master output. Most p5sound objects connect to the master\n * output when they are created.\n *\n * @method connect\n * @for p5.SoundFile\n * @param {Object} [object] Audio object that accepts an input\n */\n p5.SoundFile.prototype.connect = function(unit) {\n if (!unit) {\n this.panner.connect(p5sound.input);\n }\n else {\n if (unit.hasOwnProperty('input')) {\n this.panner.connect(unit.input);\n } else {\n this.panner.connect(unit);\n }\n }\n };\n\n /**\n * Disconnects the output of this p5sound object.\n *\n * @method disconnect\n * @for p5.SoundFile\n */\n p5.SoundFile.prototype.disconnect = function() {\n if (this.panner) {\n this.panner.disconnect();\n }\n };\n\n /**\n */\n p5.SoundFile.prototype.getLevel = function() {\n console.warn('p5.SoundFile.getLevel has been removed from the library. Use p5.Amplitude instead');\n };\n\n /**\n * Reset the source for this SoundFile to a\n * new path (URL).\n *\n * @method setPath\n * @for p5.SoundFile\n * @param {String} path path to audio file\n * @param {Function} callback Callback\n */\n p5.SoundFile.prototype.setPath = function(p, callback) {\n var path = p5.prototype._checkFileFormats(p);\n this.url = path;\n this.load(callback);\n };\n\n /**\n * Replace the current Audio Buffer with a new Buffer.\n *\n * @method setBuffer\n * @for p5.SoundFile\n * @param {Array} buf Array of Float32 Array(s). 2 Float32 Arrays\n * will create a stereo source. 1 will create\n * a mono source.\n */\n p5.SoundFile.prototype.setBuffer = function(buf) {\n var numChannels = buf.length;\n var size = buf[0].length;\n var newBuffer = ac.createBuffer(numChannels, size, ac.sampleRate);\n\n if (!(buf[0] instanceof Float32Array)) {\n buf[0] = new Float32Array(buf[0]);\n }\n\n for (var channelNum = 0; channelNum < numChannels; channelNum++) {\n var channel = newBuffer.getChannelData( channelNum );\n channel.set(buf[channelNum]);\n }\n\n this.buffer = newBuffer;\n\n // set numbers of channels on input to the panner\n this.panner.inputChannels(numChannels);\n };\n\n //////////////////////////////////////////////////\n // script processor node with an empty buffer to help\n // keep a sample-accurate position in playback buffer.\n // Inspired by Chinmay Pendharkar's technique for Sonoport --> http://bit.ly/1HwdCsV\n // Copyright [2015] [Sonoport (Asia) Pte. Ltd.],\n // Licensed under the Apache License http://apache.org/licenses/LICENSE-2.0\n ////////////////////////////////////////////////////////////////////////////////////\n\n var _createCounterBuffer = function(buffer) {\n const len = buffer.length;\n const audioBuf = ac.createBuffer( 1, buffer.length, ac.sampleRate );\n const arrayBuffer = audioBuf.getChannelData(0);\n for (var index = 0; index < len; index++) {\n arrayBuffer[index] = index;\n }\n return audioBuf;\n };\n\n // initialize counterNode, set its initial buffer and playbackRate\n p5.SoundFile.prototype._initCounterNode = function() {\n var self = this;\n var now = ac.currentTime;\n var cNode = ac.createBufferSource();\n\n // dispose of worklet node if it already exists\n if (self._workletNode) {\n self._workletNode.disconnect();\n delete self._workletNode;\n }\n self._workletNode = new AudioWorkletNode(ac, processorNames.soundFileProcessor);\n self._workletNode.port.onmessage = event => {\n if (event.data.name === 'position') {\n // event.data.position should only be 0 when paused\n if (event.data.position === 0) {\n return;\n }\n this._lastPos = event.data.position;\n\n // do any callbacks that have been scheduled\n this._onTimeUpdate(self._lastPos);\n }\n };\n\n // create counter buffer of the same length as self.buffer\n cNode.buffer = _createCounterBuffer( self.buffer );\n\n cNode.playbackRate.setValueAtTime(self.playbackRate, now);\n\n cNode.connect(self._workletNode);\n self._workletNode.connect(p5.soundOut._silentNode);\n\n return cNode;\n };\n\n // initialize sourceNode, set its initial buffer and playbackRate\n p5.SoundFile.prototype._initSourceNode = function() {\n var bufferSourceNode = ac.createBufferSource();\n bufferSourceNode.buffer = this.buffer;\n bufferSourceNode.playbackRate.value = this.playbackRate;\n bufferSourceNode.connect(this.output);\n return bufferSourceNode;\n };\n\n /**\n * processPeaks returns an array of timestamps where it thinks there is a beat.\n *\n * This is an asynchronous function that processes the soundfile in an offline audio context,\n * and sends the results to your callback function.\n *\n * The process involves running the soundfile through a lowpass filter, and finding all of the\n * peaks above the initial threshold. If the total number of peaks are below the minimum number of peaks,\n * it decreases the threshold and re-runs the analysis until either minPeaks or minThreshold are reached.\n *\n * @method processPeaks\n * @for p5.SoundFile\n * @param {Function} callback a function to call once this data is returned\n * @param {Number} [initThreshold] initial threshold defaults to 0.9\n * @param {Number} [minThreshold] minimum threshold defaults to 0.22\n * @param {Number} [minPeaks] minimum number of peaks defaults to 200\n * @return {Array} Array of timestamped peaks\n */\n p5.SoundFile.prototype.processPeaks = function(callback, _initThreshold, _minThreshold, _minPeaks) {\n var bufLen = this.buffer.length;\n var sampleRate = this.buffer.sampleRate;\n var buffer = this.buffer;\n var allPeaks = [];\n\n var initialThreshold = _initThreshold || 0.9,\n threshold = initialThreshold,\n minThreshold = _minThreshold || 0.22,\n minPeaks = _minPeaks || 200;\n\n // Create offline context\n var offlineContext = new window.OfflineAudioContext(1, bufLen, sampleRate);\n\n // create buffer source\n var source = offlineContext.createBufferSource();\n source.buffer = buffer;\n\n // Create filter. TO DO: allow custom setting of filter\n var filter = offlineContext.createBiquadFilter();\n filter.type = 'lowpass';\n source.connect(filter);\n filter.connect(offlineContext.destination);\n\n // start playing at time:0\n source.start(0);\n offlineContext.startRendering(); // Render the song\n\n // act on the result\n offlineContext.oncomplete = function(e) {\n if (!self.panner) return;\n var filteredBuffer = e.renderedBuffer;\n var bufferData = filteredBuffer.getChannelData(0);\n\n\n // step 1:\n // create Peak instances, add them to array, with strength and sampleIndex\n do {\n allPeaks = getPeaksAtThreshold(bufferData, threshold);\n threshold -= 0.005;\n } while (Object.keys(allPeaks).length < minPeaks && threshold >= minThreshold);\n\n\n // step 2:\n // find intervals for each peak in the sampleIndex, add tempos array\n var intervalCounts = countIntervalsBetweenNearbyPeaks(allPeaks);\n\n // step 3: find top tempos\n var groups = groupNeighborsByTempo(intervalCounts, filteredBuffer.sampleRate);\n\n // sort top intervals\n var topTempos = groups.sort(function(intA, intB) {\n return intB.count - intA.count;\n\n }).splice(0,5);\n\n // set this SoundFile's tempo to the top tempo ??\n this.tempo = topTempos[0].tempo;\n\n // step 4:\n // new array of peaks at top tempo within a bpmVariance\n var bpmVariance = 5;\n var tempoPeaks = getPeaksAtTopTempo(allPeaks, topTempos[0].tempo, filteredBuffer.sampleRate, bpmVariance);\n\n callback(tempoPeaks);\n };\n };\n\n // process peaks\n var Peak = function(amp, i) {\n this.sampleIndex = i;\n this.amplitude = amp;\n this.tempos = [];\n this.intervals = [];\n };\n\n // 1. for processPeaks() Function to identify peaks above a threshold\n // returns an array of peak indexes as frames (samples) of the original soundfile\n function getPeaksAtThreshold(data, threshold) {\n var peaksObj = {};\n var length = data.length;\n\n for (var i = 0; i < length; i++) {\n if (data[i] > threshold) {\n var amp = data[i];\n var peak = new Peak(amp, i);\n peaksObj[i] = peak;\n // Skip forward ~ 1/8s to get past this peak.\n i += 6000;\n }\n i++;\n }\n return peaksObj;\n }\n\n // 2. for processPeaks()\n function countIntervalsBetweenNearbyPeaks(peaksObj) {\n var intervalCounts = [];\n var peaksArray = Object.keys(peaksObj).sort();\n\n for (var index = 0; index < peaksArray.length; index++) {\n\n // find intervals in comparison to nearby peaks\n for (var i = 0; i < 10; i++) {\n var startPeak = peaksObj[peaksArray[index]];\n var endPeak = peaksObj[peaksArray[index + i]];\n\n if (startPeak && endPeak) {\n var startPos = startPeak.sampleIndex;\n var endPos = endPeak.sampleIndex;\n var interval = endPos - startPos;\n\n // add a sample interval to the startPeak in the allPeaks array\n if (interval > 0) {\n startPeak.intervals.push(interval);\n }\n\n // tally the intervals and return interval counts\n var foundInterval = intervalCounts.some(function(intervalCount) {\n if (intervalCount.interval === interval) {\n intervalCount.count++;\n return intervalCount;\n }\n });\n\n // store with JSON like formatting\n if (!foundInterval) {\n intervalCounts.push({\n interval: interval,\n count: 1,\n });\n }\n }\n }\n }\n\n return intervalCounts;\n }\n\n\n // 3. for processPeaks --> find tempo\n function groupNeighborsByTempo(intervalCounts, sampleRate) {\n var tempoCounts = [];\n\n intervalCounts.forEach(function(intervalCount) {\n\n try {\n // Convert an interval to tempo\n var theoreticalTempo = Math.abs( 60 / (intervalCount.interval / sampleRate ) );\n\n theoreticalTempo = mapTempo(theoreticalTempo);\n\n var foundTempo = tempoCounts.some(function(tempoCount) {\n if (tempoCount.tempo === theoreticalTempo)\n return tempoCount.count += intervalCount.count;\n });\n if (!foundTempo) {\n if (isNaN(theoreticalTempo)) {\n return;\n }\n tempoCounts.push({\n tempo: Math.round(theoreticalTempo),\n count: intervalCount.count\n });\n }\n } catch(e) {\n throw e;\n }\n\n });\n\n return tempoCounts;\n }\n\n // 4. for processPeaks - get peaks at top tempo\n function getPeaksAtTopTempo(peaksObj, tempo, sampleRate, bpmVariance) {\n var peaksAtTopTempo = [];\n var peaksArray = Object.keys(peaksObj).sort();\n\n // TO DO: filter out peaks that have the tempo and return\n for (var i = 0; i < peaksArray.length; i++) {\n var key = peaksArray[i];\n var peak = peaksObj[key];\n\n for (var j = 0; j < peak.intervals.length; j++) {\n var intervalBPM = Math.round(Math.abs( 60 / (peak.intervals[j] / sampleRate) ) );\n\n intervalBPM = mapTempo(intervalBPM);\n\n if ( Math.abs(intervalBPM - tempo) < bpmVariance ) {\n // convert sampleIndex to seconds\n peaksAtTopTempo.push(peak.sampleIndex/sampleRate);\n }\n }\n }\n\n // filter out peaks that are very close to each other\n peaksAtTopTempo = peaksAtTopTempo.filter(function(peakTime, index, arr) {\n var dif = arr[index + 1] - peakTime;\n if (dif > 0.01) {\n return true;\n }\n });\n\n return peaksAtTopTempo;\n }\n\n // helper function for processPeaks\n function mapTempo(theoreticalTempo) {\n // these scenarios create infinite while loop\n if (!isFinite(theoreticalTempo) || theoreticalTempo === 0 ) {\n return;\n }\n\n // Adjust the tempo to fit within the 90-180 BPM range\n while (theoreticalTempo < 90) theoreticalTempo *= 2;\n while (theoreticalTempo > 180 && theoreticalTempo > 90) theoreticalTempo /= 2;\n\n return theoreticalTempo;\n }\n\n\n /*** SCHEDULE EVENTS ***/\n\n // Cue inspired by JavaScript setTimeout, and the\n // Tone.js Transport Timeline Event, MIT License Yotam Mann 2015 tonejs.org\n var Cue = function(callback, time, id, val) {\n this.callback = callback;\n this.time = time;\n this.id = id;\n this.val = val;\n };\n\n /**\n * Schedule events to trigger every time a MediaElement\n * (audio/video) reaches a playback cue point.\n *\n * Accepts a callback function, a time (in seconds) at which to trigger\n * the callback, and an optional parameter for the callback.\n *\n * Time will be passed as the first parameter to the callback function,\n * and param will be the second parameter.\n *\n *\n * @method addCue\n * @for p5.SoundFile\n * @param {Number} time Time in seconds, relative to this media\n * element's playback. For example, to trigger\n * an event every time playback reaches two\n * seconds, pass in the number 2. This will be\n * passed as the first parameter to\n * the callback function.\n * @param {Function} callback Name of a function that will be\n * called at the given time. The callback will\n * receive time and (optionally) param as its\n * two parameters.\n * @param {Object} [value] An object to be passed as the\n * second parameter to the\n * callback function.\n * @return {Number} id ID of this cue,\n * useful for removeCue(id)\n * @example\n *
\n */\n p5.SoundFile.prototype.addCue = function(time, callback, val) {\n var id = this._cueIDCounter++;\n\n var cue = new Cue(callback, time, id, val);\n this._cues.push(cue);\n\n // if (!this.elt.ontimeupdate) {\n // this.elt.ontimeupdate = this._onTimeUpdate.bind(this);\n // }\n\n return id;\n };\n\n /**\n * Remove a callback based on its ID. The ID is returned by the\n * addCue method.\n *\n * @method removeCue\n * @for p5.SoundFile\n * @param {Number} id ID of the cue, as returned by addCue\n */\n p5.SoundFile.prototype.removeCue = function(id) {\n var cueLength = this._cues.length;\n for (var i = 0; i < cueLength; i++) {\n var cue = this._cues[i];\n if (cue.id === id) {\n this._cues.splice(i, 1);\n break;\n }\n }\n\n if (this._cues.length === 0) {\n // TO DO: remove callback\n // this.elt.ontimeupdate = null\n }\n };\n\n /**\n * Remove all of the callbacks that had originally been scheduled\n * via the addCue method.\n *\n * @method clearCues\n */\n p5.SoundFile.prototype.clearCues = function() {\n this._cues = [];\n // this.elt.ontimeupdate = null;\n };\n\n // private method that checks for cues to be fired if events\n // have been scheduled using addCue(callback, time).\n p5.SoundFile.prototype._onTimeUpdate = function(position) {\n var playbackTime = position/this.buffer.sampleRate;\n var cueLength = this._cues.length;\n\n for (var i = 0 ; i < cueLength; i++) {\n var cue = this._cues[i];\n var callbackTime = cue.time;\n var val = cue.val;\n\n if (this._prevTime < callbackTime && callbackTime <= playbackTime) {\n\n // pass the scheduled callbackTime as parameter to the callback\n cue.callback(val);\n }\n\n }\n\n this._prevTime = playbackTime;\n };\n\n /**\n * Save a p5.SoundFile as a .wav file. The browser will prompt the user\n * to download the file to their device. To upload a file to a server, see\n * getBlob\n *\n * @method save\n * @for p5.SoundFile\n * @param {String} [fileName] name of the resulting .wav file.\n * @example\n *
\n * var inp, button, mySound;\n * var fileName = 'cool';\n * function preload() {\n * mySound = loadSound('assets/doorbell.mp3');\n * }\n * function setup() {\n * btn = createButton('click to save file');\n * btn.position(0, 0);\n * btn.mouseClicked(handleMouseClick);\n * }\n *\n * function handleMouseClick() {\n * mySound.save(fileName);\n * }\n *
\n */\n p5.SoundFile.prototype.save = function(fileName) {\n const dataView = convertToWav(this.buffer);\n p5.prototype.saveSound([dataView], fileName, 'wav');\n };\n\n /**\n * This method is useful for sending a SoundFile to a server. It returns the\n * .wav-encoded audio data as a \"Blob\".\n * A Blob is a file-like data object that can be uploaded to a server\n * with an http request. We'll\n * use the `httpDo` options object to send a POST request with some\n * specific options: we encode the request as `multipart/form-data`,\n * and attach the blob as one of the form values using `FormData`.\n *\n *\n * @method getBlob\n * @for p5.SoundFile\n * @returns {Blob} A file-like data object\n * @example\n *
\n *\n * function preload() {\n * mySound = loadSound('assets/doorbell.mp3');\n * }\n *\n * function setup() {\n * noCanvas();\n * var soundBlob = mySound.getBlob();\n *\n * // Now we can send the blob to a server...\n * var serverUrl = 'https://jsonplaceholder.typicode.com/posts';\n * var httpRequestOptions = {\n * method: 'POST',\n * body: new FormData().append('soundBlob', soundBlob),\n * headers: new Headers({\n * 'Content-Type': 'multipart/form-data'\n * })\n * };\n * httpDo(serverUrl, httpRequestOptions);\n *\n * // We can also create an `ObjectURL` pointing to the Blob\n * var blobUrl = URL.createObjectURL(soundBlob);\n *\n * // The `
\n */\n p5.SoundFile.prototype.getBlob = function() {\n const dataView = convertToWav(this.buffer);\n return new Blob([dataView], { type: 'audio/wav' });\n };\n\n // event handler to remove references to the bufferSourceNode when it is done playing\n function _clearOnEnd(e) {\n const thisBufferSourceNode = e.target;\n const soundFile = this;\n\n // delete this.bufferSourceNode from the sources array when it is done playing:\n thisBufferSourceNode._playing = false;\n thisBufferSourceNode.removeEventListener('ended', soundFile._clearOnEnd);\n\n // call the onended callback\n soundFile._onended(soundFile);\n\n soundFile.bufferSourceNodes.forEach(function (n, i) {\n if (n._playing === false) {\n soundFile.bufferSourceNodes.splice(i);\n }\n });\n\n if (soundFile.bufferSourceNodes.length === 0) {\n soundFile._playing = false;\n }\n }\n});\n","'use strict';\n\ndefine(function (require) {\n var p5sound = require('master');\n var processorNames = require('./audioWorklet/processorNames');\n\n /**\n * Amplitude measures volume between 0.0 and 1.0.\n * Listens to all p5sound by default, or use setInput()\n * to listen to a specific sound source. Accepts an optional\n * smoothing value, which defaults to 0.\n *\n * @class p5.Amplitude\n * @constructor\n * @param {Number} [smoothing] between 0.0 and .999 to smooth\n * amplitude readings (defaults to 0)\n * @example\n *
\n * var sound, amplitude, cnv;\n *\n * function preload(){\n * sound = loadSound('assets/beat.mp3');\n * }\n * function setup() {\n * cnv = createCanvas(100,100);\n * amplitude = new p5.Amplitude();\n *\n * // start / stop the sound when canvas is clicked\n * cnv.mouseClicked(function() {\n * if (sound.isPlaying() ){\n * sound.stop();\n * } else {\n * sound.play();\n * }\n * });\n * }\n * function draw() {\n * background(0);\n * fill(255);\n * var level = amplitude.getLevel();\n * var size = map(level, 0, 1, 0, 200);\n * ellipse(width/2, height/2, size, size);\n * }\n *\n *
\n */\n p5.Amplitude = function(smoothing) {\n\n // Set to 2048 for now. In future iterations, this should be inherited or parsed from p5sound's default\n this.bufferSize = 2048;\n\n // set audio context\n this.audiocontext = p5sound.audiocontext;\n this._workletNode = new AudioWorkletNode(this.audiocontext, processorNames.amplitudeProcessor, {\n outputChannelCount: [1],\n processorOptions: {\n normalize: false,\n smoothing: smoothing || 0\n }\n });\n\n this._workletNode.port.onmessage = function(event) {\n if (event.data.name === 'amplitude') {\n this.volume = event.data.volume;\n this.volNorm = event.data.volNorm;\n this.stereoVol = event.data.stereoVol;\n this.stereoVolNorm = event.data.stereoVolNorm;\n }\n }.bind(this);\n\n // for connections\n this.input = this._workletNode;\n\n this.output = this.audiocontext.createGain();\n\n // the variables to return\n this.volume = 0;\n this.volNorm = 0;\n this.stereoVol = [0, 0];\n this.stereoVolNorm = [0, 0];\n\n this.normalize = false;\n\n this._workletNode.connect(this.output);\n this.output.gain.value = 0;\n\n // this may only be necessary because of a Chrome bug\n this.output.connect(this.audiocontext.destination);\n\n // connect to p5sound master output by default, unless set by input()\n p5sound.meter.connect(this._workletNode);\n\n // add this p5.SoundFile to the soundArray\n p5sound.soundArray.push(this);\n };\n\n /**\n * Connects to the p5sound instance (master output) by default.\n * Optionally, you can pass in a specific source (i.e. a soundfile).\n *\n * @method setInput\n * @for p5.Amplitude\n * @param {soundObject|undefined} [snd] set the sound source\n * (optional, defaults to\n * master output)\n * @param {Number|undefined} [smoothing] a range between 0.0 and 1.0\n * to smooth amplitude readings\n * @example\n *
\n * function preload(){\n * sound1 = loadSound('assets/beat.mp3');\n * sound2 = loadSound('assets/drum.mp3');\n * }\n * function setup(){\n * amplitude = new p5.Amplitude();\n * sound1.play();\n * sound2.play();\n * amplitude.setInput(sound2);\n * }\n * function draw() {\n * background(0);\n * fill(255);\n * var level = amplitude.getLevel();\n * var size = map(level, 0, 1, 0, 200);\n * ellipse(width/2, height/2, size, size);\n * }\n * function mouseClicked(){\n * sound1.stop();\n * sound2.stop();\n * }\n *
\n */\n p5.Amplitude.prototype.setInput = function(source, smoothing) {\n\n p5sound.meter.disconnect();\n\n if (smoothing) {\n this._workletNode.parameters.get('smoothing').value = smoothing;\n }\n\n // connect to the master out of p5s instance if no snd is provided\n if (source == null) {\n console.log('Amplitude input source is not ready! Connecting to master output instead');\n p5sound.meter.connect(this._workletNode);\n }\n\n // if it is a p5.Signal\n else if (source instanceof p5.Signal) {\n source.output.connect(this._workletNode);\n }\n // connect to the sound if it is available\n else if (source) {\n source.connect(this._workletNode);\n this._workletNode.disconnect();\n this._workletNode.connect(this.output);\n }\n\n // otherwise, connect to the master out of p5s instance (default)\n else {\n p5sound.meter.connect(this._workletNode);\n }\n };\n\n p5.Amplitude.prototype.connect = function(unit) {\n if (unit) {\n if (unit.hasOwnProperty('input')) {\n this.output.connect(unit.input);\n } else {\n this.output.connect(unit);\n }\n } else {\n this.output.connect(this.panner.connect(p5sound.input));\n }\n };\n\n p5.Amplitude.prototype.disconnect = function() {\n if (this.output) {\n this.output.disconnect();\n }\n };\n\n /**\n * Returns a single Amplitude reading at the moment it is called.\n * For continuous readings, run in the draw loop.\n *\n * @method getLevel\n * @for p5.Amplitude\n * @param {Number} [channel] Optionally return only channel 0 (left) or 1 (right)\n * @return {Number} Amplitude as a number between 0.0 and 1.0\n * @example\n *
\n * function preload(){\n * sound = loadSound('assets/beat.mp3');\n * }\n * function setup() {\n * amplitude = new p5.Amplitude();\n * sound.play();\n * }\n * function draw() {\n * background(0);\n * fill(255);\n * var level = amplitude.getLevel();\n * var size = map(level, 0, 1, 0, 200);\n * ellipse(width/2, height/2, size, size);\n * }\n * function mouseClicked(){\n * sound.stop();\n * }\n *
\n */\n p5.Amplitude.prototype.getLevel = function(channel) {\n if (typeof channel !== 'undefined') {\n if (this.normalize) {\n return this.stereoVolNorm[channel];\n } else {\n return this.stereoVol[channel];\n }\n }\n else if (this.normalize) {\n return this.volNorm;\n }\n else {\n return this.volume;\n }\n };\n\n /**\n * Determines whether the results of Amplitude.process() will be\n * Normalized. To normalize, Amplitude finds the difference the\n * loudest reading it has processed and the maximum amplitude of\n * 1.0. Amplitude adds this difference to all values to produce\n * results that will reliably map between 0.0 and 1.0. However,\n * if a louder moment occurs, the amount that Normalize adds to\n * all the values will change. Accepts an optional boolean parameter\n * (true or false). Normalizing is off by default.\n *\n * @method toggleNormalize\n * @for p5.Amplitude\n * @param {boolean} [boolean] set normalize to true (1) or false (0)\n */\n p5.Amplitude.prototype.toggleNormalize = function(bool) {\n if (typeof bool === 'boolean') {\n this.normalize = bool;\n }\n else {\n this.normalize = !this.normalize;\n }\n this._workletNode.port.postMessage({ name: 'toggleNormalize', normalize: this.normalize });\n };\n\n /**\n * Smooth Amplitude analysis by averaging with the last analysis\n * frame. Off by default.\n *\n * @method smooth\n * @for p5.Amplitude\n * @param {Number} set smoothing from 0.0 <= 1\n */\n p5.Amplitude.prototype.smooth = function(s) {\n if (s >= 0 && s < 1) {\n this._workletNode.port.postMessage({ name: 'smoothing', smoothing: s });\n } else {\n console.log('Error: smoothing must be between 0 and 1');\n }\n };\n\n p5.Amplitude.prototype.dispose = function() {\n // remove reference from soundArray\n var index = p5sound.soundArray.indexOf(this);\n p5sound.soundArray.splice(index, 1);\n\n if (this.input) {\n this.input.disconnect();\n delete this.input;\n }\n if (this.output) {\n this.output.disconnect();\n delete this.output;\n }\n\n this._workletNode.disconnect();\n delete this._workletNode;\n };\n\n});\n","'use strict';\n\ndefine(function(require) {\n var p5sound = require('master');\n\n /**\n *
FFT (Fast Fourier Transform) is an analysis algorithm that\n * isolates individual\n * \n * audio frequencies within a waveform.
\n *\n *
Once instantiated, a p5.FFT object can return an array based on\n * two types of analyses: • FFT.waveform() computes\n * amplitude values along the time domain. The array indices correspond\n * to samples across a brief moment in time. Each value represents\n * amplitude of the waveform at that sample of time. \n * • FFT.analyze() computes amplitude values along the\n * frequency domain. The array indices correspond to frequencies (i.e.\n * pitches), from the lowest to the highest that humans can hear. Each\n * value represents amplitude at that slice of the frequency spectrum.\n * Use with getEnergy() to measure amplitude at specific\n * frequencies, or within a range of frequencies.
\n *\n *
FFT analyzes a very short snapshot of sound called a sample\n * buffer. It returns an array of amplitude measurements, referred\n * to as bins. The array is 1024 bins long by default.\n * You can change the bin array length, but it must be a power of 2\n * between 16 and 1024 in order for the FFT algorithm to function\n * correctly. The actual size of the FFT buffer is twice the\n * number of bins, so given a standard sample rate, the buffer is\n * 2048/44100 seconds long.
\n *\n *\n * @class p5.FFT\n * @constructor\n * @param {Number} [smoothing] Smooth results of Freq Spectrum.\n * 0.0 < smoothing < 1.0.\n * Defaults to 0.8.\n * @param {Number} [bins] Length of resulting array.\n * Must be a power of two between\n * 16 and 1024. Defaults to 1024.\n * @example\n *
\n * function preload(){\n * sound = loadSound('assets/Damscray_DancingTiger.mp3');\n * }\n *\n * function setup(){\n * var cnv = createCanvas(100,100);\n * cnv.mouseClicked(togglePlay);\n * fft = new p5.FFT();\n * sound.amp(0.2);\n * }\n *\n * function draw(){\n * background(0);\n *\n * var spectrum = fft.analyze();\n * noStroke();\n * fill(0,255,0); // spectrum is green\n * for (var i = 0; i< spectrum.length; i++){\n * var x = map(i, 0, spectrum.length, 0, width);\n * var h = -height + map(spectrum[i], 0, 255, height, 0);\n * rect(x, height, width / spectrum.length, h )\n * }\n *\n * var waveform = fft.waveform();\n * noFill();\n * beginShape();\n * stroke(255,0,0); // waveform is red\n * strokeWeight(1);\n * for (var i = 0; i< waveform.length; i++){\n * var x = map(i, 0, waveform.length, 0, width);\n * var y = map( waveform[i], -1, 1, 0, height);\n * vertex(x,y);\n * }\n * endShape();\n *\n * text('click to play/pause', 4, 10);\n * }\n *\n * // fade sound if mouse is over canvas\n * function togglePlay() {\n * if (sound.isPlaying()) {\n * sound.pause();\n * } else {\n * sound.loop();\n * }\n * }\n *
\n */\n p5.FFT = function(smoothing, bins) {\n this.input = this.analyser = p5sound.audiocontext.createAnalyser();\n\n Object.defineProperties(this, {\n bins: {\n get: function() {\n return this.analyser.fftSize / 2;\n },\n set: function(b) {\n this.analyser.fftSize = b * 2;\n },\n configurable: true,\n enumerable: true\n },\n smoothing: {\n get: function() {\n return this.analyser.smoothingTimeConstant;\n },\n set: function(s) {\n this.analyser.smoothingTimeConstant = s;\n },\n configurable: true,\n enumerable: true\n }\n });\n\n // set default smoothing and bins\n this.smooth(smoothing);\n this.bins = bins || 1024;\n\n // default connections to p5sound fftMeter\n p5sound.fftMeter.connect(this.analyser);\n\n this.freqDomain = new Uint8Array(this.analyser.frequencyBinCount);\n this.timeDomain = new Uint8Array(this.analyser.frequencyBinCount);\n\n // predefined frequency ranges, these will be tweakable\n this.bass = [20, 140];\n this.lowMid = [140, 400];\n this.mid = [400, 2600];\n this.highMid = [2600, 5200];\n this.treble = [5200, 14000];\n\n // add this p5.SoundFile to the soundArray\n p5sound.soundArray.push(this);\n };\n\n /**\n * Set the input source for the FFT analysis. If no source is\n * provided, FFT will analyze all sound in the sketch.\n *\n * @method setInput\n * @for p5.FFT\n * @param {Object} [source] p5.sound object (or web audio API source node)\n */\n p5.FFT.prototype.setInput = function(source) {\n if (!source) {\n p5sound.fftMeter.connect(this.analyser);\n } else {\n if (source.output) {\n source.output.connect(this.analyser);\n } else if (source.connect) {\n source.connect(this.analyser);\n }\n p5sound.fftMeter.disconnect();\n }\n };\n\n /**\n * Returns an array of amplitude values (between -1.0 and +1.0) that represent\n * a snapshot of amplitude readings in a single buffer. Length will be\n * equal to bins (defaults to 1024). Can be used to draw the waveform\n * of a sound.\n *\n * @method waveform\n * @for p5.FFT\n * @param {Number} [bins] Must be a power of two between\n * 16 and 1024. Defaults to 1024.\n * @param {String} [precision] If any value is provided, will return results\n * in a Float32 Array which is more precise\n * than a regular array.\n * @return {Array} Array Array of amplitude values (-1 to 1)\n * over time. Array length = bins.\n *\n */\n p5.FFT.prototype.waveform = function() {\n var bins, mode, normalArray;\n\n for (var i = 0; i < arguments.length; i++) {\n if (typeof arguments[i] === 'number') {\n bins = arguments[i];\n this.analyser.fftSize = bins * 2;\n }\n if (typeof arguments[i] === 'string') {\n mode = arguments[i];\n }\n }\n\n // getFloatFrequencyData doesnt work in Safari as of 5/2015\n if (mode && !p5.prototype._isSafari()) {\n timeToFloat(this, this.timeDomain);\n this.analyser.getFloatTimeDomainData(this.timeDomain);\n return this.timeDomain;\n } else {\n timeToInt(this, this.timeDomain);\n this.analyser.getByteTimeDomainData(this.timeDomain);\n var normalArray = new Array();\n for (var j = 0; j < this.timeDomain.length; j++) {\n var scaled = p5.prototype.map(this.timeDomain[j], 0, 255, -1, 1);\n normalArray.push(scaled);\n }\n return normalArray;\n }\n };\n\n /**\n * Returns an array of amplitude values (between 0 and 255)\n * across the frequency spectrum. Length is equal to FFT bins\n * (1024 by default). The array indices correspond to frequencies\n * (i.e. pitches), from the lowest to the highest that humans can\n * hear. Each value represents amplitude at that slice of the\n * frequency spectrum. Must be called prior to using\n * getEnergy().\n *\n * @method analyze\n * @for p5.FFT\n * @param {Number} [bins] Must be a power of two between\n * 16 and 1024. Defaults to 1024.\n * @param {Number} [scale] If \"dB,\" returns decibel\n * float measurements between\n * -140 and 0 (max).\n * Otherwise returns integers from 0-255.\n * @return {Array} spectrum Array of energy (amplitude/volume)\n * values across the frequency spectrum.\n * Lowest energy (silence) = 0, highest\n * possible is 255.\n * @example\n *
\n * var osc;\n * var fft;\n *\n * function setup(){\n * createCanvas(100,100);\n * osc = new p5.Oscillator();\n * osc.amp(0);\n * osc.start();\n * fft = new p5.FFT();\n * }\n *\n * function draw(){\n * background(0);\n *\n * var freq = map(mouseX, 0, 800, 20, 15000);\n * freq = constrain(freq, 1, 20000);\n * osc.freq(freq);\n *\n * var spectrum = fft.analyze();\n * noStroke();\n * fill(0,255,0); // spectrum is green\n * for (var i = 0; i< spectrum.length; i++){\n * var x = map(i, 0, spectrum.length, 0, width);\n * var h = -height + map(spectrum[i], 0, 255, height, 0);\n * rect(x, height, width / spectrum.length, h );\n * }\n *\n * stroke(255);\n * text('Freq: ' + round(freq)+'Hz', 10, 10);\n *\n * isMouseOverCanvas();\n * }\n *\n * // only play sound when mouse is over canvas\n * function isMouseOverCanvas() {\n * var mX = mouseX, mY = mouseY;\n * if (mX > 0 && mX < width && mY < height && mY > 0) {\n * osc.amp(0.5, 0.2);\n * } else {\n * osc.amp(0, 0.2);\n * }\n * }\n *
\n *\n *\n */\n p5.FFT.prototype.analyze = function() {\n var mode;\n\n for (var i = 0; i < arguments.length; i++) {\n if (typeof arguments[i] === 'number') {\n this.bins = arguments[i];\n this.analyser.fftSize = this.bins * 2;\n }\n if (typeof arguments[i] === 'string') {\n mode = arguments[i];\n }\n }\n\n if (mode && mode.toLowerCase() === 'db') {\n freqToFloat(this);\n this.analyser.getFloatFrequencyData(this.freqDomain);\n return this.freqDomain;\n } else {\n freqToInt(this, this.freqDomain);\n this.analyser.getByteFrequencyData(this.freqDomain);\n var normalArray = Array.apply([], this.freqDomain);\n \n return normalArray;\n }\n };\n\n /**\n * Returns the amount of energy (volume) at a specific\n * \n * frequency, or the average amount of energy between two\n * frequencies. Accepts Number(s) corresponding\n * to frequency (in Hz), or a String corresponding to predefined\n * frequency ranges (\"bass\", \"lowMid\", \"mid\", \"highMid\", \"treble\").\n * Returns a range between 0 (no energy/volume at that frequency) and\n * 255 (maximum energy).\n * NOTE: analyze() must be called prior to getEnergy(). Analyze()\n * tells the FFT to analyze frequency data, and getEnergy() uses\n * the results determine the value at a specific frequency or\n * range of frequencies.\n *\n * @method getEnergy\n * @for p5.FFT\n * @param {Number|String} frequency1 Will return a value representing\n * energy at this frequency. Alternately,\n * the strings \"bass\", \"lowMid\" \"mid\",\n * \"highMid\", and \"treble\" will return\n * predefined frequency ranges.\n * @param {Number} [frequency2] If a second frequency is given,\n * will return average amount of\n * energy that exists between the\n * two frequencies.\n * @return {Number} Energy Energy (volume/amplitude) from\n * 0 and 255.\n *\n */\n p5.FFT.prototype.getEnergy = function(frequency1, frequency2) {\n var nyquist = p5sound.audiocontext.sampleRate / 2;\n\n if (frequency1 === 'bass') {\n frequency1 = this.bass[0];\n frequency2 = this.bass[1];\n } else if (frequency1 === 'lowMid') {\n frequency1 = this.lowMid[0];\n frequency2 = this.lowMid[1];\n } else if (frequency1 === 'mid') {\n frequency1 = this.mid[0];\n frequency2 = this.mid[1];\n } else if (frequency1 === 'highMid') {\n frequency1 = this.highMid[0];\n frequency2 = this.highMid[1];\n } else if (frequency1 === 'treble') {\n frequency1 = this.treble[0];\n frequency2 = this.treble[1];\n }\n\n if (typeof frequency1 !== 'number') {\n throw 'invalid input for getEnergy()';\n } else if (!frequency2) {\n // if only one parameter:\n var index = Math.round(frequency1 / nyquist * this.freqDomain.length);\n return this.freqDomain[index];\n } else if (frequency1 && frequency2) {\n // if two parameters:\n // if second is higher than first\n if (frequency1 > frequency2) {\n var swap = frequency2;\n frequency2 = frequency1;\n frequency1 = swap;\n }\n var lowIndex = Math.round(frequency1 / nyquist * this.freqDomain.length);\n var highIndex = Math.round(frequency2 / nyquist * this.freqDomain.length);\n\n var total = 0;\n var numFrequencies = 0;\n // add up all of the values for the frequencies\n for (var i = lowIndex; i <= highIndex; i++) {\n total += this.freqDomain[i];\n numFrequencies += 1;\n }\n // divide by total number of frequencies\n var toReturn = total / numFrequencies;\n return toReturn;\n } else {\n throw 'invalid input for getEnergy()';\n }\n };\n\n // compatability with v.012, changed to getEnergy in v.0121. Will be deprecated...\n p5.FFT.prototype.getFreq = function(freq1, freq2) {\n console.log('getFreq() is deprecated. Please use getEnergy() instead.');\n var x = this.getEnergy(freq1, freq2);\n return x;\n };\n\n /**\n * Returns the\n * \n * spectral centroid of the input signal.\n * NOTE: analyze() must be called prior to getCentroid(). Analyze()\n * tells the FFT to analyze frequency data, and getCentroid() uses\n * the results determine the spectral centroid.\n *\n * @method getCentroid\n * @for p5.FFT\n * @return {Number} Spectral Centroid Frequency Frequency of the spectral centroid in Hz.\n *\n *\n * @example\n *
\n *\n *\n *function setup(){\n * cnv = createCanvas(100,100);\n * sound = new p5.AudioIn();\n * sound.start();\n * fft = new p5.FFT();\n * sound.connect(fft);\n *}\n *\n *\n *function draw(){\n *\n * var centroidplot = 0.0;\n * var spectralCentroid = 0;\n *\n *\n * background(0);\n * stroke(0,255,0);\n * var spectrum = fft.analyze();\n * fill(0,255,0); // spectrum is green\n *\n * //draw the spectrum\n * for (var i = 0; i< spectrum.length; i++){\n * var x = map(log(i), 0, log(spectrum.length), 0, width);\n * var h = map(spectrum[i], 0, 255, 0, height);\n * var rectangle_width = (log(i+1)-log(i))*(width/log(spectrum.length));\n * rect(x, height, rectangle_width, -h )\n * }\n\n * var nyquist = 22050;\n *\n * // get the centroid\n * spectralCentroid = fft.getCentroid();\n *\n * // the mean_freq_index calculation is for the display.\n * var mean_freq_index = spectralCentroid/(nyquist/spectrum.length);\n *\n * centroidplot = map(log(mean_freq_index), 0, log(spectrum.length), 0, width);\n *\n *\n * stroke(255,0,0); // the line showing where the centroid is will be red\n *\n * rect(centroidplot, 0, width / spectrum.length, height)\n * noStroke();\n * fill(255,255,255); // text is white\n * text(\"centroid: \", 10, 20);\n * text(round(spectralCentroid)+\" Hz\", 10, 40);\n *}\n *
\n */\n p5.FFT.prototype.getCentroid = function() {\n var nyquist = p5sound.audiocontext.sampleRate / 2;\n var cumulative_sum = 0;\n var centroid_normalization = 0;\n\n for (var i = 0; i < this.freqDomain.length; i++) {\n cumulative_sum += i * this.freqDomain[i];\n centroid_normalization += this.freqDomain[i];\n }\n\n var mean_freq_index = 0;\n\n if (centroid_normalization !== 0) {\n mean_freq_index = cumulative_sum / centroid_normalization;\n }\n\n var spec_centroid_freq =\n mean_freq_index * (nyquist / this.freqDomain.length);\n return spec_centroid_freq;\n };\n\n /**\n * Smooth FFT analysis by averaging with the last analysis frame.\n *\n * @method smooth\n * @param {Number} smoothing 0.0 < smoothing < 1.0.\n * Defaults to 0.8.\n */\n p5.FFT.prototype.smooth = function(s) {\n if (typeof s !== 'undefined') {\n this.smoothing = s;\n }\n return this.smoothing;\n };\n\n p5.FFT.prototype.dispose = function() {\n // remove reference from soundArray\n var index = p5sound.soundArray.indexOf(this);\n p5sound.soundArray.splice(index, 1);\n\n if (this.analyser) {\n this.analyser.disconnect();\n delete this.analyser;\n }\n };\n\n /**\n * Returns an array of average amplitude values for a given number\n * of frequency bands split equally. N defaults to 16.\n * NOTE: analyze() must be called prior to linAverages(). Analyze()\n * tells the FFT to analyze frequency data, and linAverages() uses\n * the results to group them into a smaller set of averages.\n *\n * @method linAverages\n * @for p5.FFT\n * @param {Number} N Number of returned frequency groups\n * @return {Array} linearAverages Array of average amplitude values for each group\n */\n p5.FFT.prototype.linAverages = function(N) {\n var N = N || 16; // This prevents undefined, null or 0 values of N\n\n var spectrum = this.freqDomain;\n var spectrumLength = spectrum.length;\n var spectrumStep = Math.floor(spectrumLength / N);\n\n var linearAverages = new Array(N);\n // Keep a second index for the current average group and place the values accordingly\n // with only one loop in the spectrum data\n var groupIndex = 0;\n\n for (var specIndex = 0; specIndex < spectrumLength; specIndex++) {\n linearAverages[groupIndex] =\n linearAverages[groupIndex] !== undefined\n ? (linearAverages[groupIndex] + spectrum[specIndex]) / 2\n : spectrum[specIndex];\n\n // Increase the group index when the last element of the group is processed\n if (specIndex % spectrumStep === spectrumStep - 1) {\n groupIndex++;\n }\n }\n\n return linearAverages;\n };\n\n /**\n * Returns an array of average amplitude values of the spectrum, for a given\n * set of \n * Octave Bands\n * NOTE: analyze() must be called prior to logAverages(). Analyze()\n * tells the FFT to analyze frequency data, and logAverages() uses\n * the results to group them into a smaller set of averages.\n *\n * @method logAverages\n * @for p5.FFT\n * @param {Array} octaveBands Array of Octave Bands objects for grouping\n * @return {Array} logAverages Array of average amplitude values for each group\n */\n p5.FFT.prototype.logAverages = function(octaveBands) {\n var nyquist = p5sound.audiocontext.sampleRate / 2;\n var spectrum = this.freqDomain;\n var spectrumLength = spectrum.length;\n\n var logAverages = new Array(octaveBands.length);\n // Keep a second index for the current average group and place the values accordingly\n // With only one loop in the spectrum data\n var octaveIndex = 0;\n\n for (var specIndex = 0; specIndex < spectrumLength; specIndex++) {\n var specIndexFrequency = Math.round(\n specIndex * nyquist / this.freqDomain.length\n );\n\n // Increase the group index if the current frequency exceeds the limits of the band\n if (specIndexFrequency > octaveBands[octaveIndex].hi) {\n octaveIndex++;\n }\n\n logAverages[octaveIndex] =\n logAverages[octaveIndex] !== undefined\n ? (logAverages[octaveIndex] + spectrum[specIndex]) / 2\n : spectrum[specIndex];\n }\n\n return logAverages;\n };\n\n /**\n * Calculates and Returns the 1/N\n * Octave Bands\n * N defaults to 3 and minimum central frequency to 15.625Hz.\n * (1/3 Octave Bands ~= 31 Frequency Bands)\n * Setting fCtr0 to a central value of a higher octave will ignore the lower bands\n * and produce less frequency groups.\n *\n * @method getOctaveBands\n * @for p5.FFT\n * @param {Number} N Specifies the 1/N type of generated octave bands\n * @param {Number} fCtr0 Minimum central frequency for the lowest band\n * @return {Array} octaveBands Array of octave band objects with their bounds\n */\n p5.FFT.prototype.getOctaveBands = function(N, fCtr0) {\n var N = N || 3; // Default to 1/3 Octave Bands\n var fCtr0 = fCtr0 || 15.625; // Minimum central frequency, defaults to 15.625Hz\n\n var octaveBands = [];\n var lastFrequencyBand = {\n lo: fCtr0 / Math.pow(2, 1 / (2 * N)),\n ctr: fCtr0,\n hi: fCtr0 * Math.pow(2, 1 / (2 * N))\n };\n octaveBands.push(lastFrequencyBand);\n\n var nyquist = p5sound.audiocontext.sampleRate / 2;\n while (lastFrequencyBand.hi < nyquist) {\n var newFrequencyBand = {};\n newFrequencyBand.lo = lastFrequencyBand.hi;\n newFrequencyBand.ctr = lastFrequencyBand.ctr * Math.pow(2, 1 / N);\n newFrequencyBand.hi = newFrequencyBand.ctr * Math.pow(2, 1 / (2 * N));\n\n octaveBands.push(newFrequencyBand);\n lastFrequencyBand = newFrequencyBand;\n }\n\n return octaveBands;\n };\n\n // helper methods to convert type from float (dB) to int (0-255)\n var freqToFloat = function(fft) {\n if (fft.freqDomain instanceof Float32Array === false) {\n fft.freqDomain = new Float32Array(fft.analyser.frequencyBinCount);\n }\n };\n var freqToInt = function(fft) {\n if (fft.freqDomain instanceof Uint8Array === false) {\n fft.freqDomain = new Uint8Array(fft.analyser.frequencyBinCount);\n }\n };\n var timeToFloat = function(fft) {\n if (fft.timeDomain instanceof Float32Array === false) {\n fft.timeDomain = new Float32Array(fft.analyser.frequencyBinCount);\n }\n };\n var timeToInt = function(fft) {\n if (fft.timeDomain instanceof Uint8Array === false) {\n fft.timeDomain = new Uint8Array(fft.analyser.frequencyBinCount);\n }\n };\n});\n","'use strict';\n\ndefine(function (require) {\n\n // Signal is built with the Tone.js signal by Yotam Mann\n // https://github.com/TONEnoTONE/Tone.js/\n var Signal = require('Tone/signal/Signal');\n var Add = require('Tone/signal/Add');\n var Mult = require('Tone/signal/Multiply');\n var Scale = require('Tone/signal/Scale');\n\n /**\n *
p5.Signal is a constant audio-rate signal used by p5.Oscillator\n * and p5.Envelope for modulation math.
\n *\n *
This is necessary because Web Audio is processed on a seprate clock.\n * For example, the p5 draw loop runs about 60 times per second. But\n * the audio clock must process samples 44100 times per second. If we\n * want to add a value to each of those samples, we can't do it in the\n * draw loop, but we can do it by adding a constant-rate audio signal.This class mostly functions behind the scenes in p5.sound, and returns\n * a Tone.Signal from the Tone.js library by Yotam Mann.\n * If you want to work directly with audio signals for modular\n * synthesis, check out\n * tone.js.
\n *\n * @class p5.Signal\n * @constructor\n * @return {Tone.Signal} A Signal object from the Tone.js library\n * @example\n *
\n * function setup() {\n * carrier = new p5.Oscillator('sine');\n * carrier.amp(1); // set amplitude\n * carrier.freq(220); // set frequency\n * carrier.start(); // start oscillating\n *\n * modulator = new p5.Oscillator('sawtooth');\n * modulator.disconnect();\n * modulator.amp(1);\n * modulator.freq(4);\n * modulator.start();\n *\n * // Modulator's default amplitude range is -1 to 1.\n * // Multiply it by -200, so the range is -200 to 200\n * // then add 220 so the range is 20 to 420\n * carrier.freq( modulator.mult(-200).add(220) );\n * }\n *
\n */\n p5.Signal = function(value) {\n var s = new Signal(value);\n // p5sound.soundArray.push(s);\n return s; // TODO: is this really a constructor?\n };\n\n /**\n * Fade to value, for smooth transitions\n *\n * @method fade\n * @for p5.Signal\n * @param {Number} value Value to set this signal\n * @param {Number} [secondsFromNow] Length of fade, in seconds from now\n */\n Signal.prototype.fade = Signal.prototype.linearRampToValueAtTime;\n Mult.prototype.fade = Signal.prototype.fade;\n Add.prototype.fade = Signal.prototype.fade;\n Scale.prototype.fade = Signal.prototype.fade;\n\n\n /**\n * Connect a p5.sound object or Web Audio node to this\n * p5.Signal so that its amplitude values can be scaled.\n *\n * @method setInput\n * @for p5.Signal\n * @param {Object} input\n */\n Signal.prototype.setInput = function(_input) {\n _input.connect(this);\n };\n Mult.prototype.setInput = Signal.prototype.setInput;\n Add.prototype.setInput = Signal.prototype.setInput;\n Scale.prototype.setInput = Signal.prototype.setInput;\n\n\n // signals can add / mult / scale themselves\n\n /**\n * Add a constant value to this audio signal,\n * and return the resulting audio signal. Does\n * not change the value of the original signal,\n * instead it returns a new p5.SignalAdd.\n *\n * @method add\n * @for p5.Signal\n * @param {Number} number\n * @return {p5.Signal} object\n */\n Signal.prototype.add = function(num) {\n var add = new Add(num);\n // add.setInput(this);\n this.connect(add);\n return add;\n };\n Mult.prototype.add = Signal.prototype.add;\n Add.prototype.add = Signal.prototype.add;\n Scale.prototype.add = Signal.prototype.add;\n\n /**\n * Multiply this signal by a constant value,\n * and return the resulting audio signal. Does\n * not change the value of the original signal,\n * instead it returns a new p5.SignalMult.\n *\n * @method mult\n * @for p5.Signal\n * @param {Number} number to multiply\n * @return {p5.Signal} object\n */\n Signal.prototype.mult = function(num) {\n var mult = new Mult(num);\n // mult.setInput(this);\n this.connect(mult);\n return mult;\n };\n Mult.prototype.mult = Signal.prototype.mult;\n Add.prototype.mult = Signal.prototype.mult;\n Scale.prototype.mult = Signal.prototype.mult;\n\n /**\n * Scale this signal value to a given range,\n * and return the result as an audio signal. Does\n * not change the value of the original signal,\n * instead it returns a new p5.SignalScale.\n *\n * @method scale\n * @for p5.Signal\n * @param {Number} number to multiply\n * @param {Number} inMin input range minumum\n * @param {Number} inMax input range maximum\n * @param {Number} outMin input range minumum\n * @param {Number} outMax input range maximum\n * @return {p5.Signal} object\n */\n Signal.prototype.scale = function(inMin, inMax, outMin, outMax) {\n var mapOutMin, mapOutMax;\n if (arguments.length === 4) {\n mapOutMin = p5.prototype.map(outMin, inMin, inMax, 0, 1) - 0.5;\n mapOutMax = p5.prototype.map(outMax, inMin, inMax, 0, 1) - 0.5;\n }\n else {\n mapOutMin = arguments[0];\n mapOutMax = arguments[1];\n }\n var scale = new Scale(mapOutMin, mapOutMax);\n this.connect(scale);\n return scale;\n };\n Mult.prototype.scale = Signal.prototype.scale;\n Add.prototype.scale = Signal.prototype.scale;\n Scale.prototype.scale = Signal.prototype.scale;\n\n});\n\n\n","define([\"Tone/core/Tone\", \"Tone/type/TimeBase\"], function (Tone) {\n\n\t/**\n\t * @class Tone.Frequency is a primitive type for encoding Frequency values. \n\t * Eventually all time values are evaluated to hertz\n\t * using the `eval` method. \n\t * @constructor\n\t * @extends {Tone.TimeBase}\n\t * @param {String|Number} val The time value.\n\t * @param {String=} units The units of the value.\n\t * @example\n\t * Tone.Frequency(\"C3\") // 261\n\t * Tone.Frequency(38, \"midi\") //\n\t * Tone.Frequency(\"C3\").transpose(4);\n\t */\n\tTone.Frequency = function(val, units){\n\t\tif (this instanceof Tone.Frequency){\n\t\t\t\n\t\t\tTone.TimeBase.call(this, val, units);\n\n\t\t} else {\n\t\t\treturn new Tone.Frequency(val, units);\n\t\t}\n\t};\n\n\tTone.extend(Tone.Frequency, Tone.TimeBase);\n\n\t///////////////////////////////////////////////////////////////////////////\n\t//\tAUGMENT BASE EXPRESSIONS\n\t///////////////////////////////////////////////////////////////////////////\n\n\t//clone the expressions so that \n\t//we can add more without modifying the original\n\tTone.Frequency.prototype._primaryExpressions = Object.create(Tone.TimeBase.prototype._primaryExpressions);\n\n\t/*\n\t * midi type primary expression\n\t * @type {Object}\n\t * @private\n\t */\n\tTone.Frequency.prototype._primaryExpressions.midi = {\n\t\tregexp : /^(\\d+(?:\\.\\d+)?midi)/,\n\t\tmethod : function(value){\n\t\t\treturn this.midiToFrequency(value);\n\t\t}\t\n\t};\n\n\t/*\n\t * note type primary expression\n\t * @type {Object}\n\t * @private\n\t */\n\tTone.Frequency.prototype._primaryExpressions.note = {\n\t\tregexp : /^([a-g]{1}(?:b|#|x|bb)?)(-?[0-9]+)/i,\n\t\tmethod : function(pitch, octave){\n\t\t\tvar index = noteToScaleIndex[pitch.toLowerCase()];\n\t\t\tvar noteNumber = index + (parseInt(octave) + 1) * 12;\n\t\t\treturn this.midiToFrequency(noteNumber);\n\t\t}\t\n\t};\n\n\t/*\n\t * BeatsBarsSixteenths type primary expression\n\t * @type {Object}\n\t * @private\n\t */\n\tTone.Frequency.prototype._primaryExpressions.tr = {\n\t\t\tregexp : /^(\\d+(?:\\.\\d+)?):(\\d+(?:\\.\\d+)?):?(\\d+(?:\\.\\d+)?)?/,\n\t\t\tmethod : function(m, q, s){\n\t\t\tvar total = 1;\n\t\t\tif (m && m !== \"0\"){\n\t\t\t\ttotal *= this._beatsToUnits(this._timeSignature() * parseFloat(m));\n\t\t\t}\n\t\t\tif (q && q !== \"0\"){\n\t\t\t\ttotal *= this._beatsToUnits(parseFloat(q));\n\t\t\t}\n\t\t\tif (s && s !== \"0\"){\n\t\t\t\ttotal *= this._beatsToUnits(parseFloat(s) / 4);\n\t\t\t}\n\t\t\treturn total;\n\t\t}\n\t};\n\n\t///////////////////////////////////////////////////////////////////////////\n\t//\tEXPRESSIONS\n\t///////////////////////////////////////////////////////////////////////////\n\n\t/**\n\t * Transposes the frequency by the given number of semitones.\n\t * @param {Interval} interval\n\t * @return {Tone.Frequency} this\n\t * @example\n\t * Tone.Frequency(\"A4\").transpose(3); //\"C5\"\n\t */\n\tTone.Frequency.prototype.transpose = function(interval){\n\t\tthis._expr = function(expr, interval){\n\t\t\tvar val = expr();\n\t\t\treturn val * this.intervalToFrequencyRatio(interval);\n\t\t}.bind(this, this._expr, interval);\n\t\treturn this;\n\t};\n\n\t/**\n\t * Takes an array of semitone intervals and returns\n\t * an array of frequencies transposed by those intervals.\n\t * @param {Array} intervals\n\t * @return {Tone.Frequency} this\n\t * @example\n\t * Tone.Frequency(\"A4\").harmonize([0, 3, 7]); //[\"A4\", \"C5\", \"E5\"]\n\t */\n\tTone.Frequency.prototype.harmonize = function(intervals){\n\t\tthis._expr = function(expr, intervals){\n\t\t\tvar val = expr();\n\t\t\tvar ret = [];\n\t\t\tfor (var i = 0; i < intervals.length; i++){\n\t\t\t\tret[i] = val * this.intervalToFrequencyRatio(intervals[i]);\n\t\t\t}\n\t\t\treturn ret;\n\t\t}.bind(this, this._expr, intervals);\n\t\treturn this;\n\t};\n\n\t///////////////////////////////////////////////////////////////////////////\n\t//\tUNIT CONVERSIONS\n\t///////////////////////////////////////////////////////////////////////////\n\n\t/**\n\t * Return the value of the frequency as a MIDI note\n\t * @return {MIDI}\n\t * @example\n\t * Tone.Frequency(\"C4\").toMidi(); //60\n\t */\n\tTone.Frequency.prototype.toMidi = function(){\n\t\treturn this.frequencyToMidi(this.valueOf());\n\t};\n\n\t/**\n\t * Return the value of the frequency in Scientific Pitch Notation\n\t * @return {Note}\n\t * @example\n\t * Tone.Frequency(69, \"midi\").toNote(); //\"A4\"\n\t */\n\tTone.Frequency.prototype.toNote = function(){\n\t\tvar freq = this.valueOf();\n\t\tvar log = Math.log(freq / Tone.Frequency.A4) / Math.LN2;\n\t\tvar noteNumber = Math.round(12 * log) + 57;\n\t\tvar octave = Math.floor(noteNumber/12);\n\t\tif(octave < 0){\n\t\t\tnoteNumber += -12 * octave;\n\t\t}\n\t\tvar noteName = scaleIndexToNote[noteNumber % 12];\n\t\treturn noteName + octave.toString();\n\t};\n\n\t/**\n\t * Return the duration of one cycle in seconds.\n\t * @return {Seconds}\n\t */\n\tTone.Frequency.prototype.toSeconds = function(){\n\t\treturn 1 / this.valueOf();\n\t};\n\n\t/**\n\t * Return the value in Hertz\n\t * @return {Frequency}\n\t */\n\tTone.Frequency.prototype.toFrequency = function(){\n\t\treturn this.valueOf();\n\t};\n\n\t/**\n\t * Return the duration of one cycle in ticks\n\t * @return {Ticks}\n\t */\n\tTone.Frequency.prototype.toTicks = function(){\n\t\tvar quarterTime = this._beatsToUnits(1);\n\t\tvar quarters = this.valueOf() / quarterTime;\n\t\treturn Math.floor(quarters * Tone.Transport.PPQ);\n\t};\n\n\t///////////////////////////////////////////////////////////////////////////\n\t//\tUNIT CONVERSIONS HELPERS\n\t///////////////////////////////////////////////////////////////////////////\n\n\t/**\n\t * Returns the value of a frequency in the current units\n\t * @param {Frequency} freq\n\t * @return {Number}\n\t * @private\n\t */\n\tTone.Frequency.prototype._frequencyToUnits = function(freq){\n\t\treturn freq;\n\t};\n\n\t/**\n\t * Returns the value of a tick in the current time units\n\t * @param {Ticks} ticks\n\t * @return {Number}\n\t * @private\n\t */\n\tTone.Frequency.prototype._ticksToUnits = function(ticks){\n\t\treturn 1 / ((ticks * 60) / (Tone.Transport.bpm.value * Tone.Transport.PPQ));\n\t};\n\n\t/**\n\t * Return the value of the beats in the current units\n\t * @param {Number} beats\n\t * @return {Number}\n\t * @private\n\t */\n\tTone.Frequency.prototype._beatsToUnits = function(beats){\n\t\treturn 1 / Tone.TimeBase.prototype._beatsToUnits.call(this, beats);\n\t};\n\n\t/**\n\t * Returns the value of a second in the current units\n\t * @param {Seconds} seconds\n\t * @return {Number}\n\t * @private\n\t */\n\tTone.Frequency.prototype._secondsToUnits = function(seconds){\n\t\treturn 1 / seconds;\n\t};\n\n\t/**\n\t * The default units if none are given.\n\t * @private\n\t */\n\tTone.Frequency.prototype._defaultUnits = \"hz\";\n\n\t///////////////////////////////////////////////////////////////////////////\n\t//\tFREQUENCY CONVERSIONS\n\t///////////////////////////////////////////////////////////////////////////\n\n\t/**\n\t * Note to scale index\n\t * @type {Object}\n\t */\n\tvar noteToScaleIndex = {\n\t\t\"cbb\" : -2, \"cb\" : -1, \"c\" : 0, \"c#\" : 1, \"cx\" : 2, \n\t\t\"dbb\" : 0, \"db\" : 1, \"d\" : 2, \"d#\" : 3, \"dx\" : 4,\n\t\t\"ebb\" : 2, \"eb\" : 3, \"e\" : 4, \"e#\" : 5, \"ex\" : 6, \n\t\t\"fbb\" : 3, \"fb\" : 4, \"f\" : 5, \"f#\" : 6, \"fx\" : 7,\n\t\t\"gbb\" : 5, \"gb\" : 6, \"g\" : 7, \"g#\" : 8, \"gx\" : 9,\n\t\t\"abb\" : 7, \"ab\" : 8, \"a\" : 9, \"a#\" : 10, \"ax\" : 11,\n\t\t\"bbb\" : 9, \"bb\" : 10, \"b\" : 11, \"b#\" : 12, \"bx\" : 13,\n\t};\n\n\t/**\n\t * scale index to note (sharps)\n\t * @type {Array}\n\t */\n\tvar scaleIndexToNote = [\"C\", \"C#\", \"D\", \"D#\", \"E\", \"F\", \"F#\", \"G\", \"G#\", \"A\", \"A#\", \"B\"];\n\n\t/**\n\t * The [concert pitch](https://en.wikipedia.org/wiki/Concert_pitch)\n\t * A4's values in Hertz. \n\t * @type {Frequency}\n\t * @static\n\t */\n\tTone.Frequency.A4 = 440;\n\n\t/**\n\t * Convert a MIDI note to frequency value. \n\t * @param {MIDI} midi The midi number to convert.\n\t * @return {Frequency} the corresponding frequency value\n\t * @example\n\t * tone.midiToFrequency(69); // returns 440\n\t */\n\tTone.Frequency.prototype.midiToFrequency = function(midi){\n\t\treturn Tone.Frequency.A4 * Math.pow(2, (midi - 69) / 12);\n\t};\n\n\t/**\n\t * Convert a frequency value to a MIDI note.\n\t * @param {Frequency} frequency The value to frequency value to convert.\n\t * @returns {MIDI}\n\t * @example\n\t * tone.midiToFrequency(440); // returns 69\n\t */\n\tTone.Frequency.prototype.frequencyToMidi = function(frequency){\n\t\treturn 69 + 12 * Math.log(frequency / Tone.Frequency.A4) / Math.LN2;\n\t};\n\n\treturn Tone.Frequency;\n});","define([\"Tone/core/Tone\", \"Tone/type/Time\"], function (Tone) {\n\n\t/**\n\t * @class Tone.TransportTime is a the time along the Transport's\n\t * timeline. It is similar to Tone.Time, but instead of evaluating\n\t * against the AudioContext's clock, it is evaluated against\n\t * the Transport's position. See [TransportTime wiki](https://github.com/Tonejs/Tone.js/wiki/TransportTime).\n\t * @constructor\n\t * @param {Time} val The time value as a number or string\n\t * @param {String=} units Unit values\n\t * @extends {Tone.Time}\n\t */\n\tTone.TransportTime = function(val, units){\n\t\tif (this instanceof Tone.TransportTime){\n\t\t\t\n\t\t\tTone.Time.call(this, val, units);\n\n\t\t} else {\n\t\t\treturn new Tone.TransportTime(val, units);\n\t\t}\n\t};\n\n\tTone.extend(Tone.TransportTime, Tone.Time);\n\n\t//clone the expressions so that \n\t//we can add more without modifying the original\n\tTone.TransportTime.prototype._unaryExpressions = Object.create(Tone.Time.prototype._unaryExpressions);\n\n\t/**\n\t * Adds an additional unary expression\n\t * which quantizes values to the next subdivision\n\t * @type {Object}\n\t * @private\n\t */\n\tTone.TransportTime.prototype._unaryExpressions.quantize = {\n\t\tregexp : /^@/,\n\t\tmethod : function(rh){\n\t\t\tvar subdivision = this._secondsToTicks(rh());\n\t\t\tvar multiple = Math.ceil(Tone.Transport.ticks / subdivision);\n\t\t\treturn this._ticksToUnits(multiple * subdivision);\n\t\t}\n\t};\n\n\t/**\n\t * Convert seconds into ticks\n\t * @param {Seconds} seconds\n\t * @return {Ticks}\n\t * @private\n\t */\n\tTone.TransportTime.prototype._secondsToTicks = function(seconds){\n\t\tvar quarterTime = this._beatsToUnits(1);\n\t\tvar quarters = seconds / quarterTime;\n\t\treturn Math.round(quarters * Tone.Transport.PPQ);\n\t};\n\n\t/**\n\t * Evaluate the time expression. Returns values in ticks\n\t * @return {Ticks}\n\t */\n\tTone.TransportTime.prototype.valueOf = function(){\n\t\tvar val = this._secondsToTicks(this._expr());\n\t\treturn val + (this._plusNow ? Tone.Transport.ticks : 0);\n\t};\n\n\t/**\n\t * Return the time in ticks.\n\t * @return {Ticks}\n\t */\n\tTone.TransportTime.prototype.toTicks = function(){\n\t\treturn this.valueOf();\n\t};\n\n\t/**\n\t * Return the time in seconds.\n\t * @return {Seconds}\n\t */\n\tTone.TransportTime.prototype.toSeconds = function(){\n\t\tvar val = this._expr();\n\t\treturn val + (this._plusNow ? Tone.Transport.seconds : 0);\n\t};\n\n\t/**\n\t * Return the time as a frequency value\n\t * @return {Frequency} \n\t */\n\tTone.TransportTime.prototype.toFrequency = function(){\n\t\treturn 1/this.toSeconds();\n\t};\n\n\treturn Tone.TransportTime;\n});","'use strict';\n\ndefine(function (require) {\n\n var p5sound = require('master');\n var Add = require('Tone/signal/Add');\n var Mult = require('Tone/signal/Multiply');\n var Scale = require('Tone/signal/Scale');\n var TimelineSignal = require('Tone/signal/TimelineSignal');\n\n /**\n *
Envelopes are pre-defined amplitude distribution over time.\n * Typically, envelopes are used to control the output volume\n * of an object, a series of fades referred to as Attack, Decay,\n * Sustain and Release (\n * ADSR\n * ). Envelopes can also control other Web Audio Parameters—for example, a p5.Envelope can\n * control an Oscillator's frequency like this: osc.freq(env).
\n *
Use setRange to change the attack/release level.\n * Use setADSR to change attackTime, decayTime, sustainPercent and releaseTime.
\n *
Use the play method to play the entire envelope,\n * the ramp method for a pingable trigger,\n * or triggerAttack/\n * triggerRelease to trigger noteOn/noteOff.
\n * var attackLevel = 1.0;\n * var releaseLevel = 0;\n *\n * var attackTime = 0.001;\n * var decayTime = 0.2;\n * var susPercent = 0.2;\n * var releaseTime = 0.5;\n *\n * var env, triOsc;\n *\n * function setup() {\n * var cnv = createCanvas(100, 100);\n *\n * textAlign(CENTER);\n * text('click to play', width/2, height/2);\n *\n * env = new p5.Envelope();\n * env.setADSR(attackTime, decayTime, susPercent, releaseTime);\n * env.setRange(attackLevel, releaseLevel);\n *\n * triOsc = new p5.Oscillator('triangle');\n * triOsc.amp(env);\n * triOsc.start();\n * triOsc.freq(220);\n *\n * cnv.mousePressed(playEnv);\n * }\n *\n * function playEnv() {\n * env.play();\n * }\n *
\n */\n p5.Envelope = function(t1, l1, t2, l2, t3, l3) {\n /**\n * Time until envelope reaches attackLevel\n * @property attackTime\n */\n this.aTime = t1 || 0.1;\n /**\n * Level once attack is complete.\n * @property attackLevel\n */\n this.aLevel = l1 || 1;\n /**\n * Time until envelope reaches decayLevel.\n * @property decayTime\n */\n this.dTime = t2 || 0.5;\n /**\n * Level after decay. The envelope will sustain here until it is released.\n * @property decayLevel\n */\n this.dLevel = l2 || 0;\n /**\n * Duration of the release portion of the envelope.\n * @property releaseTime\n */\n this.rTime = t3 || 0;\n /**\n * Level at the end of the release.\n * @property releaseLevel\n */\n this.rLevel = l3 || 0;\n\n this._rampHighPercentage = 0.98;\n\n this._rampLowPercentage = 0.02;\n\n\n this.output = p5sound.audiocontext.createGain();\n\n this.control = new TimelineSignal();\n\n this._init(); // this makes sure the envelope starts at zero\n\n this.control.connect(this.output); // connect to the output\n\n this.connection = null; // store connection\n\n //array of math operation signal chaining\n this.mathOps = [this.control];\n\n //whether envelope should be linear or exponential curve\n this.isExponential = false;\n\n // oscillator or buffer source to clear on env complete\n // to save resources if/when it is retriggered\n this.sourceToClear = null;\n\n // set to true if attack is set, then false on release\n this.wasTriggered = false;\n\n\n // add to the soundArray so we can dispose of the env later\n p5sound.soundArray.push(this);\n };\n\n // this init function just smooths the starting value to zero and gives a start point for the timeline\n // - it was necessary to remove glitches at the beginning.\n p5.Envelope.prototype._init = function () {\n var now = p5sound.audiocontext.currentTime;\n var t = now;\n this.control.setTargetAtTime(0.00001, t, .001);\n //also, compute the correct time constants\n this._setRampAD(this.aTime, this.dTime);\n };\n\n /**\n * Reset the envelope with a series of time/value pairs.\n *\n * @method set\n * @for p5.Envelope\n * @param {Number} attackTime Time (in seconds) before level\n * reaches attackLevel\n * @param {Number} attackLevel Typically an amplitude between\n * 0.0 and 1.0\n * @param {Number} decayTime Time\n * @param {Number} decayLevel Amplitude (In a standard ADSR envelope,\n * decayLevel = sustainLevel)\n * @param {Number} releaseTime Release Time (in seconds)\n * @param {Number} releaseLevel Amplitude\n * @example\n *
\n * var t1 = 0.1; // attack time in seconds\n * var l1 = 0.7; // attack level 0.0 to 1.0\n * var t2 = 0.3; // decay time in seconds\n * var l2 = 0.1; // decay level 0.0 to 1.0\n * var t3 = 0.2; // sustain time in seconds\n * var l3 = 0.5; // sustain level 0.0 to 1.0\n * // release level defaults to zero\n *\n * var env;\n * var triOsc;\n *\n * function setup() {\n * background(0);\n * noStroke();\n * fill(255);\n * textAlign(CENTER);\n * text('click to play', width/2, height/2);\n *\n * env = new p5.Envelope(t1, l1, t2, l2, t3, l3);\n * triOsc = new p5.Oscillator('triangle');\n * triOsc.amp(env); // give the env control of the triOsc's amp\n * triOsc.start();\n * }\n *\n * // mouseClick triggers envelope if over canvas\n * function mouseClicked() {\n * // is mouse over canvas?\n * if (mouseX > 0 && mouseX < width && mouseY > 0 && mouseY < height) {\n * env.play(triOsc);\n * }\n * }\n *
\n *\n */\n p5.Envelope.prototype.set = function(t1, l1, t2, l2, t3, l3) {\n this.aTime = t1;\n this.aLevel = l1;\n this.dTime = t2 || 0;\n this.dLevel = l2 || 0;\n this.rTime = t3 || 0;\n this.rLevel = l3 || 0;\n\n // set time constants for ramp\n this._setRampAD(t1, t2);\n };\n\n /**\n * Set values like a traditional\n * \n * ADSR envelope\n * .\n *\n * @method setADSR\n * @for p5.Envelope\n * @param {Number} attackTime Time (in seconds before envelope\n * reaches Attack Level\n * @param {Number} [decayTime] Time (in seconds) before envelope\n * reaches Decay/Sustain Level\n * @param {Number} [susRatio] Ratio between attackLevel and releaseLevel, on a scale from 0 to 1,\n * where 1.0 = attackLevel, 0.0 = releaseLevel.\n * The susRatio determines the decayLevel and the level at which the\n * sustain portion of the envelope will sustain.\n * For example, if attackLevel is 0.4, releaseLevel is 0,\n * and susAmt is 0.5, the decayLevel would be 0.2. If attackLevel is\n * increased to 1.0 (using setRange),\n * then decayLevel would increase proportionally, to become 0.5.\n * @param {Number} [releaseTime] Time in seconds from now (defaults to 0)\n * @example\n *
\n * var attackLevel = 1.0;\n * var releaseLevel = 0;\n *\n * var attackTime = 0.001;\n * var decayTime = 0.2;\n * var susPercent = 0.2;\n * var releaseTime = 0.5;\n *\n * var env, triOsc;\n *\n * function setup() {\n * var cnv = createCanvas(100, 100);\n *\n * textAlign(CENTER);\n * text('click to play', width/2, height/2);\n *\n * env = new p5.Envelope();\n * env.setADSR(attackTime, decayTime, susPercent, releaseTime);\n * env.setRange(attackLevel, releaseLevel);\n *\n * triOsc = new p5.Oscillator('triangle');\n * triOsc.amp(env);\n * triOsc.start();\n * triOsc.freq(220);\n *\n * cnv.mousePressed(playEnv);\n * }\n *\n * function playEnv() {\n * env.play();\n * }\n *
\n */\n p5.Envelope.prototype.setADSR = function(aTime, dTime, sPercent, rTime) {\n this.aTime = aTime;\n this.dTime = dTime || 0;\n\n // lerp\n this.sPercent = sPercent || 0;\n this.dLevel = typeof sPercent !== 'undefined' ? sPercent * (this.aLevel - this.rLevel) + this.rLevel : 0;\n\n this.rTime = rTime || 0;\n\n // also set time constants for ramp\n this._setRampAD(aTime, dTime);\n };\n\n /**\n * Set max (attackLevel) and min (releaseLevel) of envelope.\n *\n * @method setRange\n * @for p5.Envelope\n * @param {Number} aLevel attack level (defaults to 1)\n * @param {Number} rLevel release level (defaults to 0)\n * @example\n *
\n * var attackLevel = 1.0;\n * var releaseLevel = 0;\n *\n * var attackTime = 0.001;\n * var decayTime = 0.2;\n * var susPercent = 0.2;\n * var releaseTime = 0.5;\n *\n * var env, triOsc;\n *\n * function setup() {\n * var cnv = createCanvas(100, 100);\n *\n * textAlign(CENTER);\n * text('click to play', width/2, height/2);\n *\n * env = new p5.Envelope();\n * env.setADSR(attackTime, decayTime, susPercent, releaseTime);\n * env.setRange(attackLevel, releaseLevel);\n *\n * triOsc = new p5.Oscillator('triangle');\n * triOsc.amp(env);\n * triOsc.start();\n * triOsc.freq(220);\n *\n * cnv.mousePressed(playEnv);\n * }\n *\n * function playEnv() {\n * env.play();\n * }\n *
\n */\n p5.Envelope.prototype.setRange = function(aLevel, rLevel) {\n this.aLevel = aLevel || 1;\n this.rLevel = rLevel || 0;\n\n // not sure if this belongs here:\n\n // {Number} [dLevel] decay/sustain level (optional)\n // if (typeof(dLevel) !== 'undefined') {\n // this.dLevel = dLevel\n // } else if (this.sPercent) {\n // this.dLevel = this.sPercent ? this.sPercent * (this.aLevel - this.rLevel) + this.rLevel : 0;\n // }\n };\n\n // private (undocumented) method called when ADSR is set to set time constants for ramp\n //\n // Set the \n // time constants for simple exponential ramps.\n // The larger the time constant value, the slower the\n // transition will be.\n //\n // method _setRampAD\n // param {Number} attackTimeConstant attack time constant\n // param {Number} decayTimeConstant decay time constant\n //\n p5.Envelope.prototype._setRampAD = function(t1, t2) {\n this._rampAttackTime = this.checkExpInput(t1);\n this._rampDecayTime = this.checkExpInput(t2);\n\n var TCDenominator = 1.0;\n /// Aatish Bhatia's calculation for time constant for rise(to adjust 1/1-e calculation to any percentage)\n TCDenominator = Math.log(1.0 / this.checkExpInput(1.0 - this._rampHighPercentage));\n this._rampAttackTC = t1 / this.checkExpInput(TCDenominator);\n TCDenominator = Math.log(1.0 / this._rampLowPercentage);\n this._rampDecayTC = t2 / this.checkExpInput(TCDenominator);\n };\n\n // private method\n p5.Envelope.prototype.setRampPercentages = function(p1, p2) {\n //set the percentages that the simple exponential ramps go to\n this._rampHighPercentage = this.checkExpInput(p1);\n this._rampLowPercentage = this.checkExpInput(p2);\n var TCDenominator = 1.0;\n //now re-compute the time constants based on those percentages\n /// Aatish Bhatia's calculation for time constant for rise(to adjust 1/1-e calculation to any percentage)\n TCDenominator = Math.log(1.0 / this.checkExpInput(1.0 - this._rampHighPercentage));\n this._rampAttackTC = this._rampAttackTime / this.checkExpInput(TCDenominator);\n TCDenominator = Math.log(1.0 / this._rampLowPercentage);\n this._rampDecayTC = this._rampDecayTime / this.checkExpInput(TCDenominator);\n };\n\n\n /**\n * Assign a parameter to be controlled by this envelope.\n * If a p5.Sound object is given, then the p5.Envelope will control its\n * output gain. If multiple inputs are provided, the env will\n * control all of them.\n *\n * @method setInput\n * @for p5.Envelope\n * @param {Object} [...inputs] A p5.sound object or\n * Web Audio Param.\n */\n p5.Envelope.prototype.setInput = function() {\n for (var i = 0; i\n * Web Audio Audio Param.\n *\n * @method play\n * @for p5.Envelope\n * @param {Object} unit A p5.sound object or\n * Web Audio Param.\n * @param {Number} [startTime] time from now (in seconds) at which to play\n * @param {Number} [sustainTime] time to sustain before releasing the envelope\n * @example\n *
\n * var attackLevel = 1.0;\n * var releaseLevel = 0;\n *\n * var attackTime = 0.001;\n * var decayTime = 0.2;\n * var susPercent = 0.2;\n * var releaseTime = 0.5;\n *\n * var env, triOsc;\n *\n * function setup() {\n * var cnv = createCanvas(100, 100);\n *\n * textAlign(CENTER);\n * text('click to play', width/2, height/2);\n *\n * env = new p5.Envelope();\n * env.setADSR(attackTime, decayTime, susPercent, releaseTime);\n * env.setRange(attackLevel, releaseLevel);\n *\n * triOsc = new p5.Oscillator('triangle');\n * triOsc.amp(env);\n * triOsc.start();\n * triOsc.freq(220);\n *\n * cnv.mousePressed(playEnv);\n * }\n *\n * function playEnv() {\n * // trigger env on triOsc, 0 seconds from now\n * // After decay, sustain for 0.2 seconds before release\n * env.play(triOsc, 0, 0.2);\n * }\n *
\n */\n p5.Envelope.prototype.play = function(unit, secondsFromNow, susTime) {\n var tFromNow = secondsFromNow || 0;\n var susTime = susTime || 0;\n\n if (unit) {\n if (this.connection !== unit) {\n this.connect(unit);\n }\n }\n\n this.triggerAttack(unit, tFromNow);\n\n this.triggerRelease(unit, tFromNow + this.aTime + this.dTime + susTime);\n\n };\n\n /**\n * Trigger the Attack, and Decay portion of the Envelope.\n * Similar to holding down a key on a piano, but it will\n * hold the sustain level until you let go. Input can be\n * any p5.sound object, or a \n * Web Audio Param.\n *\n * @method triggerAttack\n * @for p5.Envelope\n * @param {Object} unit p5.sound Object or Web Audio Param\n * @param {Number} secondsFromNow time from now (in seconds)\n * @example\n *
\n *\n * var attackLevel = 1.0;\n * var releaseLevel = 0;\n *\n * var attackTime = 0.001;\n * var decayTime = 0.3;\n * var susPercent = 0.4;\n * var releaseTime = 0.5;\n *\n * var env, triOsc;\n *\n * function setup() {\n * var cnv = createCanvas(100, 100);\n * background(200);\n * textAlign(CENTER);\n * text('click to play', width/2, height/2);\n *\n * env = new p5.Envelope();\n * env.setADSR(attackTime, decayTime, susPercent, releaseTime);\n * env.setRange(attackLevel, releaseLevel);\n *\n * triOsc = new p5.Oscillator('triangle');\n * triOsc.amp(env);\n * triOsc.start();\n * triOsc.freq(220);\n *\n * cnv.mousePressed(envAttack);\n * }\n *\n * function envAttack() {\n * console.log('trigger attack');\n * env.triggerAttack();\n *\n * background(0,255,0);\n * text('attack!', width/2, height/2);\n * }\n *\n * function mouseReleased() {\n * env.triggerRelease();\n *\n * background(200);\n * text('click to play', width/2, height/2);\n * }\n *
\n */\n p5.Envelope.prototype.triggerAttack = function(unit, secondsFromNow) {\n var now = p5sound.audiocontext.currentTime;\n var tFromNow = secondsFromNow || 0;\n var t = now + tFromNow;\n this.lastAttack = t;\n this.wasTriggered = true;\n\n if (unit) {\n if (this.connection !== unit) {\n this.connect(unit);\n }\n }\n\n // get and set value (with linear ramp) to anchor automation\n var valToSet = this.control.getValueAtTime(t);\n\n if (this.isExponential === true)\n {\n this.control.exponentialRampToValueAtTime(this.checkExpInput(valToSet), t);\n }\n else\n {\n this.control.linearRampToValueAtTime(valToSet, t);\n }\n\n // after each ramp completes, cancel scheduled values\n // (so they can be overridden in case env has been re-triggered)\n // then, set current value (with linearRamp to avoid click)\n // then, schedule the next automation...\n\n // attack\n t += this.aTime;\n if (this.isExponential === true)\n {\n this.control.exponentialRampToValueAtTime(this.checkExpInput(this.aLevel), t);\n valToSet = this.checkExpInput(this.control.getValueAtTime(t));\n this.control.cancelScheduledValues(t);\n this.control.exponentialRampToValueAtTime(valToSet, t);\n }\n else\n {\n this.control.linearRampToValueAtTime(this.aLevel, t);\n valToSet = this.control.getValueAtTime(t);\n this.control.cancelScheduledValues(t);\n this.control.linearRampToValueAtTime(valToSet, t);\n\n }\n\n // decay to decay level (if using ADSR, then decay level == sustain level)\n t += this.dTime;\n if (this.isExponential === true)\n {\n this.control.exponentialRampToValueAtTime(this.checkExpInput(this.dLevel), t);\n valToSet = this.checkExpInput(this.control.getValueAtTime(t));\n this.control.cancelScheduledValues(t);\n this.control.exponentialRampToValueAtTime(valToSet, t);\n }\n else\n {\n this.control.linearRampToValueAtTime(this.dLevel, t);\n valToSet = this.control.getValueAtTime(t);\n this.control.cancelScheduledValues(t);\n this.control.linearRampToValueAtTime(valToSet, t);\n }\n };\n\n /**\n * Trigger the Release of the Envelope. This is similar to releasing\n * the key on a piano and letting the sound fade according to the\n * release level and release time.\n *\n * @method triggerRelease\n * @for p5.Envelope\n * @param {Object} unit p5.sound Object or Web Audio Param\n * @param {Number} secondsFromNow time to trigger the release\n * @example\n *
\n *\n * var attackLevel = 1.0;\n * var releaseLevel = 0;\n *\n * var attackTime = 0.001;\n * var decayTime = 0.3;\n * var susPercent = 0.4;\n * var releaseTime = 0.5;\n *\n * var env, triOsc;\n *\n * function setup() {\n * var cnv = createCanvas(100, 100);\n * background(200);\n * textAlign(CENTER);\n * text('click to play', width/2, height/2);\n *\n * env = new p5.Envelope();\n * env.setADSR(attackTime, decayTime, susPercent, releaseTime);\n * env.setRange(attackLevel, releaseLevel);\n *\n * triOsc = new p5.Oscillator('triangle');\n * triOsc.amp(env);\n * triOsc.start();\n * triOsc.freq(220);\n *\n * cnv.mousePressed(envAttack);\n * }\n *\n * function envAttack() {\n * console.log('trigger attack');\n * env.triggerAttack();\n *\n * background(0,255,0);\n * text('attack!', width/2, height/2);\n * }\n *\n * function mouseReleased() {\n * env.triggerRelease();\n *\n * background(200);\n * text('click to play', width/2, height/2);\n * }\n *
\n */\n p5.Envelope.prototype.triggerRelease = function(unit, secondsFromNow) {\n\n // only trigger a release if an attack was triggered\n if (!this.wasTriggered) {\n // this currently causes a bit of trouble:\n // if a later release has been scheduled (via the play function)\n // a new earlier release won't interrupt it, because\n // this.wasTriggered has already been set to false.\n // If we want new earlier releases to override, then we need to\n // keep track of the last release time, and if the new release time is\n // earlier, then use it.\n return;\n }\n\n var now = p5sound.audiocontext.currentTime;\n var tFromNow = secondsFromNow || 0;\n var t = now + tFromNow;\n\n if (unit) {\n if (this.connection !== unit) {\n this.connect(unit);\n }\n }\n\n // get and set value (with linear or exponential ramp) to anchor automation\n var valToSet = this.control.getValueAtTime(t);\n if (this.isExponential === true)\n {\n this.control.exponentialRampToValueAtTime(this.checkExpInput(valToSet), t);\n }\n else\n {\n this.control.linearRampToValueAtTime(valToSet, t);\n }\n\n // release\n t += this.rTime;\n\n if (this.isExponential === true)\n {\n this.control.exponentialRampToValueAtTime(this.checkExpInput(this.rLevel), t);\n valToSet = this.checkExpInput(this.control.getValueAtTime(t));\n this.control.cancelScheduledValues(t);\n this.control.exponentialRampToValueAtTime(valToSet, t);\n }\n else\n {\n this.control.linearRampToValueAtTime(this.rLevel, t);\n valToSet = this.control.getValueAtTime(t);\n this.control.cancelScheduledValues(t);\n this.control.linearRampToValueAtTime(valToSet, t);\n }\n\n this.wasTriggered = false;\n };\n\n /**\n * Exponentially ramp to a value using the first two\n * values from setADSR(attackTime, decayTime)\n * as \n * time constants for simple exponential ramps.\n * If the value is higher than current value, it uses attackTime,\n * while a decrease uses decayTime.\n *\n * @method ramp\n * @for p5.Envelope\n * @param {Object} unit p5.sound Object or Web Audio Param\n * @param {Number} secondsFromNow When to trigger the ramp\n * @param {Number} v Target value\n * @param {Number} [v2] Second target value (optional)\n * @example\n *
\n * var env, osc, amp, cnv;\n *\n * var attackTime = 0.001;\n * var decayTime = 0.2;\n * var attackLevel = 1;\n * var decayLevel = 0;\n *\n * function setup() {\n * cnv = createCanvas(100, 100);\n * fill(0,255,0);\n * noStroke();\n *\n * env = new p5.Envelope();\n * env.setADSR(attackTime, decayTime);\n *\n * osc = new p5.Oscillator();\n * osc.amp(env);\n * osc.start();\n *\n * amp = new p5.Amplitude();\n *\n * cnv.mousePressed(triggerRamp);\n * }\n *\n * function triggerRamp() {\n * env.ramp(osc, 0, attackLevel, decayLevel);\n * }\n *\n * function draw() {\n * background(20,20,20);\n * text('click me', 10, 20);\n * var h = map(amp.getLevel(), 0, 0.4, 0, height);;\n *\n * rect(0, height, width, -h);\n * }\n *
\n */\n p5.Envelope.prototype.ramp = function(unit, secondsFromNow, v1, v2) {\n\n var now = p5sound.audiocontext.currentTime;\n var tFromNow = secondsFromNow || 0;\n var t = now + tFromNow;\n var destination1 = this.checkExpInput(v1);\n var destination2 = typeof v2 !== 'undefined' ? this.checkExpInput(v2) : undefined;\n\n // connect env to unit if not already connected\n if (unit) {\n if (this.connection !== unit) {\n this.connect(unit);\n }\n }\n\n //get current value\n var currentVal = this.checkExpInput(this.control.getValueAtTime(t));\n // this.control.cancelScheduledValues(t);\n\n //if it's going up\n if (destination1 > currentVal) {\n this.control.setTargetAtTime(destination1, t, this._rampAttackTC);\n t += this._rampAttackTime;\n }\n\n //if it's going down\n else if (destination1 < currentVal) {\n this.control.setTargetAtTime(destination1, t, this._rampDecayTC);\n t += this._rampDecayTime;\n }\n\n // Now the second part of envelope begins\n if (destination2 === undefined) return;\n\n //if it's going up\n if (destination2 > destination1) {\n this.control.setTargetAtTime(destination2, t, this._rampAttackTC);\n }\n\n //if it's going down\n else if (destination2 < destination1) {\n this.control.setTargetAtTime(destination2, t, this._rampDecayTC);\n }\n };\n\n\n p5.Envelope.prototype.connect = function(unit) {\n this.connection = unit;\n\n // assume we're talking about output gain\n // unless given a different audio param\n if (unit instanceof p5.Oscillator ||\n unit instanceof p5.SoundFile ||\n unit instanceof p5.AudioIn ||\n unit instanceof p5.Reverb ||\n unit instanceof p5.Noise ||\n unit instanceof p5.Filter ||\n unit instanceof p5.Delay\n ) {\n unit = unit.output.gain;\n }\n if (unit instanceof AudioParam) {\n //set the initial value\n unit.setValueAtTime(0, p5sound.audiocontext.currentTime);\n }\n if (unit instanceof p5.Signal) {\n unit.setValue(0);\n }\n this.output.connect(unit);\n };\n\n p5.Envelope.prototype.disconnect = function() {\n if (this.output) {\n this.output.disconnect();\n }\n };\n\n\n // Signal Math\n\n /**\n * Add a value to the p5.Oscillator's output amplitude,\n * and return the oscillator. Calling this method\n * again will override the initial add() with new values.\n *\n * @method add\n * @for p5.Envelope\n * @param {Number} number Constant number to add\n * @return {p5.Envelope} Envelope Returns this envelope\n * with scaled output\n */\n p5.Envelope.prototype.add = function(num) {\n var add = new Add(num);\n var thisChain = this.mathOps.length;\n var nextChain = this.output;\n return p5.prototype._mathChain(this, add, thisChain, nextChain, Add);\n };\n\n /**\n * Multiply the p5.Envelope's output amplitude\n * by a fixed value. Calling this method\n * again will override the initial mult() with new values.\n *\n * @method mult\n * @for p5.Envelope\n * @param {Number} number Constant number to multiply\n * @return {p5.Envelope} Envelope Returns this envelope\n * with scaled output\n */\n p5.Envelope.prototype.mult = function(num) {\n var mult = new Mult(num);\n var thisChain = this.mathOps.length;\n var nextChain = this.output;\n return p5.prototype._mathChain(this, mult, thisChain, nextChain, Mult);\n };\n\n /**\n * Scale this envelope's amplitude values to a given\n * range, and return the envelope. Calling this method\n * again will override the initial scale() with new values.\n *\n * @method scale\n * @for p5.Envelope\n * @param {Number} inMin input range minumum\n * @param {Number} inMax input range maximum\n * @param {Number} outMin input range minumum\n * @param {Number} outMax input range maximum\n * @return {p5.Envelope} Envelope Returns this envelope\n * with scaled output\n */\n p5.Envelope.prototype.scale = function(inMin, inMax, outMin, outMax) {\n var scale = new Scale(inMin, inMax, outMin, outMax);\n var thisChain = this.mathOps.length;\n var nextChain = this.output;\n return p5.prototype._mathChain(this, scale, thisChain, nextChain, Scale);\n };\n\n\n // get rid of the oscillator\n p5.Envelope.prototype.dispose = function() {\n // remove reference from soundArray\n var index = p5sound.soundArray.indexOf(this);\n p5sound.soundArray.splice(index, 1);\n\n this.disconnect();\n if (this.control) {\n this.control.dispose();\n this.control = null;\n }\n for (var i = 1; i < this.mathOps.length; i++) {\n this.mathOps[i].dispose();\n }\n };\n\n // Different name for backwards compatibility, replicates p5.Envelope class\n p5.Env = function(t1, l1, t2, l2, t3, l3) {\n console.warn('WARNING: p5.Env is now deprecated and may be removed in future versions. ' +\n 'Please use the new p5.Envelope instead.');\n p5.Envelope.call(this, t1, l1, t2, l2, t3, l3);\n };\n p5.Env.prototype = Object.create(p5.Envelope.prototype);\n\n});\n","'use strict';\n\ndefine(function (require) {\n\n var p5sound = require('master');\n require('oscillator');\n\n /**\n * Creates a Pulse object, an oscillator that implements\n * Pulse Width Modulation.\n * The pulse is created with two oscillators.\n * Accepts a parameter for frequency, and to set the\n * width between the pulses. See \n * p5.Oscillator for a full list of methods.\n *\n * @class p5.Pulse\n * @extends p5.Oscillator\n * @constructor\n * @param {Number} [freq] Frequency in oscillations per second (Hz)\n * @param {Number} [w] Width between the pulses (0 to 1.0,\n * defaults to 0)\n * @example\n *
Note: This uses the getUserMedia/\n * Stream API, which is not supported by certain browsers. Access in Chrome browser\n * is limited to localhost and https, but access over http may be limited.
\n *\n * @class p5.AudioIn\n * @constructor\n * @param {Function} [errorCallback] A function to call if there is an error\n * accessing the AudioIn. For example,\n * Safari and iOS devices do not\n * currently allow microphone access.\n * @example\n *
\n * var mic;\n * function setup(){\n * mic = new p5.AudioIn()\n * mic.start();\n * }\n * function draw(){\n * background(0);\n * micLevel = mic.getLevel();\n * ellipse(width/2, constrain(height-micLevel*height*5, 0, height), 10, 10);\n * }\n *
\n */\n p5.AudioIn = function(errorCallback) {\n // set up audio input\n /**\n * @property {GainNode} input\n */\n this.input = p5sound.audiocontext.createGain();\n /**\n * @property {GainNode} output\n */\n this.output = p5sound.audiocontext.createGain();\n\n /**\n * @property {MediaStream|null} stream\n */\n this.stream = null;\n /**\n * @property {MediaStreamAudioSourceNode|null} mediaStream\n */\n this.mediaStream = null;\n /**\n * @property {Number|null} currentSource\n */\n this.currentSource = null;\n\n /**\n * Client must allow browser to access their microphone / audioin source.\n * Default: false. Will become true when the client enables acces.\n *\n * @property {Boolean} enabled\n */\n this.enabled = false;\n\n /**\n * Input amplitude, connect to it by default but not to master out\n *\n * @property {p5.Amplitude} amplitude\n */\n this.amplitude = new p5.Amplitude();\n this.output.connect(this.amplitude.input);\n\n if (!window.MediaStreamTrack || !window.navigator.mediaDevices || !window.navigator.mediaDevices.getUserMedia) {\n errorCallback ? errorCallback() : window.alert('This browser does not support MediaStreamTrack and mediaDevices');\n }\n\n // add to soundArray so we can dispose on close\n p5sound.soundArray.push(this);\n };\n\n /**\n * Start processing audio input. This enables the use of other\n * AudioIn methods like getLevel(). Note that by default, AudioIn\n * is not connected to p5.sound's output. So you won't hear\n * anything unless you use the connect() method. \n *\n * Certain browsers limit access to the user's microphone. For example,\n * Chrome only allows access from localhost and over https. For this reason,\n * you may want to include an errorCallback—a function that is called in case\n * the browser won't provide mic access.\n *\n * @method start\n * @for p5.AudioIn\n * @param {Function} [successCallback] Name of a function to call on\n * success.\n * @param {Function} [errorCallback] Name of a function to call if\n * there was an error. For example,\n * some browsers do not support\n * getUserMedia.\n */\n p5.AudioIn.prototype.start = function(successCallback, errorCallback) {\n var self = this;\n\n if (this.stream) {\n this.stop();\n }\n\n // set the audio source\n var audioSource = p5sound.inputSources[self.currentSource];\n var constraints = {\n audio: {\n sampleRate: p5sound.audiocontext.sampleRate,\n echoCancellation: false\n }\n };\n\n // if developers determine which source to use\n if (p5sound.inputSources[this.currentSource]) {\n constraints.audio.deviceId = audioSource.deviceId;\n }\n\n window.navigator.mediaDevices.getUserMedia( constraints )\n .then( function(stream) {\n self.stream = stream;\n self.enabled = true;\n // Wrap a MediaStreamSourceNode around the live input\n self.mediaStream = p5sound.audiocontext.createMediaStreamSource(stream);\n self.mediaStream.connect(self.output);\n // only send to the Amplitude reader, so we can see it but not hear it.\n self.amplitude.setInput(self.output);\n if (successCallback) successCallback();\n })\n .catch( function(err) {\n if (errorCallback) errorCallback(err);\n else console.error(err);\n });\n };\n\n /**\n * Turn the AudioIn off. If the AudioIn is stopped, it cannot getLevel().\n * If re-starting, the user may be prompted for permission access.\n *\n * @method stop\n * @for p5.AudioIn\n */\n p5.AudioIn.prototype.stop = function() {\n if (this.stream) {\n this.stream.getTracks().forEach(function(track) {\n track.stop();\n });\n\n this.mediaStream.disconnect();\n\n delete this.mediaStream;\n delete this.stream;\n }\n };\n\n /**\n * Connect to an audio unit. If no parameter is provided, will\n * connect to the master output (i.e. your speakers). \n *\n * @method connect\n * @for p5.AudioIn\n * @param {Object} [unit] An object that accepts audio input,\n * such as an FFT\n */\n p5.AudioIn.prototype.connect = function(unit) {\n if (unit) {\n if (unit.hasOwnProperty('input')) {\n this.output.connect(unit.input);\n }\n else if (unit.hasOwnProperty('analyser')) {\n this.output.connect(unit.analyser);\n }\n else {\n this.output.connect(unit);\n }\n }\n else {\n this.output.connect(p5sound.input);\n }\n };\n\n /**\n * Disconnect the AudioIn from all audio units. For example, if\n * connect() had been called, disconnect() will stop sending\n * signal to your speakers. \n *\n * @method disconnect\n * @for p5.AudioIn\n */\n p5.AudioIn.prototype.disconnect = function() {\n if (this.output) {\n this.output.disconnect();\n // stay connected to amplitude even if not outputting to p5\n this.output.connect(this.amplitude.input);\n }\n };\n\n /**\n * Read the Amplitude (volume level) of an AudioIn. The AudioIn\n * class contains its own instance of the Amplitude class to help\n * make it easy to get a microphone's volume level. Accepts an\n * optional smoothing value (0.0 < 1.0). NOTE: AudioIn must\n * .start() before using .getLevel(). \n *\n * @method getLevel\n * @for p5.AudioIn\n * @param {Number} [smoothing] Smoothing is 0.0 by default.\n * Smooths values based on previous values.\n * @return {Number} Volume level (between 0.0 and 1.0)\n */\n p5.AudioIn.prototype.getLevel = function(smoothing) {\n if (smoothing) {\n this.amplitude.smoothing = smoothing;\n }\n return this.amplitude.getLevel();\n };\n\n /**\n * Set amplitude (volume) of a mic input between 0 and 1.0. \n *\n * @method amp\n * @for p5.AudioIn\n * @param {Number} vol between 0 and 1.0\n * @param {Number} [time] ramp time (optional)\n */\n p5.AudioIn.prototype.amp = function(vol, t) {\n if (t) {\n var rampTime = t || 0;\n var currentVol = this.output.gain.value;\n this.output.gain.cancelScheduledValues(p5sound.audiocontext.currentTime);\n this.output.gain.setValueAtTime(currentVol, p5sound.audiocontext.currentTime);\n this.output.gain.linearRampToValueAtTime(vol, rampTime + p5sound.audiocontext.currentTime);\n } else {\n this.output.gain.cancelScheduledValues(p5sound.audiocontext.currentTime);\n this.output.gain.setValueAtTime(vol, p5sound.audiocontext.currentTime);\n }\n };\n\n /**\n * Returns a list of available input sources. This is a wrapper\n * for and it returns a Promise.\n *\n * @method getSources\n * @for p5.AudioIn\n * @param {Function} [successCallback] This callback function handles the sources when they\n * have been enumerated. The callback function\n * receives the deviceList array as its only argument\n * @param {Function} [errorCallback] This optional callback receives the error\n * message as its argument.\n * @returns {Promise} Returns a Promise that can be used in place of the callbacks, similar\n * to the enumerateDevices() method\n * @example\n *
\n */\n p5.AudioIn.prototype.getSources = function (onSuccess, onError) {\n return new Promise( function(resolve, reject) {\n window.navigator.mediaDevices.enumerateDevices()\n .then( function(devices) {\n p5sound.inputSources = devices.filter(function(device) {\n return device.kind === 'audioinput';\n });\n resolve(p5sound.inputSources);\n if (onSuccess) {\n onSuccess(p5sound.inputSources);\n }\n })\n .catch( function(error) {\n reject(error);\n if (onError) {\n onError(error);\n } else {\n console.error('This browser does not support MediaStreamTrack.getSources()');\n }\n });\n });\n };\n\n /**\n * Set the input source. Accepts a number representing a\n * position in the array returned by getSources().\n * This is only available in browsers that support\n * navigator.mediaDevices.enumerateDevices(). \n *\n * @method setSource\n * @for p5.AudioIn\n * @param {number} num position of input source in the array\n */\n p5.AudioIn.prototype.setSource = function(num) {\n if (p5sound.inputSources.length > 0 && num < p5sound.inputSources.length) {\n // set the current source\n this.currentSource = num;\n console.log('set source to ', p5sound.inputSources[this.currentSource]);\n } else {\n console.log('unable to set input source');\n }\n\n // restart stream if currently active\n if (this.stream && this.stream.active) {\n this.start();\n }\n };\n\n // private method\n p5.AudioIn.prototype.dispose = function() {\n // remove reference from soundArray\n var index = p5sound.soundArray.indexOf(this);\n p5sound.soundArray.splice(index, 1);\n\n this.stop();\n\n if (this.output) {\n this.output.disconnect();\n }\n if (this.amplitude) {\n this.amplitude.disconnect();\n }\n delete this.amplitude;\n delete this.output;\n };\n\n});\n","define([\"Tone/core/Tone\", \"Tone/signal/Signal\", \"Tone/signal/Expr\", \n\t\"Tone/signal/EqualPowerGain\", \"Tone/core/Gain\"], function(Tone){\n\n\t\"use strict\";\n\n\t/**\n\t * @class Tone.Crossfade provides equal power fading between two inputs. \n\t * More on crossfading technique [here](https://en.wikipedia.org/wiki/Fade_(audio_engineering)#Crossfading).\n\t *\n\t * @constructor\n\t * @extends {Tone}\n\t * @param {NormalRange} [initialFade=0.5]\n\t * @example\n\t * var crossFade = new Tone.CrossFade(0.5);\n\t * //connect effect A to crossfade from\n\t * //effect output 0 to crossfade input 0\n\t * effectA.connect(crossFade, 0, 0);\n\t * //connect effect B to crossfade from\n\t * //effect output 0 to crossfade input 1\n\t * effectB.connect(crossFade, 0, 1);\n\t * crossFade.fade.value = 0;\n\t * // ^ only effectA is output\n\t * crossFade.fade.value = 1;\n\t * // ^ only effectB is output\n\t * crossFade.fade.value = 0.5;\n\t * // ^ the two signals are mixed equally. \n\t */\t\t\n\tTone.CrossFade = function(initialFade){\n\n\t\tthis.createInsOuts(2, 1);\n\n\t\t/**\n\t\t * Alias for input[0]. \n\t\t * @type {Tone.Gain}\n\t\t */\n\t\tthis.a = this.input[0] = new Tone.Gain();\n\n\t\t/**\n\t\t * Alias for input[1]. \n\t\t * @type {Tone.Gain}\n\t\t */\n\t\tthis.b = this.input[1] = new Tone.Gain();\n\n\t\t/**\n\t\t * \tThe mix between the two inputs. A fade value of 0\n\t\t * \twill output 100% input[0] and \n\t\t * \ta value of 1 will output 100% input[1]. \n\t\t * @type {NormalRange}\n\t\t * @signal\n\t\t */\n\t\tthis.fade = new Tone.Signal(this.defaultArg(initialFade, 0.5), Tone.Type.NormalRange);\n\n\t\t/**\n\t\t * equal power gain cross fade\n\t\t * @private\n\t\t * @type {Tone.EqualPowerGain}\n\t\t */\n\t\tthis._equalPowerA = new Tone.EqualPowerGain();\n\n\t\t/**\n\t\t * equal power gain cross fade\n\t\t * @private\n\t\t * @type {Tone.EqualPowerGain}\n\t\t */\n\t\tthis._equalPowerB = new Tone.EqualPowerGain();\n\t\t\n\t\t/**\n\t\t * invert the incoming signal\n\t\t * @private\n\t\t * @type {Tone}\n\t\t */\n\t\tthis._invert = new Tone.Expr(\"1 - $0\");\n\n\t\t//connections\n\t\tthis.a.connect(this.output);\n\t\tthis.b.connect(this.output);\n\t\tthis.fade.chain(this._equalPowerB, this.b.gain);\n\t\tthis.fade.chain(this._invert, this._equalPowerA, this.a.gain);\n\t\tthis._readOnly(\"fade\");\n\t};\n\n\tTone.extend(Tone.CrossFade);\n\n\t/**\n\t * clean up\n\t * @returns {Tone.CrossFade} this\n\t */\n\tTone.CrossFade.prototype.dispose = function(){\n\t\tTone.prototype.dispose.call(this);\n\t\tthis._writable(\"fade\");\n\t\tthis._equalPowerA.dispose();\n\t\tthis._equalPowerA = null;\n\t\tthis._equalPowerB.dispose();\n\t\tthis._equalPowerB = null;\n\t\tthis.fade.dispose();\n\t\tthis.fade = null;\n\t\tthis._invert.dispose();\n\t\tthis._invert = null;\n\t\tthis.a.dispose();\n\t\tthis.a = null;\n\t\tthis.b.dispose();\n\t\tthis.b = null;\n\t\treturn this;\n\t};\n\n\treturn Tone.CrossFade;\n});\n","define([\"Tone/core/Tone\", \"Tone/signal/Add\", \"Tone/signal/Subtract\", \"Tone/signal/Multiply\", \n\t\"Tone/signal/GreaterThan\", \"Tone/signal/GreaterThanZero\", \"Tone/signal/Abs\", \"Tone/signal/Negate\", \n\t\"Tone/signal/Modulo\", \"Tone/signal/Pow\", \"Tone/signal/AudioToGain\"], \n\tfunction(Tone){\n\n\t\"use strict\";\n\n\t/**\n\t * @class Evaluate an expression at audio rate.
\n\t * Parsing code modified from https://code.google.com/p/tapdigit/\n\t * Copyright 2011 2012 Ariya Hidayat, New BSD License\n\t *\n\t * @extends {Tone.SignalBase}\n\t * @constructor\n\t * @param {string} expr the expression to generate\n\t * @example\n\t * //adds the signals from input[0] and input[1].\n\t * var expr = new Tone.Expr(\"$0 + $1\");\n\t */\n\tTone.Expr = function(){\n\n\t\tvar expr = this._replacements(Array.prototype.slice.call(arguments));\n\t\tvar inputCount = this._parseInputs(expr);\n\n\t\t/**\n\t\t * hold onto all of the nodes for disposal\n\t\t * @type {Array}\n\t\t * @private\n\t\t */\n\t\tthis._nodes = [];\n\n\t\t/**\n\t\t * The inputs. The length is determined by the expression. \n\t\t * @type {Array}\n\t\t */\n\t\tthis.input = new Array(inputCount);\n\n\t\t//create a gain for each input\n\t\tfor (var i = 0; i < inputCount; i++){\n\t\t\tthis.input[i] = this.context.createGain();\n\t\t}\n\n\t\t//parse the syntax tree\n\t\tvar tree = this._parseTree(expr);\n\t\t//evaluate the results\n\t\tvar result;\n\t\ttry {\n\t\t\tresult = this._eval(tree);\n\t\t} catch (e){\n\t\t\tthis._disposeNodes();\n\t\t\tthrow new Error(\"Tone.Expr: Could evaluate expression: \"+expr);\n\t\t}\n\n\t\t/**\n\t\t * The output node is the result of the expression\n\t\t * @type {Tone}\n\t\t */\n\t\tthis.output = result;\n\t};\n\n\tTone.extend(Tone.Expr, Tone.SignalBase);\n\n\t//some helpers to cut down the amount of code\n\tfunction applyBinary(Constructor, args, self){\n\t\tvar op = new Constructor();\n\t\tself._eval(args[0]).connect(op, 0, 0);\n\t\tself._eval(args[1]).connect(op, 0, 1);\n\t\treturn op;\n\t}\n\tfunction applyUnary(Constructor, args, self){\n\t\tvar op = new Constructor();\n\t\tself._eval(args[0]).connect(op, 0, 0);\n\t\treturn op;\n\t}\n\tfunction getNumber(arg){\n\t\treturn arg ? parseFloat(arg) : undefined;\n\t}\n\tfunction literalNumber(arg){\n\t\treturn arg && arg.args ? parseFloat(arg.args) : undefined;\n\t}\n\n\t/*\n\t * the Expressions that Tone.Expr can parse.\n\t *\n\t * each expression belongs to a group and contains a regexp \n\t * for selecting the operator as well as that operators method\n\t * \n\t * @type {Object}\n\t * @private\n\t */\n\tTone.Expr._Expressions = {\n\t\t//values\n\t\t\"value\" : {\n\t\t\t\"signal\" : {\n\t\t\t\tregexp : /^\\d+\\.\\d+|^\\d+/,\n\t\t\t\tmethod : function(arg){\n\t\t\t\t\tvar sig = new Tone.Signal(getNumber(arg));\n\t\t\t\t\treturn sig;\n\t\t\t\t}\n\t\t\t},\n\t\t\t\"input\" : {\n\t\t\t\tregexp : /^\\$\\d/,\n\t\t\t\tmethod : function(arg, self){\n\t\t\t\t\treturn self.input[getNumber(arg.substr(1))];\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\t\t//syntactic glue\n\t\t\"glue\" : {\n\t\t\t\"(\" : {\n\t\t\t\tregexp : /^\\(/,\n\t\t\t},\n\t\t\t\")\" : {\n\t\t\t\tregexp : /^\\)/,\n\t\t\t},\n\t\t\t\",\" : {\n\t\t\t\tregexp : /^,/,\n\t\t\t}\n\t\t},\n\t\t//functions\n\t\t\"func\" : {\n\t\t\t\"abs\" : {\n\t\t\t\tregexp : /^abs/,\n\t\t\t\tmethod : applyUnary.bind(this, Tone.Abs)\n\t\t\t},\n\t\t\t\"mod\" : {\n\t\t\t\tregexp : /^mod/,\n\t\t\t\tmethod : function(args, self){\n\t\t\t\t\tvar modulus = literalNumber(args[1]);\n\t\t\t\t\tvar op = new Tone.Modulo(modulus);\n\t\t\t\t\tself._eval(args[0]).connect(op);\n\t\t\t\t\treturn op;\n\t\t\t\t}\n\t\t\t},\n\t\t\t\"pow\" : {\n\t\t\t\tregexp : /^pow/,\n\t\t\t\tmethod : function(args, self){\n\t\t\t\t\tvar exp = literalNumber(args[1]);\n\t\t\t\t\tvar op = new Tone.Pow(exp);\n\t\t\t\t\tself._eval(args[0]).connect(op);\n\t\t\t\t\treturn op;\n\t\t\t\t}\n\t\t\t},\n\t\t\t\"a2g\" : {\n\t\t\t\tregexp : /^a2g/,\n\t\t\t\tmethod : function(args, self){\n\t\t\t\t\tvar op = new Tone.AudioToGain();\n\t\t\t\t\tself._eval(args[0]).connect(op);\n\t\t\t\t\treturn op;\n\t\t\t\t}\n\t\t\t},\n\t\t},\n\t\t//binary expressions\n\t\t\"binary\" : {\n\t\t\t\"+\" : {\n\t\t\t\tregexp : /^\\+/,\n\t\t\t\tprecedence : 1,\n\t\t\t\tmethod : applyBinary.bind(this, Tone.Add)\n\t\t\t},\n\t\t\t\"-\" : {\n\t\t\t\tregexp : /^\\-/,\n\t\t\t\tprecedence : 1,\n\t\t\t\tmethod : function(args, self){\n\t\t\t\t\t//both unary and binary op\n\t\t\t\t\tif (args.length === 1){\n\t\t\t\t\t\treturn applyUnary(Tone.Negate, args, self);\n\t\t\t\t\t} else {\n\t\t\t\t\t\treturn applyBinary(Tone.Subtract, args, self);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t},\n\t\t\t\"*\" : {\n\t\t\t\tregexp : /^\\*/,\n\t\t\t\tprecedence : 0,\n\t\t\t\tmethod : applyBinary.bind(this, Tone.Multiply)\n\t\t\t}\n\t\t},\n\t\t//unary expressions\n\t\t\"unary\" : {\n\t\t\t\"-\" : {\n\t\t\t\tregexp : /^\\-/,\n\t\t\t\tmethod : applyUnary.bind(this, Tone.Negate)\n\t\t\t},\n\t\t\t\"!\" : {\n\t\t\t\tregexp : /^\\!/,\n\t\t\t\tmethod : applyUnary.bind(this, Tone.NOT)\n\t\t\t},\n\t\t},\n\t};\n\t\t\n\t/**\n\t * @param {string} expr the expression string\n\t * @return {number} the input count\n\t * @private\n\t */\n\tTone.Expr.prototype._parseInputs = function(expr){\n\t\tvar inputArray = expr.match(/\\$\\d/g);\n\t\tvar inputMax = 0;\n\t\tif (inputArray !== null){\n\t\t\tfor (var i = 0; i < inputArray.length; i++){\n\t\t\t\tvar inputNum = parseInt(inputArray[i].substr(1)) + 1;\n\t\t\t\tinputMax = Math.max(inputMax, inputNum);\n\t\t\t}\n\t\t}\n\t\treturn inputMax;\n\t};\n\n\t/**\n\t * @param {Array} args \tan array of arguments\n\t * @return {string} the results of the replacements being replaced\n\t * @private\n\t */\n\tTone.Expr.prototype._replacements = function(args){\n\t\tvar expr = args.shift();\n\t\tfor (var i = 0; i < args.length; i++){\n\t\t\texpr = expr.replace(/\\%/i, args[i]);\n\t\t}\n\t\treturn expr;\n\t};\n\n\t/**\n\t * tokenize the expression based on the Expressions object\n\t * @param {string} expr \n\t * @return {Object} returns two methods on the tokenized list, next and peek\n\t * @private\n\t */\n\tTone.Expr.prototype._tokenize = function(expr){\n\t\tvar position = -1;\n\t\tvar tokens = [];\n\n\t\twhile(expr.length > 0){\n\t\t\texpr = expr.trim();\n\t\t\tvar token = getNextToken(expr);\n\t\t\ttokens.push(token);\n\t\t\texpr = expr.substr(token.value.length);\n\t\t}\n\n\t\tfunction getNextToken(expr){\n\t\t\tfor (var type in Tone.Expr._Expressions){\n\t\t\t\tvar group = Tone.Expr._Expressions[type];\n\t\t\t\tfor (var opName in group){\n\t\t\t\t\tvar op = group[opName];\n\t\t\t\t\tvar reg = op.regexp;\n\t\t\t\t\tvar match = expr.match(reg);\n\t\t\t\t\tif (match !== null){\n\t\t\t\t\t\treturn {\n\t\t\t\t\t\t\ttype : type,\n\t\t\t\t\t\t\tvalue : match[0],\n\t\t\t\t\t\t\tmethod : op.method\n\t\t\t\t\t\t};\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\tthrow new SyntaxError(\"Tone.Expr: Unexpected token \"+expr);\n\t\t}\n\n\t\treturn {\n\t\t\tnext : function(){\n\t\t\t\treturn tokens[++position];\n\t\t\t},\n\t\t\tpeek : function(){\n\t\t\t\treturn tokens[position + 1];\n\t\t\t}\n\t\t};\n\t};\n\n\t/**\n\t * recursively parse the string expression into a syntax tree\n\t * \n\t * @param {string} expr \n\t * @return {Object}\n\t * @private\n\t */\n\tTone.Expr.prototype._parseTree = function(expr){\n\t\tvar lexer = this._tokenize(expr);\n\t\tvar isUndef = this.isUndef.bind(this);\n\n\t\tfunction matchSyntax(token, syn) {\n\t\t\treturn !isUndef(token) && \n\t\t\t\ttoken.type === \"glue\" &&\n\t\t\t\ttoken.value === syn;\n\t\t}\n\n\t\tfunction matchGroup(token, groupName, prec) {\n\t\t\tvar ret = false;\n\t\t\tvar group = Tone.Expr._Expressions[groupName];\n\t\t\tif (!isUndef(token)){\n\t\t\t\tfor (var opName in group){\n\t\t\t\t\tvar op = group[opName];\n\t\t\t\t\tif (op.regexp.test(token.value)){\n\t\t\t\t\t\tif (!isUndef(prec)){\n\t\t\t\t\t\t\tif(op.precedence === prec){\t\n\t\t\t\t\t\t\t\treturn true;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\treturn true;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn ret;\n\t\t}\n\n\t\tfunction parseExpression(precedence) {\n\t\t\tif (isUndef(precedence)){\n\t\t\t\tprecedence = 5;\n\t\t\t}\n\t\t\tvar expr;\n\t\t\tif (precedence < 0){\n\t\t\t\texpr = parseUnary();\n\t\t\t} else {\n\t\t\t\texpr = parseExpression(precedence-1);\n\t\t\t}\n\t\t\tvar token = lexer.peek();\n\t\t\twhile (matchGroup(token, \"binary\", precedence)) {\n\t\t\t\ttoken = lexer.next();\n\t\t\t\texpr = {\n\t\t\t\t\toperator: token.value,\n\t\t\t\t\tmethod : token.method,\n\t\t\t\t\targs : [\n\t\t\t\t\t\texpr,\n\t\t\t\t\t\tparseExpression(precedence-1)\n\t\t\t\t\t]\n\t\t\t\t};\n\t\t\t\ttoken = lexer.peek();\n\t\t\t}\n\t\t\treturn expr;\n\t\t}\n\n\t\tfunction parseUnary() {\n\t\t\tvar token, expr;\n\t\t\ttoken = lexer.peek();\n\t\t\tif (matchGroup(token, \"unary\")) {\n\t\t\t\ttoken = lexer.next();\n\t\t\t\texpr = parseUnary();\n\t\t\t\treturn {\n\t\t\t\t\toperator: token.value,\n\t\t\t\t\tmethod : token.method,\n\t\t\t\t\targs : [expr]\n\t\t\t\t};\n\t\t\t}\n\t\t\treturn parsePrimary();\n\t\t}\n\n\t\tfunction parsePrimary() {\n\t\t\tvar token, expr;\n\t\t\ttoken = lexer.peek();\n\t\t\tif (isUndef(token)) {\n\t\t\t\tthrow new SyntaxError(\"Tone.Expr: Unexpected termination of expression\");\n\t\t\t}\n\t\t\tif (token.type === \"func\") {\n\t\t\t\ttoken = lexer.next();\n\t\t\t\treturn parseFunctionCall(token);\n\t\t\t}\n\t\t\tif (token.type === \"value\") {\n\t\t\t\ttoken = lexer.next();\n\t\t\t\treturn {\n\t\t\t\t\tmethod : token.method,\n\t\t\t\t\targs : token.value\n\t\t\t\t};\n\t\t\t}\n\t\t\tif (matchSyntax(token, \"(\")) {\n\t\t\t\tlexer.next();\n\t\t\t\texpr = parseExpression();\n\t\t\t\ttoken = lexer.next();\n\t\t\t\tif (!matchSyntax(token, \")\")) {\n\t\t\t\t\tthrow new SyntaxError(\"Expected )\");\n\t\t\t\t}\n\t\t\t\treturn expr;\n\t\t\t}\n\t\t\tthrow new SyntaxError(\"Tone.Expr: Parse error, cannot process token \" + token.value);\n\t\t}\n\n\t\tfunction parseFunctionCall(func) {\n\t\t\tvar token, args = [];\n\t\t\ttoken = lexer.next();\n\t\t\tif (!matchSyntax(token, \"(\")) {\n\t\t\t\tthrow new SyntaxError(\"Tone.Expr: Expected ( in a function call \\\"\" + func.value + \"\\\"\");\n\t\t\t}\n\t\t\ttoken = lexer.peek();\n\t\t\tif (!matchSyntax(token, \")\")) {\n\t\t\t\targs = parseArgumentList();\n\t\t\t}\n\t\t\ttoken = lexer.next();\n\t\t\tif (!matchSyntax(token, \")\")) {\n\t\t\t\tthrow new SyntaxError(\"Tone.Expr: Expected ) in a function call \\\"\" + func.value + \"\\\"\");\n\t\t\t}\n\t\t\treturn {\n\t\t\t\tmethod : func.method,\n\t\t\t\targs : args,\n\t\t\t\tname : name\n\t\t\t};\n\t\t}\n\n\t\tfunction parseArgumentList() {\n\t\t\tvar token, expr, args = [];\n\t\t\twhile (true) {\n\t\t\t\texpr = parseExpression();\n\t\t\t\tif (isUndef(expr)) {\n\t\t\t\t\t// TODO maybe throw exception?\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\targs.push(expr);\n\t\t\t\ttoken = lexer.peek();\n\t\t\t\tif (!matchSyntax(token, \",\")) {\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tlexer.next();\n\t\t\t}\n\t\t\treturn args;\n\t\t}\n\n\t\treturn parseExpression();\n\t};\n\n\t/**\n\t * recursively evaluate the expression tree\n\t * @param {Object} tree \n\t * @return {AudioNode} the resulting audio node from the expression\n\t * @private\n\t */\n\tTone.Expr.prototype._eval = function(tree){\n\t\tif (!this.isUndef(tree)){\n\t\t\tvar node = tree.method(tree.args, this);\n\t\t\tthis._nodes.push(node);\n\t\t\treturn node;\n\t\t} \n\t};\n\n\t/**\n\t * dispose all the nodes\n\t * @private\n\t */\n\tTone.Expr.prototype._disposeNodes = function(){\n\t\tfor (var i = 0; i < this._nodes.length; i++){\n\t\t\tvar node = this._nodes[i];\n\t\t\tif (this.isFunction(node.dispose)) {\n\t\t\t\tnode.dispose();\n\t\t\t} else if (this.isFunction(node.disconnect)) {\n\t\t\t\tnode.disconnect();\n\t\t\t}\n\t\t\tnode = null;\n\t\t\tthis._nodes[i] = null;\n\t\t}\n\t\tthis._nodes = null;\n\t};\n\n\t/**\n\t * clean up\n\t */\n\tTone.Expr.prototype.dispose = function(){\n\t\tTone.prototype.dispose.call(this);\n\t\tthis._disposeNodes();\n\t};\n\n\treturn Tone.Expr;\n});","define([\"Tone/core/Tone\", \"Tone/signal/GreaterThanZero\", \"Tone/signal/Subtract\", \"Tone/signal/Signal\"], \n\tfunction(Tone){\n\n\t\"use strict\";\n\n\t/**\n\t * @class Output 1 if the signal is greater than the value, otherwise outputs 0.\n\t * can compare two signals or a signal and a number. \n\t * \n\t * @constructor\n\t * @extends {Tone.Signal}\n\t * @param {number} [value=0] the value to compare to the incoming signal\n\t * @example\n\t * var gt = new Tone.GreaterThan(2);\n\t * var sig = new Tone.Signal(4).connect(gt);\n\t * //output of gt is equal 1. \n\t */\n\tTone.GreaterThan = function(value){\n\n\t\tthis.createInsOuts(2, 0);\n\t\t\n\t\t/**\n\t\t * subtract the amount from the incoming signal\n\t\t * @type {Tone.Subtract}\n\t\t * @private\n\t\t */\n\t\tthis._param = this.input[0] = new Tone.Subtract(value);\n\t\tthis.input[1] = this._param.input[1];\n\n\t\t/**\n\t\t * compare that amount to zero\n\t\t * @type {Tone.GreaterThanZero}\n\t\t * @private\n\t\t */\n\t\tthis._gtz = this.output = new Tone.GreaterThanZero();\n\n\t\t//connect\n\t\tthis._param.connect(this._gtz);\n\t};\n\n\tTone.extend(Tone.GreaterThan, Tone.Signal);\n\n\t/**\n\t * dispose method\n\t * @returns {Tone.GreaterThan} this\n\t */\n\tTone.GreaterThan.prototype.dispose = function(){\n\t\tTone.prototype.dispose.call(this);\n\t\tthis._param.dispose();\n\t\tthis._param = null;\n\t\tthis._gtz.dispose();\n\t\tthis._gtz = null;\n\t\treturn this;\n\t};\n\n\treturn Tone.GreaterThan;\n});","define([\"Tone/core/Tone\", \"Tone/signal/WaveShaper\", \"Tone/signal/SignalBase\"], \nfunction(Tone){\n\n\t\"use strict\";\n\n\t/**\n\t * @class Return the absolute value of an incoming signal. \n\t * \n\t * @constructor\n\t * @extends {Tone.SignalBase}\n\t * @example\n\t * var signal = new Tone.Signal(-1);\n\t * var abs = new Tone.Abs();\n\t * signal.connect(abs);\n\t * //the output of abs is 1. \n\t */\n\tTone.Abs = function(){\n\t\t/**\n\t\t * @type {Tone.LessThan}\n\t\t * @private\n\t\t */\n\t\tthis._abs = this.input = this.output = new Tone.WaveShaper(function(val){\n\t\t\tif (val === 0){\n\t\t\t\treturn 0;\n\t\t\t} else {\n\t\t\t\treturn Math.abs(val);\n\t\t\t}\n\t\t}, 127);\n\t};\n\n\tTone.extend(Tone.Abs, Tone.SignalBase);\n\n\t/**\n\t * dispose method\n\t * @returns {Tone.Abs} this\n\t */\n\tTone.Abs.prototype.dispose = function(){\n\t\tTone.prototype.dispose.call(this);\n\t\tthis._abs.dispose();\n\t\tthis._abs = null;\n\t\treturn this;\n\t}; \n\n\treturn Tone.Abs;\n});","define([\"Tone/core/Tone\", \"Tone/signal/WaveShaper\", \"Tone/signal/Multiply\", \"Tone/signal/Subtract\"], \nfunction(Tone){\n\n\t\"use strict\";\n\n\t/**\n\t * @class Signal-rate modulo operator. Only works in AudioRange [-1, 1] and for modulus\n\t * values in the NormalRange. \n\t *\n\t * @constructor\n\t * @extends {Tone.SignalBase}\n\t * @param {NormalRange} modulus The modulus to apply.\n\t * @example\n\t * var mod = new Tone.Modulo(0.2)\n\t * var sig = new Tone.Signal(0.5).connect(mod);\n\t * //mod outputs 0.1\n\t */\n\tTone.Modulo = function(modulus){\n\n\t\tthis.createInsOuts(1, 0);\n\n\t\t/**\n\t\t * A waveshaper gets the integer multiple of \n\t\t * the input signal and the modulus.\n\t\t * @private\n\t\t * @type {Tone.WaveShaper}\n\t\t */\n\t\tthis._shaper = new Tone.WaveShaper(Math.pow(2, 16));\n\n\t\t/**\n\t\t * the integer multiple is multiplied by the modulus\n\t\t * @type {Tone.Multiply}\n\t\t * @private\n\t\t */\n\t\tthis._multiply = new Tone.Multiply();\n\n\t\t/**\n\t\t * and subtracted from the input signal\n\t\t * @type {Tone.Subtract}\n\t\t * @private\n\t\t */\n\t\tthis._subtract = this.output = new Tone.Subtract();\n\n\t\t/**\n\t\t * the modulus signal\n\t\t * @type {Tone.Signal}\n\t\t * @private\n\t\t */\n\t\tthis._modSignal = new Tone.Signal(modulus);\n\n\t\t//connections\n\t\tthis.input.fan(this._shaper, this._subtract);\n\t\tthis._modSignal.connect(this._multiply, 0, 0);\n\t\tthis._shaper.connect(this._multiply, 0, 1);\n\t\tthis._multiply.connect(this._subtract, 0, 1);\n\t\tthis._setWaveShaper(modulus);\n\t};\n\n\tTone.extend(Tone.Modulo, Tone.SignalBase);\n\n\t/**\n\t * @param {number} mod the modulus to apply\n\t * @private\n\t */\n\tTone.Modulo.prototype._setWaveShaper = function(mod){\n\t\tthis._shaper.setMap(function(val){\n\t\t\tvar multiple = Math.floor((val + 0.0001) / mod);\n\t\t\treturn multiple;\n\t\t});\n\t};\n\n\t/**\n\t * The modulus value.\n\t * @memberOf Tone.Modulo#\n\t * @type {NormalRange}\n\t * @name value\n\t */\n\tObject.defineProperty(Tone.Modulo.prototype, \"value\", {\n\t\tget : function(){\n\t\t\treturn this._modSignal.value;\n\t\t},\n\t\tset : function(mod){\n\t\t\tthis._modSignal.value = mod;\n\t\t\tthis._setWaveShaper(mod);\n\t\t}\n\t});\n\n\t/**\n\t * clean up\n\t * @returns {Tone.Modulo} this\n\t */\n\tTone.Modulo.prototype.dispose = function(){\n\t\tTone.prototype.dispose.call(this);\n\t\tthis._shaper.dispose();\n\t\tthis._shaper = null;\n\t\tthis._multiply.dispose();\n\t\tthis._multiply = null;\n\t\tthis._subtract.dispose();\n\t\tthis._subtract = null;\n\t\tthis._modSignal.dispose();\n\t\tthis._modSignal = null;\n\t\treturn this;\n\t};\n\n\treturn Tone.Modulo;\n});","define([\"Tone/core/Tone\", \"Tone/signal/WaveShaper\"], function(Tone){\n\n\t\"use strict\";\n\n\t/**\n\t * @class Pow applies an exponent to the incoming signal. The incoming signal\n\t * must be AudioRange.\n\t *\n\t * @extends {Tone.SignalBase}\n\t * @constructor\n\t * @param {Positive} exp The exponent to apply to the incoming signal, must be at least 2. \n\t * @example\n\t * var pow = new Tone.Pow(2);\n\t * var sig = new Tone.Signal(0.5).connect(pow);\n\t * //output of pow is 0.25. \n\t */\n\tTone.Pow = function(exp){\n\n\t\t/**\n\t\t * the exponent\n\t\t * @private\n\t\t * @type {number}\n\t\t */\n\t\tthis._exp = this.defaultArg(exp, 1);\n\n\t\t/**\n\t\t * @type {WaveShaperNode}\n\t\t * @private\n\t\t */\n\t\tthis._expScaler = this.input = this.output = new Tone.WaveShaper(this._expFunc(this._exp), 8192);\n\t};\n\n\tTone.extend(Tone.Pow, Tone.SignalBase);\n\n\t/**\n\t * The value of the exponent.\n\t * @memberOf Tone.Pow#\n\t * @type {number}\n\t * @name value\n\t */\n\tObject.defineProperty(Tone.Pow.prototype, \"value\", {\n\t\tget : function(){\n\t\t\treturn this._exp;\n\t\t},\n\t\tset : function(exp){\n\t\t\tthis._exp = exp;\n\t\t\tthis._expScaler.setMap(this._expFunc(this._exp));\n\t\t}\n\t});\n\n\n\t/**\n\t * the function which maps the waveshaper\n\t * @param {number} exp\n\t * @return {function}\n\t * @private\n\t */\n\tTone.Pow.prototype._expFunc = function(exp){\n\t\treturn function(val){\n\t\t\treturn Math.pow(Math.abs(val), exp);\n\t\t};\n\t};\n\n\t/**\n\t * Clean up.\n\t * @returns {Tone.Pow} this\n\t */\n\tTone.Pow.prototype.dispose = function(){\n\t\tTone.prototype.dispose.call(this);\n\t\tthis._expScaler.dispose();\n\t\tthis._expScaler = null;\n\t\treturn this;\n\t};\n\n\treturn Tone.Pow;\n});","define([\"Tone/core/Tone\", \"Tone/signal/WaveShaper\", \"Tone/signal/Signal\"], function(Tone){\n\n\t\"use strict\";\n\n\t/**\n\t * @class AudioToGain converts an input in AudioRange [-1,1] to NormalRange [0,1]. \n\t * See Tone.GainToAudio.\n\t *\n\t * @extends {Tone.SignalBase}\n\t * @constructor\n\t * @example\n\t * var a2g = new Tone.AudioToGain();\n\t */\n\tTone.AudioToGain = function(){\n\n\t\t/**\n\t\t * @type {WaveShaperNode}\n\t\t * @private\n\t\t */\n\t\tthis._norm = this.input = this.output = new Tone.WaveShaper(function(x){\n\t\t\treturn (x + 1) / 2;\n\t\t});\n\t};\n\n\tTone.extend(Tone.AudioToGain, Tone.SignalBase);\n\n\t/**\n\t * clean up\n\t * @returns {Tone.AudioToGain} this\n\t */\n\tTone.AudioToGain.prototype.dispose = function(){\n\t\tTone.prototype.dispose.call(this);\n\t\tthis._norm.dispose();\n\t\tthis._norm = null;\n\t\treturn this;\n\t};\n\n\treturn Tone.AudioToGain;\n});","define([\"Tone/core/Tone\", \"Tone/signal/WaveShaper\"], function(Tone){\n\n\t\"use strict\";\n\n\t/**\n\t * @class Convert an incoming signal between 0, 1 to an equal power gain scale.\n\t *\n\t * @extends {Tone.SignalBase}\n\t * @constructor\n\t * @example\n\t * var eqPowGain = new Tone.EqualPowerGain();\n\t */\n\tTone.EqualPowerGain = function(){\n\n\t\t/**\n\t\t * @type {Tone.WaveShaper}\n\t\t * @private\n\t\t */\n\t\tthis._eqPower = this.input = this.output = new Tone.WaveShaper(function(val){\n\t\t\tif (Math.abs(val) < 0.001){\n\t\t\t\t//should output 0 when input is 0\n\t\t\t\treturn 0;\n\t\t\t} else {\n\t\t\t\treturn this.equalPowerScale(val);\n\t\t\t}\n\t\t}.bind(this), 4096);\n\t};\n\n\tTone.extend(Tone.EqualPowerGain, Tone.SignalBase);\n\n\t/**\n\t * clean up\n\t * @returns {Tone.EqualPowerGain} this\n\t */\n\tTone.EqualPowerGain.prototype.dispose = function(){\n\t\tTone.prototype.dispose.call(this);\n\t\tthis._eqPower.dispose();\n\t\tthis._eqPower = null;\n\t\treturn this;\n\t};\n\n\treturn Tone.EqualPowerGain;\n});","'use strict';\n\ndefine(function (require) {\n\n var Effect = require('effect');\n var EQFilter = require('eqFilter');\n\n /**\n * p5.EQ is an audio effect that performs the function of a multiband\n * audio equalizer. Equalization is used to adjust the balance of\n * frequency compoenents of an audio signal. This process is commonly used\n * in sound production and recording to change the waveform before it reaches\n * a sound output device. EQ can also be used as an audio effect to create\n * interesting distortions by filtering out parts of the spectrum. p5.EQ is\n * built using a chain of Web Audio Biquad Filter Nodes and can be\n * instantiated with 3 or 8 bands. Bands can be added or removed from\n * the EQ by directly modifying p5.EQ.bands (the array that stores filters).\n *\n * This class extends p5.Effect.\n * Methods amp(), chain(),\n * drywet(), connect(), and\n * disconnect() are available.\n *\n * @class p5.EQ\n * @constructor\n * @extends p5.Effect\n * @param {Number} [_eqsize] Constructor will accept 3 or 8, defaults to 3\n * @return {Object} p5.EQ object\n *\n * @example\n *
\n * var eq;\n * var band_names;\n * var band_index;\n *\n * var soundFile, play;\n *\n * function preload() {\n * soundFormats('mp3', 'ogg');\n * soundFile = loadSound('assets/beat');\n * }\n *\n * function setup() {\n * eq = new p5.EQ(3);\n * soundFile.disconnect();\n * eq.process(soundFile);\n *\n * band_names = ['lows','mids','highs'];\n * band_index = 0;\n * play = false;\n * textAlign(CENTER);\n * }\n *\n * function draw() {\n * background(30);\n * noStroke();\n * fill(255);\n * text('click to kill',50,25);\n *\n * fill(255, 40, 255);\n * textSize(26);\n * text(band_names[band_index],50,55);\n *\n * fill(255);\n * textSize(9);\n * text('space = play/pause',50,80);\n * }\n *\n * //If mouse is over canvas, cycle to the next band and kill the frequency\n * function mouseClicked() {\n * for (var i = 0; i < eq.bands.length; i++) {\n * eq.bands[i].gain(0);\n * }\n * eq.bands[band_index].gain(-40);\n * if (mouseX > 0 && mouseX < width && mouseY < height && mouseY > 0) {\n * band_index === 2 ? band_index = 0 : band_index++;\n * }\n * }\n *\n * //use space bar to trigger play / pause\n * function keyPressed() {\n * if (key===' ') {\n * play = !play\n * play ? soundFile.loop() : soundFile.pause();\n * }\n * }\n *
\n */\n p5.EQ = function(_eqsize) {\n Effect.call(this);\n\n //p5.EQ can be of size (3) or (8), defaults to 3\n _eqsize = _eqsize === 3 || _eqsize === 8 ? _eqsize : 3;\n\n var factor;\n _eqsize === 3 ? factor = Math.pow(2,3) : factor = 2;\n\n /**\n * The p5.EQ is built with abstracted p5.Filter objects.\n * To modify any bands, use methods of the \n * p5.Filter API, especially `gain` and `freq`.\n * Bands are stored in an array, with indices 0 - 3, or 0 - 7\n * @property {Array} bands\n *\n */\n this.bands = [];\n\n\n var freq, res;\n for (var i = 0; i < _eqsize; i++) {\n if (i === _eqsize - 1) {\n freq = 21000;\n res = .01;\n } else if (i === 0) {\n freq = 100;\n res = .1;\n }\n else if (i===1) {\n freq = _eqsize === 3 ? 360 * factor : 360;\n res = 1;\n }else {\n freq = this.bands[i-1].freq() * factor;\n res = 1;\n }\n this.bands[i] = this._newBand(freq, res);\n\n if (i>0) {\n this.bands[i-1].connect(this.bands[i].biquad);\n } else {\n this.input.connect(this.bands[i].biquad);\n }\n }\n this.bands[_eqsize-1].connect(this.output);\n };\n p5.EQ.prototype = Object.create(Effect.prototype);\n\n /**\n * Process an input by connecting it to the EQ\n * @method process\n * @param {Object} src Audio source\n */\n p5.EQ.prototype.process = function (src) {\n src.connect(this.input);\n };\n\n // /**\n // * Set the frequency and gain of each band in the EQ. This method should be\n // * called with 3 or 8 frequency and gain pairs, depending on the size of the EQ.\n // * ex. eq.set(freq0, gain0, freq1, gain1, freq2, gain2);\n // *\n // * @method set\n // * @for p5.EQ\n // * @param {Number} [freq0] Frequency value for band with index 0\n // * @param {Number} [gain0] Gain value for band with index 0\n // * @param {Number} [freq1] Frequency value for band with index 1\n // * @param {Number} [gain1] Gain value for band with index 1\n // * @param {Number} [freq2] Frequency value for band with index 2\n // * @param {Number} [gain2] Gain value for band with index 2\n // * @param {Number} [freq3] Frequency value for band with index 3\n // * @param {Number} [gain3] Gain value for band with index 3\n // * @param {Number} [freq4] Frequency value for band with index 4\n // * @param {Number} [gain4] Gain value for band with index 4\n // * @param {Number} [freq5] Frequency value for band with index 5\n // * @param {Number} [gain5] Gain value for band with index 5\n // * @param {Number} [freq6] Frequency value for band with index 6\n // * @param {Number} [gain6] Gain value for band with index 6\n // * @param {Number} [freq7] Frequency value for band with index 7\n // * @param {Number} [gain7] Gain value for band with index 7\n // */\n p5.EQ.prototype.set = function() {\n if (arguments.length === this.bands.length * 2) {\n for (var i = 0; i < arguments.length; i+=2) {\n this.bands[i/2].freq(arguments[i]);\n this.bands[i/2].gain(arguments[i+1]);\n }\n }\n else {\n console.error('Argument mismatch. .set() should be called with ' + this.bands.length*2 +\n ' arguments. (one frequency and gain value pair for each band of the eq)');\n }\n };\n\n /**\n * Add a new band. Creates a p5.Filter and strips away everything but\n * the raw biquad filter. This method returns an abstracted p5.Filter,\n * which can be added to p5.EQ.bands, in order to create new EQ bands.\n * @private\n * @for p5.EQ\n * @method _newBand\n * @param {Number} freq\n * @param {Number} res\n * @return {Object} Abstracted Filter\n */\n p5.EQ.prototype._newBand = function(freq, res) {\n return new EQFilter(freq, res);\n };\n\n p5.EQ.prototype.dispose = function () {\n Effect.prototype.dispose.apply(this);\n\n if (this.bands) {\n while (this.bands.length > 0) {\n delete this.bands.pop().dispose();\n }\n delete this.bands;\n }\n };\n\n return p5.EQ;\n});\n","'use strict';\n\ndefine(function (require) {\n var Filter = require('filter');\n var p5sound = require('master');\n\n /**\n * EQFilter extends p5.Filter with constraints\n * necessary for the p5.EQ\n *\n * @private\n */\n var EQFilter = function(freq, res) {\n Filter.call(this, 'peaking');\n this.disconnect();\n this.set(freq, res);\n this.biquad.gain.value = 0;\n delete this.input;\n delete this.output;\n delete this._drywet;\n delete this.wet;\n\n };\n EQFilter.prototype = Object.create(Filter.prototype);\n\n EQFilter.prototype.amp = function() {\n console.warn('`amp()` is not available for p5.EQ bands. Use `.gain()`');\n };\n EQFilter.prototype.drywet = function() {\n console.warn('`drywet()` is not available for p5.EQ bands.');\n };\n EQFilter.prototype.connect = function(unit) {\n var u = unit || p5.soundOut.input;\n if (this.biquad) {\n this.biquad.connect(u.input ? u.input : u);\n } else {\n this.output.connect(u.input ? u.input : u);\n }\n };\n\n EQFilter.prototype.disconnect = function() {\n if (this.biquad) {\n this.biquad.disconnect();\n }\n };\n EQFilter.prototype.dispose = function() {\n // remove reference form soundArray\n var index = p5sound.soundArray.indexOf(this);\n p5sound.soundArray.splice(index, 1);\n this.disconnect();\n delete this.biquad;\n };\n\n return EQFilter;\n});\n","'use strict'\n\ndefine(function (require) {\n var p5sound = require('master');\n var Effect = require('effect');\n\n /**\n * Panner3D is based on the \n * Web Audio Spatial Panner Node.\n * This panner is a spatial processing node that allows audio to be positioned\n * and oriented in 3D space.\n *\n * The position is relative to an \n * Audio Context Listener, which can be accessed\n * by p5.soundOut.audiocontext.listener\n *\n *\n * @class p5.Panner3D\n * @constructor\n */\n\tp5.Panner3D = function() {\n Effect.call(this);\n\n /**\n * \n * Web Audio Spatial Panner Node\n *\n * Properties include\n * - panningModel: \"equal power\" or \"HRTF\"\n * - distanceModel: \"linear\", \"inverse\", or \"exponential\"\n *\n * @property {AudioNode} panner\n *\n */\n this.panner = this.ac.createPanner();\n this.panner.panningModel = 'HRTF';\n this.panner.distanceModel = 'linear';\n this.panner.connect(this.output);\n this.input.connect(this.panner);\n\t};\n\n p5.Panner3D.prototype = Object.create(Effect.prototype);\n\n\n /**\n * Connect an audio sorce\n *\n * @method process\n * @for p5.Panner3D\n * @param {Object} src Input source\n */\n p5.Panner3D.prototype.process = function(src) {\n src.connect(this.input);\n }\n /**\n * Set the X,Y,Z position of the Panner\n * @method set\n * @for p5.Panner3D\n * @param {Number} xVal\n * @param {Number} yVal\n * @param {Number} zVal\n * @param {Number} time\n * @return {Array} Updated x, y, z values as an array\n */\n p5.Panner3D.prototype.set = function(xVal, yVal, zVal, time) {\n this.positionX(xVal,time);\n this.positionY(yVal,time);\n this.positionZ(zVal,time);\n return [this.panner.positionX.value,\n this.panner.positionY.value,\n this.panner.positionZ.value];\n };\n\n /**\n * Getter and setter methods for position coordinates\n * @method positionX\n * @for p5.Panner3D\n * @return {Number} updated coordinate value\n */\n /**\n * Getter and setter methods for position coordinates\n * @method positionY\n * @for p5.Panner3D\n * @return {Number} updated coordinate value\n */\n /**\n * Getter and setter methods for position coordinates\n * @method positionZ\n * @for p5.Panner3D\n * @return {Number} updated coordinate value\n */\n p5.Panner3D.prototype.positionX = function(xVal, time) {\n var t = time || 0;\n if (typeof xVal === 'number') {\n this.panner.positionX.value = xVal;\n this.panner.positionX.cancelScheduledValues(this.ac.currentTime + 0.01 + t);\n this.panner.positionX.linearRampToValueAtTime(xVal, this.ac.currentTime + 0.02 + t);\n } else if (xVal) {\n xVal.connect(this.panner.positionX);\n }\n return this.panner.positionX.value;\n };\n p5.Panner3D.prototype.positionY = function(yVal, time) {\n var t = time || 0;\n if (typeof yVal === 'number') {\n this.panner.positionY.value = yVal;\n this.panner.positionY.cancelScheduledValues(this.ac.currentTime + 0.01 + t);\n this.panner.positionY.linearRampToValueAtTime(yVal, this.ac.currentTime + 0.02 + t);\n } else if (yVal) {\n yVal.connect(this.panner.positionY);\n }\n return this.panner.positionY.value;\n };\n p5.Panner3D.prototype.positionZ = function(zVal, time) {\n var t = time || 0;\n if (typeof zVal === 'number') {\n this.panner.positionZ.value = zVal;\n this.panner.positionZ.cancelScheduledValues(this.ac.currentTime + 0.01 + t);\n this.panner.positionZ.linearRampToValueAtTime(zVal, this.ac.currentTime + 0.02 + t);\n } else if (zVal) {\n zVal.connect(this.panner.positionZ);\n }\n return this.panner.positionZ.value;\n };\n\n /**\n * Set the X,Y,Z position of the Panner\n * @method orient\n * @for p5.Panner3D\n * @param {Number} xVal\n * @param {Number} yVal\n * @param {Number} zVal\n * @param {Number} time\n * @return {Array} Updated x, y, z values as an array\n */\n p5.Panner3D.prototype.orient = function(xVal, yVal, zVal, time) {\n this.orientX(xVal,time);\n this.orientY(yVal,time);\n this.orientZ(zVal,time);\n return [this.panner.orientationX.value,\n this.panner.orientationY.value,\n this.panner.orientationZ.value];\n };\n\n /**\n * Getter and setter methods for orient coordinates\n * @method orientX\n * @for p5.Panner3D\n * @return {Number} updated coordinate value\n */\n /**\n * Getter and setter methods for orient coordinates\n * @method orientY\n * @for p5.Panner3D\n * @return {Number} updated coordinate value\n */\n /**\n * Getter and setter methods for orient coordinates\n * @method orientZ\n * @for p5.Panner3D\n * @return {Number} updated coordinate value\n */\n p5.Panner3D.prototype.orientX = function(xVal, time) {\n var t = time || 0;\n if (typeof xVal === 'number') {\n this.panner.orientationX.value = xVal;\n this.panner.orientationX.cancelScheduledValues(this.ac.currentTime + 0.01 + t);\n this.panner.orientationX.linearRampToValueAtTime(xVal, this.ac.currentTime + 0.02 + t);\n } else if (xVal) {\n xVal.connect(this.panner.orientationX);\n }\n return this.panner.orientationX.value;\n };\n p5.Panner3D.prototype.orientY = function(yVal, time) {\n var t = time || 0;\n if (typeof yVal === 'number') {\n this.panner.orientationY.value = yVal;\n this.panner.orientationY.cancelScheduledValues(this.ac.currentTime + 0.01 + t);\n this.panner.orientationY.linearRampToValueAtTime(yVal, this.ac.currentTime + 0.02 + t);\n } else if (yVal) {\n yVal.connect(this.panner.orientationY);\n }\n return this.panner.orientationY.value;\n };\n p5.Panner3D.prototype.orientZ = function(zVal, time) {\n var t = time || 0;\n if (typeof zVal === 'number') {\n this.panner.orientationZ.value = zVal;\n this.panner.orientationZ.cancelScheduledValues(this.ac.currentTime + 0.01 + t);\n this.panner.orientationZ.linearRampToValueAtTime(zVal, this.ac.currentTime + 0.02 + t);\n } else if (zVal) {\n zVal.connect(this.panner.orientationZ);\n }\n return this.panner.orientationZ.value;\n };\n\n /**\n * Set the rolloff factor and max distance\n * @method setFalloff\n * @for p5.Panner3D\n * @param {Number} [maxDistance]\n * @param {Number} [rolloffFactor]\n */\n p5.Panner3D.prototype.setFalloff = function(maxDistance, rolloffFactor) {\n this.maxDist(maxDistance);\n this.rolloff(rolloffFactor);\n };\n /**\n * Maxium distance between the source and the listener\n * @method maxDist\n * @for p5.Panner3D\n * @param {Number} maxDistance\n * @return {Number} updated value\n */\n p5.Panner3D.prototype.maxDist = function(maxDistance){\n if (typeof maxDistance === 'number') {\n this.panner.maxDistance = maxDistance;\n }\n return this.panner.maxDistance;\n };\n\n /**\n * How quickly the volume is reduced as the source moves away from the listener\n * @method rollof\n * @for p5.Panner3D\n * @param {Number} rolloffFactor\n * @return {Number} updated value\n */\n p5.Panner3D.prototype.rolloff = function(rolloffFactor){\n if (typeof rolloffFactor === 'number') {\n this.panner.rolloffFactor = rolloffFactor;\n }\n return this.panner.rolloffFactor;\n };\n\n p5.Panner3D.dispose = function() {\n Effect.prototype.dispose.apply(this);\n if (this.panner) {\n this.panner.disconnect();\n delete this.panner;\n }\n };\n\n return p5.Panner3D;\n\n});\n","'use strict'\n\ndefine(function (require) {\n var p5sound = require('master');\n var Effect = require('effect');\n\n// /**\n// * listener is a class that can construct both a Spatial Panner\n// * and a Spatial Listener. The panner is based on the \n// * Web Audio Spatial Panner Node\n// * https://www.w3.org/TR/webaudio/#the-listenernode-interface\n// * This panner is a spatial processing node that allows audio to be positioned\n// * and oriented in 3D space. \n// *\n// * The Listener modifies the properties of the Audio Context Listener. \n// * Both objects types use the same methods. The default is a spatial panner.\n// *\n// * p5.Panner3D - Constructs a Spatial Panner \n// * p5.Listener3D - Constructs a Spatial Listener \n// *\n// * @class listener\n// * @constructor\n// * @return {Object} p5.Listener3D Object\n// *\n// * @param {Web Audio Node} listener Web Audio Spatial Panning Node\n// * @param {AudioParam} listener.panningModel \"equal power\" or \"HRTF\"\n// * @param {AudioParam} listener.distanceModel \"linear\", \"inverse\", or \"exponential\"\n// * @param {String} [type] [Specify construction of a spatial panner or listener]\n// */\n \n\tp5.Listener3D = function(type) {\n this.ac = p5sound.audiocontext;\n this.listener = this.ac.listener;\n\t}; \n\n// /**\n// * Connect an audio sorce\n// * @param {Object} src Input source\n// */\n p5.Listener3D.prototype.process = function(src) {\n src.connect(this.input);\n }\n// /**\n// * Set the X,Y,Z position of the Panner\n// * @param {[Number]} xVal\n// * @param {[Number]} yVal\n// * @param {[Number]} zVal\n// * @param {[Number]} time\n// * @return {[Array]} [Updated x, y, z values as an array]\n// */\n p5.Listener3D.prototype.position = function(xVal, yVal, zVal, time) {\n this.positionX(xVal,time);\n this.positionY(yVal,time);\n this.positionZ(zVal,time);\n return [this.listener.positionX.value, \n this.listener.positionY.value,\n this.listener.positionZ.value];\n };\n\n// /**\n// * Getter and setter methods for position coordinates\n// * @return {Number} [updated coordinate value]\n// */\n p5.Listener3D.prototype.positionX = function(xVal, time) {\n var t = time || 0;\n if (typeof xVal === 'number') {\n this.listener.positionX.value = xVal;\n this.listener.positionX.cancelScheduledValues(this.ac.currentTime + 0.01 + t);\n this.listener.positionX.linearRampToValueAtTime(xVal, this.ac.currentTime + 0.02 + t);\n } else if (xVal) {\n xVal.connect(this.listener.positionX);\n }\n return this.listener.positionX.value;\n };\n p5.Listener3D.prototype.positionY = function(yVal, time) {\n var t = time || 0;\n if (typeof yVal === 'number') {\n this.listener.positionY.value = yVal;\n this.listener.positionY.cancelScheduledValues(this.ac.currentTime + 0.01 + t);\n this.listener.positionY.linearRampToValueAtTime(yVal, this.ac.currentTime + 0.02 + t);\n } else if (yVal) {\n yVal.connect(this.listener.positionY);\n }\n return this.listener.positionY.value;\n };\n p5.Listener3D.prototype.positionZ = function(zVal, time) {\n var t = time || 0;\n if (typeof zVal === 'number') {\n this.listener.positionZ.value = zVal;\n this.listener.positionZ.cancelScheduledValues(this.ac.currentTime + 0.01 + t);\n this.listener.positionZ.linearRampToValueAtTime(zVal, this.ac.currentTime + 0.02 + t);\n } else if (zVal) {\n zVal.connect(this.listener.positionZ);\n }\n return this.listener.positionZ.value;\n };\n\n// cannot define method when class definition is commented\n// /**\n// * Overrides the listener orient() method because Listener has slightly\n// * different params. In human terms, Forward vectors are the direction the \n// * nose is pointing. Up vectors are the direction of the top of the head.\n// *\n// * @method orient\n// * @param {Number} xValF Forward vector X direction\n// * @param {Number} yValF Forward vector Y direction\n// * @param {Number} zValF Forward vector Z direction\n// * @param {Number} xValU Up vector X direction\n// * @param {Number} yValU Up vector Y direction\n// * @param {Number} zValU Up vector Z direction\n// * @param {Number} time \n// * @return {Array} All orienation params\n// */\n p5.Listener3D.prototype.orient = function(xValF, yValF, zValF, \n xValU, yValU, zValU, time) {\n\n if (arguments.length === 3 || arguments.length === 4) {\n time = arguments[3];\n this.orientForward(xValF, yValF, zValF, time);\n } else if (arguments.length === 6 || arguments === 7) {\n this.orientForward(xValF, yValF, zValF);\n this.orientUp(xValU, yValU, zValU, time);\n }\n \n return [this.listener.forwardX.value, \n this.listener.forwardY.value,\n this.listener.forwardZ.value,\n this.listener.upX.value,\n this.listener.upY.value,\n this.listener.upZ.value];\n };\n\n\n p5.Listener3D.prototype.orientForward = function(xValF, yValF, zValF, time) {\n this.forwardX(xValF,time);\n this.forwardY(yValF,time);\n this.forwardZ(zValF,time);\n\n return [this.listener.forwardX, \n this.listener.forwardY,\n this.listener.forwardZ];\n };\n\n p5.Listener3D.prototype.orientUp = function(xValU, yValU, zValU, time) {\n this.upX(xValU,time);\n this.upY(yValU,time);\n this.upZ(zValU,time);\n\n return [this.listener.upX, \n this.listener.upY,\n this.listener.upZ];\n };\n// /**\n// * Getter and setter methods for orient coordinates\n// * @return {Number} [updated coordinate value]\n// */\n p5.Listener3D.prototype.forwardX = function(xVal, time) {\n var t = time || 0;\n if (typeof xVal === 'number') {\n this.listener.forwardX.value = xVal;\n this.listener.forwardX.cancelScheduledValues(this.ac.currentTime + 0.01 + t);\n this.listener.forwardX.linearRampToValueAtTime(xVal, this.ac.currentTime + 0.02 + t);\n } else if (xVal) {\n xVal.connect(this.listener.forwardX);\n }\n return this.listener.forwardX.value;\n };\n p5.Listener3D.prototype.forwardY = function(yVal, time) {\n var t = time || 0;\n if (typeof yVal === 'number') {\n this.listener.forwardY.value = yVal;\n this.listener.forwardY.cancelScheduledValues(this.ac.currentTime + 0.01 + t);\n this.listener.forwardY.linearRampToValueAtTime(yVal, this.ac.currentTime + 0.02 + t);\n } else if (yVal) {\n yVal.connect(this.listener.forwardY);\n }\n return this.listener.forwardY.value;\n };\n p5.Listener3D.prototype.forwardZ = function(zVal, time) {\n var t = time || 0;\n if (typeof zVal === 'number') {\n this.listener.forwardZ.value = zVal;\n this.listener.forwardZ.cancelScheduledValues(this.ac.currentTime + 0.01 + t);\n this.listener.forwardZ.linearRampToValueAtTime(zVal, this.ac.currentTime + 0.02 + t);\n } else if (zVal) {\n zVal.connect(this.listener.forwardZ);\n }\n return this.listener.forwardZ.value;\n };\n p5.Listener3D.prototype.upX = function(xVal, time) {\n var t = time || 0;\n if (typeof xVal === 'number') {\n this.listener.upX.value = xVal;\n this.listener.upX.cancelScheduledValues(this.ac.currentTime + 0.01 + t);\n this.listener.upX.linearRampToValueAtTime(xVal, this.ac.currentTime + 0.02 + t);\n } else if (xVal) {\n xVal.connect(this.listener.upX);\n }\n return this.listener.upX.value;\n };\n p5.Listener3D.prototype.upY = function(yVal, time) {\n var t = time || 0;\n if (typeof yVal === 'number') {\n this.listener.upY.value = yVal;\n this.listener.upY.cancelScheduledValues(this.ac.currentTime + 0.01 + t);\n this.listener.upY.linearRampToValueAtTime(yVal, this.ac.currentTime + 0.02 + t);\n } else if (yVal) {\n yVal.connect(this.listener.upY);\n }\n return this.listener.upY.value;\n };\n p5.Listener3D.prototype.upZ = function(zVal, time) {\n var t = time || 0;\n if (typeof zVal === 'number') {\n this.listener.upZ.value = zVal;\n this.listener.upZ.cancelScheduledValues(this.ac.currentTime + 0.01 + t);\n this.listener.upZ.linearRampToValueAtTime(zVal, this.ac.currentTime + 0.02 + t);\n } else if (zVal) {\n zVal.connect(this.listener.upZ);\n }\n return this.listener.upZ.value;\n };\n \n return p5.Listener3D;\n\n});","'use strict';\n\ndefine(function (require) {\n var Filter = require('filter');\n var Effect = require('effect');\n\n /**\n * Delay is an echo effect. It processes an existing sound source,\n * and outputs a delayed version of that sound. The p5.Delay can\n * produce different effects depending on the delayTime, feedback,\n * filter, and type. In the example below, a feedback of 0.5 (the\n * defaul value) will produce a looping delay that decreases in\n * volume by 50% each repeat. A filter will cut out the high\n * frequencies so that the delay does not sound as piercing as the\n * original source.\n *\n *\n * This class extends p5.Effect.\n * Methods amp(), chain(),\n * drywet(), connect(), and\n * disconnect() are available.\n * @class p5.Delay\n * @extends p5.Effect\n * @constructor\n * @example\n *
\n * var noise, env, delay;\n *\n * function setup() {\n * background(0);\n * noStroke();\n * fill(255);\n * textAlign(CENTER);\n * text('click to play', width/2, height/2);\n *\n * noise = new p5.Noise('brown');\n * noise.amp(0);\n * noise.start();\n *\n * delay = new p5.Delay();\n *\n * // delay.process() accepts 4 parameters:\n * // source, delayTime, feedback, filter frequency\n * // play with these numbers!!\n * delay.process(noise, .12, .7, 2300);\n *\n * // play the noise with an envelope,\n * // a series of fades ( time / value pairs )\n * env = new p5.Envelope(.01, 0.2, .2, .1);\n * }\n *\n * // mouseClick triggers envelope\n * function mouseClicked() {\n * // is mouse over canvas?\n * if (mouseX > 0 && mouseX < width && mouseY > 0 && mouseY < height) {\n * env.play(noise);\n * }\n * }\n *
\n */\n p5.Delay = function() {\n \tEffect.call(this);\n\n this._split = this.ac.createChannelSplitter(2);\n this._merge = this.ac.createChannelMerger(2);\n\n this._leftGain = this.ac.createGain();\n this._rightGain = this.ac.createGain();\n\n /**\n * The p5.Delay is built with two\n * \n * Web Audio Delay Nodes, one for each stereo channel.\n *\n * @property {DelayNode} leftDelay\n */\n this.leftDelay = this.ac.createDelay();\n /**\n * The p5.Delay is built with two\n * \n * Web Audio Delay Nodes, one for each stereo channel.\n *\n * @property {DelayNode} rightDelay\n */\n this.rightDelay = this.ac.createDelay();\n\n this._leftFilter = new Filter();\n this._rightFilter = new Filter();\n this._leftFilter.disconnect();\n this._rightFilter.disconnect();\n\n this._leftFilter.biquad.frequency.setValueAtTime(1200, this.ac.currentTime);\n this._rightFilter.biquad.frequency.setValueAtTime(1200, this.ac.currentTime);\n this._leftFilter.biquad.Q.setValueAtTime(0.3, this.ac.currentTime);\n this._rightFilter.biquad.Q.setValueAtTime(0.3, this.ac.currentTime);\n\n // graph routing\n this.input.connect(this._split);\n this.leftDelay.connect(this._leftGain);\n this.rightDelay.connect(this._rightGain);\n this._leftGain.connect(this._leftFilter.input);\n this._rightGain.connect(this._rightFilter.input);\n this._merge.connect(this.wet);\n\n\n this._leftFilter.biquad.gain.setValueAtTime(1, this.ac.currentTime);\n this._rightFilter.biquad.gain.setValueAtTime(1, this.ac.currentTime);\n\n // default routing\n this.setType(0);\n\n this._maxDelay = this.leftDelay.delayTime.maxValue;\n\n // set initial feedback to 0.5\n this.feedback(0.5);\n\n\n };\n\n p5.Delay.prototype = Object.create(Effect.prototype);\n /**\n * Add delay to an audio signal according to a set\n * of delay parameters.\n *\n * @method process\n * @for p5.Delay\n * @param {Object} Signal An object that outputs audio\n * @param {Number} [delayTime] Time (in seconds) of the delay/echo.\n * Some browsers limit delayTime to\n * 1 second.\n * @param {Number} [feedback] sends the delay back through itself\n * in a loop that decreases in volume\n * each time.\n * @param {Number} [lowPass] Cutoff frequency. Only frequencies\n * below the lowPass will be part of the\n * delay.\n */\n p5.Delay.prototype.process = function(src, _delayTime, _feedback, _filter) {\n var feedback = _feedback || 0;\n var delayTime = _delayTime || 0;\n if (feedback >= 1.0) {\n throw new Error('Feedback value will force a positive feedback loop.');\n }\n if (delayTime >= this._maxDelay) {\n throw new Error('Delay Time exceeds maximum delay time of ' + this._maxDelay + ' second.');\n }\n\n src.connect(this.input);\n this.leftDelay.delayTime.setValueAtTime(delayTime, this.ac.currentTime);\n this.rightDelay.delayTime.setValueAtTime(delayTime, this.ac.currentTime);\n this._leftGain.gain.value = feedback;\n this._rightGain.gain.value = feedback;\n\n if (_filter) {\n this._leftFilter.freq(_filter);\n this._rightFilter.freq(_filter);\n }\n };\n\n /**\n * Set the delay (echo) time, in seconds. Usually this value will be\n * a floating point number between 0.0 and 1.0.\n *\n * @method delayTime\n * @for p5.Delay\n * @param {Number} delayTime Time (in seconds) of the delay\n */\n p5.Delay.prototype.delayTime = function(t) {\n // if t is an audio node...\n if (typeof t !== 'number') {\n t.connect(this.leftDelay.delayTime);\n t.connect(this.rightDelay.delayTime);\n }\n\n else {\n this.leftDelay.delayTime.cancelScheduledValues(this.ac.currentTime);\n this.rightDelay.delayTime.cancelScheduledValues(this.ac.currentTime);\n this.leftDelay.delayTime.linearRampToValueAtTime(t, this.ac.currentTime);\n this.rightDelay.delayTime.linearRampToValueAtTime(t, this.ac.currentTime);\n }\n };\n\n /**\n * Feedback occurs when Delay sends its signal back through its input\n * in a loop. The feedback amount determines how much signal to send each\n * time through the loop. A feedback greater than 1.0 is not desirable because\n * it will increase the overall output each time through the loop,\n * creating an infinite feedback loop. The default value is 0.5\n *\n * @method feedback\n * @for p5.Delay\n * @param {Number|Object} feedback 0.0 to 1.0, or an object such as an\n * Oscillator that can be used to\n * modulate this param\n * @returns {Number} Feedback value\n *\n */\n p5.Delay.prototype.feedback = function(f) {\n // if f is an audio node...\n if (f && typeof f !== 'number') {\n f.connect(this._leftGain.gain);\n f.connect(this._rightGain.gain);\n }\n else if (f >= 1.0) {\n throw new Error('Feedback value will force a positive feedback loop.');\n }\n else if (typeof f === 'number') {\n this._leftGain.gain.value = f;\n this._rightGain.gain.value = f;\n }\n\n // return value of feedback\n return this._leftGain.gain.value;\n };\n\n /**\n * Set a lowpass filter frequency for the delay. A lowpass filter\n * will cut off any frequencies higher than the filter frequency.\n *\n * @method filter\n * @for p5.Delay\n * @param {Number|Object} cutoffFreq A lowpass filter will cut off any\n * frequencies higher than the filter frequency.\n * @param {Number|Object} res Resonance of the filter frequency\n * cutoff, or an object (i.e. a p5.Oscillator)\n * that can be used to modulate this parameter.\n * High numbers (i.e. 15) will produce a resonance,\n * low numbers (i.e. .2) will produce a slope.\n */\n p5.Delay.prototype.filter = function(freq, q) {\n this._leftFilter.set(freq, q);\n this._rightFilter.set(freq, q);\n };\n\n\n /**\n * Choose a preset type of delay. 'pingPong' bounces the signal\n * from the left to the right channel to produce a stereo effect.\n * Any other parameter will revert to the default delay setting.\n *\n * @method setType\n * @for p5.Delay\n * @param {String|Number} type 'pingPong' (1) or 'default' (0)\n */\n p5.Delay.prototype.setType = function(t) {\n if (t === 1) {\n t = 'pingPong';\n }\n this._split.disconnect();\n this._leftFilter.disconnect();\n this._rightFilter.disconnect();\n this._split.connect(this.leftDelay, 0);\n this._split.connect(this.rightDelay, 1);\n switch(t) {\n case 'pingPong':\n this._rightFilter.setType( this._leftFilter.biquad.type );\n this._leftFilter.output.connect(this._merge, 0, 0);\n this._rightFilter.output.connect(this._merge, 0, 1);\n this._leftFilter.output.connect(this.rightDelay);\n this._rightFilter.output.connect(this.leftDelay);\n break;\n default:\n this._leftFilter.output.connect(this._merge, 0, 0);\n this._rightFilter.output.connect(this._merge, 0, 1);\n this._leftFilter.output.connect(this.leftDelay);\n this._rightFilter.output.connect(this.rightDelay);\n }\n };\n\n // DocBlocks for methods inherited from p5.Effect\n /**\n * Set the output level of the delay effect.\n *\n * @method amp\n * @for p5.Delay\n * @param {Number} volume amplitude between 0 and 1.0\n * @param {Number} [rampTime] create a fade that lasts rampTime\n * @param {Number} [timeFromNow] schedule this event to happen\n * seconds from now\n */\n /**\n * Send output to a p5.sound or web audio object\n *\n * @method connect\n * @for p5.Delay\n * @param {Object} unit\n */\n /**\n * Disconnect all output.\n *\n * @method disconnect\n * @for p5.Delay\n */\n\n p5.Delay.prototype.dispose = function() {\n\n Effect.prototype.dispose.apply(this);\n\n this._split.disconnect();\n this._leftFilter.dispose();\n this._rightFilter.dispose();\n this._merge.disconnect();\n this._leftGain.disconnect();\n this._rightGain.disconnect();\n this.leftDelay.disconnect();\n this.rightDelay.disconnect();\n\n this._split = undefined;\n this._leftFilter = undefined;\n this._rightFilter = undefined;\n this._merge = undefined;\n this._leftGain = undefined;\n this._rightGain = undefined;\n this.leftDelay = undefined;\n this.rightDelay = undefined;\n };\n\n});\n","'use strict';\n\ndefine(function (require) {\n var CustomError = require('errorHandler');\n var Effect = require('effect');\n\n /**\n * Reverb adds depth to a sound through a large number of decaying\n * echoes. It creates the perception that sound is occurring in a\n * physical space. The p5.Reverb has paramters for Time (how long does the\n * reverb last) and decayRate (how much the sound decays with each echo)\n * that can be set with the .set() or .process() methods. The p5.Convolver\n * extends p5.Reverb allowing you to recreate the sound of actual physical\n * spaces through convolution.\n *\n * This class extends p5.Effect.\n * Methods amp(), chain(),\n * drywet(), connect(), and\n * disconnect() are available.\n *\n * @class p5.Reverb\n * @extends p5.Effect\n * @constructor\n * @example\n *
\n * var soundFile, reverb;\n * function preload() {\n * soundFile = loadSound('assets/Damscray_DancingTiger.mp3');\n * }\n *\n * function setup() {\n * reverb = new p5.Reverb();\n * soundFile.disconnect(); // so we'll only hear reverb...\n *\n * // connect soundFile to reverb, process w/\n * // 3 second reverbTime, decayRate of 2%\n * reverb.process(soundFile, 3, 2);\n * soundFile.play();\n * }\n *
\n */\n\n\n p5.Reverb = function() {\n Effect.call(this);\n\n this._initConvolverNode();\n\n // otherwise, Safari distorts\n this.input.gain.value = 0.5;\n\n // default params\n this._seconds = 3;\n this._decay = 2;\n this._reverse = false;\n\n this._buildImpulse();\n\n };\n\n p5.Reverb.prototype = Object.create(Effect.prototype);\n\n p5.Reverb.prototype._initConvolverNode = function() {\n this.convolverNode = this.ac.createConvolver();\n this.input.connect(this.convolverNode);\n this.convolverNode.connect(this.wet);\n };\n\n p5.Reverb.prototype._teardownConvolverNode = function() {\n if (this.convolverNode) {\n this.convolverNode.disconnect();\n delete this.convolverNode;\n }\n };\n\n p5.Reverb.prototype._setBuffer = function(audioBuffer) {\n this._teardownConvolverNode();\n this._initConvolverNode();\n this.convolverNode.buffer = audioBuffer;\n };\n /**\n * Connect a source to the reverb, and assign reverb parameters.\n *\n * @method process\n * @for p5.Reverb\n * @param {Object} src p5.sound / Web Audio object with a sound\n * output.\n * @param {Number} [seconds] Duration of the reverb, in seconds.\n * Min: 0, Max: 10. Defaults to 3.\n * @param {Number} [decayRate] Percentage of decay with each echo.\n * Min: 0, Max: 100. Defaults to 2.\n * @param {Boolean} [reverse] Play the reverb backwards or forwards.\n */\n p5.Reverb.prototype.process = function(src, seconds, decayRate, reverse) {\n src.connect(this.input);\n var rebuild = false;\n if (seconds) {\n this._seconds = seconds;\n rebuild = true;\n }\n if (decayRate) {\n this._decay = decayRate;\n }\n if (reverse) {\n this._reverse = reverse;\n }\n if (rebuild) {\n this._buildImpulse();\n }\n };\n\n /**\n * Set the reverb settings. Similar to .process(), but without\n * assigning a new input.\n *\n * @method set\n * @for p5.Reverb\n * @param {Number} [seconds] Duration of the reverb, in seconds.\n * Min: 0, Max: 10. Defaults to 3.\n * @param {Number} [decayRate] Percentage of decay with each echo.\n * Min: 0, Max: 100. Defaults to 2.\n * @param {Boolean} [reverse] Play the reverb backwards or forwards.\n */\n p5.Reverb.prototype.set = function(seconds, decayRate, reverse) {\n var rebuild = false;\n if (seconds) {\n this._seconds = seconds;\n rebuild = true;\n }\n if (decayRate) {\n this._decay = decayRate;\n }\n if (reverse) {\n this._reverse = reverse;\n }\n if (rebuild) {\n this._buildImpulse();\n }\n };\n\n // DocBlocks for methods inherited from p5.Effect\n /**\n * Set the output level of the reverb effect.\n *\n * @method amp\n * @for p5.Reverb\n * @param {Number} volume amplitude between 0 and 1.0\n * @param {Number} [rampTime] create a fade that lasts rampTime\n * @param {Number} [timeFromNow] schedule this event to happen\n * seconds from now\n */\n /**\n * Send output to a p5.sound or web audio object\n *\n * @method connect\n * @for p5.Reverb\n * @param {Object} unit\n */\n /**\n * Disconnect all output.\n *\n * @method disconnect\n * @for p5.Reverb\n */\n\n /**\n * Inspired by Simple Reverb by Jordan Santell\n * https://github.com/web-audio-components/simple-reverb/blob/master/index.js\n *\n * Utility function for building an impulse response\n * based on the module parameters.\n *\n * @private\n */\n p5.Reverb.prototype._buildImpulse = function() {\n var rate = this.ac.sampleRate;\n var length = rate*this._seconds;\n var decay = this._decay;\n var impulse = this.ac.createBuffer(2, length, rate);\n var impulseL = impulse.getChannelData(0);\n var impulseR = impulse.getChannelData(1);\n var n, i;\n for (i = 0; i < length; i++) {\n n = this._reverse ? length - i : i;\n impulseL[i] = (Math.random() * 2 - 1) * Math.pow(1 - n / length, decay);\n impulseR[i] = (Math.random() * 2 - 1) * Math.pow(1 - n / length, decay);\n }\n this._setBuffer(impulse);\n };\n\n p5.Reverb.prototype.dispose = function() {\n Effect.prototype.dispose.apply(this);\n this._teardownConvolverNode();\n };\n\n // =======================================================================\n // *** p5.Convolver ***\n // =======================================================================\n\n /**\n *
p5.Convolver extends p5.Reverb. It can emulate the sound of real\n * physical spaces through a process called \n * convolution.
\n *\n *
Convolution multiplies any audio input by an \"impulse response\"\n * to simulate the dispersion of sound over time. The impulse response is\n * generated from an audio file that you provide. One way to\n * generate an impulse response is to pop a balloon in a reverberant space\n * and record the echo. Convolution can also be used to experiment with\n * sound.
\n *\n *
Use the method createConvolution(path) to instantiate a\n * p5.Convolver with a path to your impulse response audio file.
\n *\n * @class p5.Convolver\n * @extends p5.Effect\n * @constructor\n * @param {String} path path to a sound file\n * @param {Function} [callback] function to call when loading succeeds\n * @param {Function} [errorCallback] function to call if loading fails.\n * This function will receive an error or\n * XMLHttpRequest object with information\n * about what went wrong.\n * @example\n *
\n * var cVerb, sound;\n * function preload() {\n * // We have both MP3 and OGG versions of all sound assets\n * soundFormats('ogg', 'mp3');\n *\n * // Try replacing 'bx-spring' with other soundfiles like\n * // 'concrete-tunnel' 'small-plate' 'drum' 'beatbox'\n * cVerb = createConvolver('assets/bx-spring.mp3');\n *\n * // Try replacing 'Damscray_DancingTiger' with\n * // 'beat', 'doorbell', lucky_dragons_-_power_melody'\n * sound = loadSound('assets/Damscray_DancingTiger.mp3');\n * }\n *\n * function setup() {\n * // disconnect from master output...\n * sound.disconnect();\n *\n * // ...and process with cVerb\n * // so that we only hear the convolution\n * cVerb.process(sound);\n *\n * sound.play();\n * }\n *
\n */\n p5.Convolver = function(path, callback, errorCallback) {\n \t p5.Reverb.call(this);\n\n /**\n * Internally, the p5.Convolver uses the a\n * \n * Web Audio Convolver Node.\n *\n * @property {ConvolverNode} convolverNode\n */\n this._initConvolverNode();\n\n // otherwise, Safari distorts\n this.input.gain.value = 0.5;\n\n if (path) {\n this.impulses = [];\n this._loadBuffer(path, callback, errorCallback);\n }\n else {\n // parameters\n this._seconds = 3;\n this._decay = 2;\n this._reverse = false;\n\n this._buildImpulse();\n }\n\n };\n\n p5.Convolver.prototype = Object.create(p5.Reverb.prototype);\n\n p5.prototype.registerPreloadMethod('createConvolver', p5.prototype);\n\n /**\n * Create a p5.Convolver. Accepts a path to a soundfile\n * that will be used to generate an impulse response.\n *\n * @method createConvolver\n * @for p5\n * @param {String} path path to a sound file\n * @param {Function} [callback] function to call if loading is successful.\n * The object will be passed in as the argument\n * to the callback function.\n * @param {Function} [errorCallback] function to call if loading is not successful.\n * A custom error will be passed in as the argument\n * to the callback function.\n * @return {p5.Convolver}\n * @example\n *
\n * var cVerb, sound;\n * function preload() {\n * // We have both MP3 and OGG versions of all sound assets\n * soundFormats('ogg', 'mp3');\n *\n * // Try replacing 'bx-spring' with other soundfiles like\n * // 'concrete-tunnel' 'small-plate' 'drum' 'beatbox'\n * cVerb = createConvolver('assets/bx-spring.mp3');\n *\n * // Try replacing 'Damscray_DancingTiger' with\n * // 'beat', 'doorbell', lucky_dragons_-_power_melody'\n * sound = loadSound('assets/Damscray_DancingTiger.mp3');\n * }\n *\n * function setup() {\n * // disconnect from master output...\n * sound.disconnect();\n *\n * // ...and process with cVerb\n * // so that we only hear the convolution\n * cVerb.process(sound);\n *\n * sound.play();\n * }\n *
\n */\n p5.prototype.createConvolver = function(path, callback, errorCallback) {\n // if loading locally without a server\n if (window.location.origin.indexOf('file://') > -1 && window.cordova === 'undefined') {\n alert('This sketch may require a server to load external files. Please see http://bit.ly/1qcInwS');\n }\n var self = this;\n var cReverb = new p5.Convolver(path, function(buffer) {\n if (typeof callback === 'function') {\n callback(buffer);\n }\n\n if (typeof self._decrementPreload === 'function') {\n self._decrementPreload();\n }\n }, errorCallback);\n cReverb.impulses = [];\n return cReverb;\n };\n\n /**\n * Private method to load a buffer as an Impulse Response,\n * assign it to the convolverNode, and add to the Array of .impulses.\n *\n * @param {String} path\n * @param {Function} callback\n * @param {Function} errorCallback\n * @private\n */\n p5.Convolver.prototype._loadBuffer = function(path, callback, errorCallback) {\n var path = p5.prototype._checkFileFormats(path);\n var self = this;\n var errorTrace = new Error().stack;\n var ac = p5.prototype.getAudioContext();\n\n var request = new XMLHttpRequest();\n request.open('GET', path, true);\n request.responseType = 'arraybuffer';\n\n request.onload = function() {\n if (request.status === 200) {\n // on success loading file:\n ac.decodeAudioData(request.response,\n function(buff) {\n var buffer = {};\n var chunks = path.split('/');\n buffer.name = chunks[chunks.length - 1];\n buffer.audioBuffer = buff;\n self.impulses.push(buffer);\n self._setBuffer(buffer.audioBuffer);\n if (callback) {\n callback(buffer);\n }\n },\n // error decoding buffer. \"e\" is undefined in Chrome 11/22/2015\n function() {\n var err = new CustomError('decodeAudioData', errorTrace, self.url);\n var msg = 'AudioContext error at decodeAudioData for ' + self.url;\n if (errorCallback) {\n err.msg = msg;\n errorCallback(err);\n } else {\n console.error(msg +'\\n The error stack trace includes: \\n' + err.stack);\n }\n }\n );\n }\n // if request status != 200, it failed\n else {\n var err = new CustomError('loadConvolver', errorTrace, self.url);\n var msg = 'Unable to load ' + self.url +\n '. The request status was: ' + request.status + ' (' + request.statusText + ')';\n\n if (errorCallback) {\n err.message = msg;\n errorCallback(err);\n } else {\n console.error(msg +'\\n The error stack trace includes: \\n' + err.stack);\n }\n }\n };\n\n // if there is another error, aside from 404...\n request.onerror = function() {\n var err = new CustomError('loadConvolver', errorTrace, self.url);\n var msg = 'There was no response from the server at ' + self.url + '. Check the url and internet connectivity.';\n\n if (errorCallback) {\n err.message = msg;\n errorCallback(err);\n } else {\n console.error(msg +'\\n The error stack trace includes: \\n' + err.stack);\n }\n };\n request.send();\n };\n\n p5.Convolver.prototype.set = null;\n\n /**\n * Connect a source to the reverb, and assign reverb parameters.\n *\n * @method process\n * @for p5.Convolver\n * @param {Object} src p5.sound / Web Audio object with a sound\n * output.\n * @example\n *
\n * var cVerb, sound;\n * function preload() {\n * soundFormats('ogg', 'mp3');\n *\n * cVerb = createConvolver('assets/concrete-tunnel.mp3');\n *\n * sound = loadSound('assets/beat.mp3');\n * }\n *\n * function setup() {\n * // disconnect from master output...\n * sound.disconnect();\n *\n * // ...and process with (i.e. connect to) cVerb\n * // so that we only hear the convolution\n * cVerb.process(sound);\n *\n * sound.play();\n * }\n *
\n */\n p5.Convolver.prototype.process = function(src) {\n src.connect(this.input);\n };\n\n /**\n * If you load multiple impulse files using the .addImpulse method,\n * they will be stored as Objects in this Array. Toggle between them\n * with the toggleImpulse(id) method.\n *\n * @property {Array} impulses\n * @for p5.Convolver\n */\n p5.Convolver.prototype.impulses = [];\n\n /**\n * Load and assign a new Impulse Response to the p5.Convolver.\n * The impulse is added to the .impulses array. Previous\n * impulses can be accessed with the .toggleImpulse(id)\n * method.\n *\n * @method addImpulse\n * @for p5.Convolver\n * @param {String} path path to a sound file\n * @param {Function} callback function (optional)\n * @param {Function} errorCallback function (optional)\n */\n p5.Convolver.prototype.addImpulse = function(path, callback, errorCallback) {\n // if loading locally without a server\n if (window.location.origin.indexOf('file://') > -1 && window.cordova === 'undefined') {\n alert('This sketch may require a server to load external files. Please see http://bit.ly/1qcInwS');\n }\n this._loadBuffer(path, callback, errorCallback);\n };\n\n /**\n * Similar to .addImpulse, except that the .impulses\n * Array is reset to save memory. A new .impulses\n * array is created with this impulse as the only item.\n *\n * @method resetImpulse\n * @for p5.Convolver\n * @param {String} path path to a sound file\n * @param {Function} callback function (optional)\n * @param {Function} errorCallback function (optional)\n */\n p5.Convolver.prototype.resetImpulse = function(path, callback, errorCallback) {\n // if loading locally without a server\n if (window.location.origin.indexOf('file://') > -1 && window.cordova === 'undefined') {\n alert('This sketch may require a server to load external files. Please see http://bit.ly/1qcInwS');\n }\n this.impulses = [];\n this._loadBuffer(path, callback, errorCallback);\n };\n\n /**\n * If you have used .addImpulse() to add multiple impulses\n * to a p5.Convolver, then you can use this method to toggle between\n * the items in the .impulses Array. Accepts a parameter\n * to identify which impulse you wish to use, identified either by its\n * original filename (String) or by its position in the .impulses\n * Array (Number). \n * You can access the objects in the .impulses Array directly. Each\n * Object has two attributes: an .audioBuffer (type:\n * Web Audio \n * AudioBuffer) and a .name, a String that corresponds\n * with the original filename.\n *\n * @method toggleImpulse\n * @for p5.Convolver\n * @param {String|Number} id Identify the impulse by its original filename\n * (String), or by its position in the\n * .impulses Array (Number).\n */\n p5.Convolver.prototype.toggleImpulse = function(id) {\n if (typeof id === 'number' && id < this.impulses.length) {\n this._setBuffer(this.impulses[id].audioBuffer);\n }\n if (typeof id === 'string') {\n for (var i = 0; i < this.impulses.length; i++) {\n if (this.impulses[i].name === id) {\n this._setBuffer(this.impulses[i].audioBuffer);\n break;\n }\n }\n }\n };\n\n p5.Convolver.prototype.dispose = function() {\n p5.Reverb.prototype.dispose.apply(this);\n\n // remove all the Impulse Response buffers\n for (var i in this.impulses) {\n if (this.impulses[i]) {\n this.impulses[i] = null;\n }\n }\n };\n\n});\n","'use strict';\n\ndefine(function (require) {\n var p5sound = require('master');\n\n // requires the Tone.js library's Clock (MIT license, Yotam Mann)\n // https://github.com/TONEnoTONE/Tone.js/\n var Clock = require('Tone/core/Clock');\n\n p5.Metro = function() {\n this.clock = new Clock({\n 'callback': this.ontick.bind(this)\n });\n this.syncedParts = [];\n this.bpm = 120; // gets overridden by p5.Part\n this._init();\n\n this.prevTick = 0;\n this.tatumTime = 0;\n\n this.tickCallback = function() {};\n };\n\n p5.Metro.prototype.ontick = function(tickTime) {\n var elapsedTime = tickTime - this.prevTick;\n var secondsFromNow = tickTime - p5sound.audiocontext.currentTime;\n if (elapsedTime - this.tatumTime <= -0.02) {\n return;\n } else {\n // console.log('ok', this.syncedParts[0].phrases[0].name);\n this.prevTick = tickTime;\n\n // for all of the active things on the metro:\n var self = this;\n this.syncedParts.forEach(function(thisPart) {\n if (!thisPart.isPlaying) return;\n thisPart.incrementStep(secondsFromNow);\n // each synced source keeps track of its own beat number\n thisPart.phrases.forEach(function(thisPhrase) {\n var phraseArray = thisPhrase.sequence;\n var bNum = self.metroTicks % phraseArray.length;\n if (phraseArray[bNum] !== 0 && (self.metroTicks < phraseArray.length || !thisPhrase.looping) ) {\n thisPhrase.callback(secondsFromNow, phraseArray[bNum]);\n }\n });\n });\n this.metroTicks += 1;\n this.tickCallback(secondsFromNow);\n }\n };\n\n p5.Metro.prototype.setBPM = function(bpm, rampTime) {\n var beatTime = 60 / (bpm*this.tatums);\n var now = p5sound.audiocontext.currentTime;\n this.tatumTime = beatTime;\n\n var rampTime = rampTime || 0;\n this.clock.frequency.setValueAtTime(this.clock.frequency.value, now);\n this.clock.frequency.linearRampToValueAtTime(bpm, now + rampTime);\n this.bpm = bpm;\n };\n\n p5.Metro.prototype.getBPM = function() {\n return this.clock.getRate() / this.tatums * 60;\n };\n\n p5.Metro.prototype._init = function() {\n this.metroTicks = 0;\n // this.setBPM(120);\n };\n\n // clear existing synced parts, add only this one\n p5.Metro.prototype.resetSync = function(part) {\n this.syncedParts = [part];\n };\n\n // push a new synced part to the array\n p5.Metro.prototype.pushSync = function(part) {\n this.syncedParts.push(part);\n };\n\n p5.Metro.prototype.start = function(timeFromNow) {\n var t = timeFromNow || 0;\n var now = p5sound.audiocontext.currentTime;\n this.clock.start(now + t);\n this.setBPM(this.bpm);\n };\n\n p5.Metro.prototype.stop = function(timeFromNow) {\n var t = timeFromNow || 0;\n var now = p5sound.audiocontext.currentTime;\n this.clock.stop(now + t);\n };\n\n p5.Metro.prototype.beatLength = function(tatums) {\n this.tatums = 1/tatums / 4; // lowest possible division of a beat\n };\n\n});\n","define([\"Tone/core/Tone\", \"Tone/core/Timeline\", \"Tone/type/Type\"], function (Tone) {\n\n\t\"use strict\";\n\n\t/**\n\t * @class A Timeline State. Provides the methods: setStateAtTime(\"state\", time)\n\t * and getValueAtTime(time).\n\t *\n\t * @extends {Tone.Timeline}\n\t * @param {String} initial The initial state of the TimelineState. \n\t * Defaults to undefined\n\t */\n\tTone.TimelineState = function(initial){\n\n\t\tTone.Timeline.call(this);\n\n\t\t/**\n\t\t * The initial state\n\t\t * @private\n\t\t * @type {String}\n\t\t */\n\t\tthis._initial = initial;\n\t};\n\n\tTone.extend(Tone.TimelineState, Tone.Timeline);\n\n\t/**\n\t * Returns the scheduled state scheduled before or at\n\t * the given time.\n\t * @param {Number} time The time to query.\n\t * @return {String} The name of the state input in setStateAtTime.\n\t */\n\tTone.TimelineState.prototype.getValueAtTime = function(time){\n\t\tvar event = this.get(time);\n\t\tif (event !== null){\n\t\t\treturn event.state;\n\t\t} else {\n\t\t\treturn this._initial;\n\t\t}\n\t};\n\n\t/**\n\t * Returns the scheduled state scheduled before or at\n\t * the given time.\n\t * @param {String} state The name of the state to set.\n\t * @param {Number} time The time to query.\n\t */\n\tTone.TimelineState.prototype.setStateAtTime = function(state, time){\n\t\tthis.add({\n\t\t\t\"state\" : state,\n\t\t\t\"time\" : time\n\t\t});\n\t};\n\n\treturn Tone.TimelineState;\n});","'use strict';\n\ndefine(function(require) {\n var p5sound = require('master');\n\n var BPM = 120;\n\n /**\n * Set the global tempo, in beats per minute, for all\n * p5.Parts. This method will impact all active p5.Parts.\n *\n * @method setBPM\n * @for p5\n * @param {Number} BPM Beats Per Minute\n * @param {Number} rampTime Seconds from now\n */\n p5.prototype.setBPM = function(bpm, rampTime) {\n BPM = bpm;\n for (var i in p5sound.parts) {\n if (p5sound.parts[i]) {\n p5sound.parts[i].setBPM(bpm, rampTime);\n }\n }\n };\n\n /**\n *
A phrase is a pattern of musical events over time, i.e.\n * a series of notes and rests.
\n *\n *
Phrases must be added to a p5.Part for playback, and\n * each part can play multiple phrases at the same time.\n * For example, one Phrase might be a kick drum, another\n * could be a snare, and another could be the bassline.
\n *\n *
The first parameter is a name so that the phrase can be\n * modified or deleted later. The callback is a a function that\n * this phrase will call at every step—for example it might be\n * called playNote(value){}. The array determines\n * which value is passed into the callback at each step of the\n * phrase. It can be numbers, an object with multiple numbers,\n * or a zero (0) indicates a rest so the callback won't be called).
\n *\n * @class p5.Phrase\n * @constructor\n * @param {String} name Name so that you can access the Phrase.\n * @param {Function} callback The name of a function that this phrase\n * will call. Typically it will play a sound,\n * and accept two parameters: a time at which\n * to play the sound (in seconds from now),\n * and a value from the sequence array. The\n * time should be passed into the play() or\n * start() method to ensure precision.\n * @param {Array} sequence Array of values to pass into the callback\n * at each step of the phrase.\n * @example\n *
\n */\n p5.Phrase = function(name, callback, sequence) {\n this.phraseStep = 0;\n this.name = name;\n this.callback = callback;\n /**\n * Array of values to pass into the callback\n * at each step of the phrase. Depending on the callback\n * function's requirements, these values may be numbers,\n * strings, or an object with multiple parameters.\n * Zero (0) indicates a rest.\n *\n * @property {Array} sequence\n */\n this.sequence = sequence;\n };\n\n /**\n *
A p5.Part plays back one or more p5.Phrases. Instantiate a part\n * with steps and tatums. By default, each step represents a 1/16th note.
\n *\n *
See p5.Phrase for more about musical timing.
\n *\n * @class p5.Part\n * @constructor\n * @param {Number} [steps] Steps in the part\n * @param {Number} [tatums] Divisions of a beat, e.g. use 1/4, or 0.25 for a quater note (default is 1/16, a sixteenth note)\n * @example\n *
\n * var box, drum, myPart;\n * var boxPat = [1,0,0,2,0,2,0,0];\n * var drumPat = [0,1,1,0,2,0,1,0];\n * var msg = 'click to play';\n *\n * function preload() {\n * box = loadSound('assets/beatbox.mp3');\n * drum = loadSound('assets/drum.mp3');\n * }\n *\n * function setup() {\n * noStroke();\n * fill(255);\n * textAlign(CENTER);\n * masterVolume(0.1);\n *\n * var boxPhrase = new p5.Phrase('box', playBox, boxPat);\n * var drumPhrase = new p5.Phrase('drum', playDrum, drumPat);\n * myPart = new p5.Part();\n * myPart.addPhrase(boxPhrase);\n * myPart.addPhrase(drumPhrase);\n * myPart.setBPM(60);\n * masterVolume(0.1);\n * }\n *\n * function draw() {\n * background(0);\n * text(msg, width/2, height/2);\n * }\n *\n * function playBox(time, playbackRate) {\n * box.rate(playbackRate);\n * box.play(time);\n * }\n *\n * function playDrum(time, playbackRate) {\n * drum.rate(playbackRate);\n * drum.play(time);\n * }\n *\n * function mouseClicked() {\n * if (mouseX > 0 && mouseX < width && mouseY > 0 && mouseY < height) {\n * myPart.start();\n * msg = 'playing part';\n * }\n * }\n *
\n */\n p5.Part = function(steps, bLength) {\n this.length = steps || 0; // how many beats\n this.partStep = 0;\n this.phrases = [];\n this.isPlaying = false;\n this.noLoop();\n this.tatums = bLength || 0.0625; // defaults to quarter note\n\n this.metro = new p5.Metro();\n this.metro._init();\n this.metro.beatLength(this.tatums);\n this.metro.setBPM(BPM);\n p5sound.parts.push(this);\n this.callback = function() {};\n };\n\n /**\n * Set the tempo of this part, in Beats Per Minute.\n *\n * @method setBPM\n * @for p5.Part\n * @param {Number} BPM Beats Per Minute\n * @param {Number} [rampTime] Seconds from now\n */\n p5.Part.prototype.setBPM = function(tempo, rampTime) {\n this.metro.setBPM(tempo, rampTime);\n };\n\n /**\n * Returns the tempo, in Beats Per Minute, of this part.\n *\n * @method getBPM\n * @for p5.Part\n * @return {Number}\n */\n p5.Part.prototype.getBPM = function() {\n return this.metro.getBPM();\n };\n\n /**\n * Start playback of this part. It will play\n * through all of its phrases at a speed\n * determined by setBPM.\n *\n * @method start\n * @for p5.Part\n * @param {Number} [time] seconds from now\n */\n p5.Part.prototype.start = function(time) {\n if (!this.isPlaying) {\n this.isPlaying = true;\n this.metro.resetSync(this);\n var t = time || 0;\n this.metro.start(t);\n }\n };\n\n /**\n * Loop playback of this part. It will begin\n * looping through all of its phrases at a speed\n * determined by setBPM.\n *\n * @method loop\n * @for p5.Part\n * @param {Number} [time] seconds from now\n */\n p5.Part.prototype.loop = function(time) {\n this.looping = true;\n // rest onended function\n this.onended = function() {\n this.partStep = 0;\n };\n var t = time || 0;\n this.start(t);\n };\n\n /**\n * Tell the part to stop looping.\n *\n * @method noLoop\n * @for p5.Part\n */\n p5.Part.prototype.noLoop = function() {\n this.looping = false;\n // rest onended function\n this.onended = function() {\n this.stop();\n };\n };\n\n /**\n * Stop the part and cue it to step 0. Playback will resume from the begining of the Part when it is played again.\n *\n * @method stop\n * @for p5.Part\n * @param {Number} [time] seconds from now\n */\n p5.Part.prototype.stop = function(time) {\n this.partStep = 0;\n this.pause(time);\n };\n\n /**\n * Pause the part. Playback will resume\n * from the current step.\n *\n * @method pause\n * @for p5.Part\n * @param {Number} time seconds from now\n */\n p5.Part.prototype.pause = function(time) {\n this.isPlaying = false;\n var t = time || 0;\n this.metro.stop(t);\n };\n\n /**\n * Add a p5.Phrase to this Part.\n *\n * @method addPhrase\n * @for p5.Part\n * @param {p5.Phrase} phrase reference to a p5.Phrase\n */\n p5.Part.prototype.addPhrase = function(name, callback, array) {\n var p;\n if (arguments.length === 3) {\n p = new p5.Phrase(name, callback, array);\n } else if (arguments[0] instanceof p5.Phrase) {\n p = arguments[0];\n } else {\n throw 'invalid input. addPhrase accepts name, callback, array or a p5.Phrase';\n }\n this.phrases.push(p);\n // reset the length if phrase is longer than part's existing length\n if (p.sequence.length > this.length) {\n this.length = p.sequence.length;\n }\n };\n\n /**\n * Remove a phrase from this part, based on the name it was\n * given when it was created.\n *\n * @method removePhrase\n * @for p5.Part\n * @param {String} phraseName\n */\n p5.Part.prototype.removePhrase = function(name) {\n for (var i in this.phrases) {\n if (this.phrases[i].name === name) {\n this.phrases.splice(i, 1);\n }\n }\n };\n\n /**\n * Get a phrase from this part, based on the name it was\n * given when it was created. Now you can modify its array.\n *\n * @method getPhrase\n * @for p5.Part\n * @param {String} phraseName\n */\n p5.Part.prototype.getPhrase = function(name) {\n for (var i in this.phrases) {\n if (this.phrases[i].name === name) {\n return this.phrases[i];\n }\n }\n };\n\n /**\n * Find all sequences with the specified name, and replace their patterns with the specified array.\n *\n * @method replaceSequence\n * @for p5.Part\n * @param {String} phraseName\n * @param {Array} sequence Array of values to pass into the callback\n * at each step of the phrase.\n */\n p5.Part.prototype.replaceSequence = function(name, array) {\n for (var i in this.phrases) {\n if (this.phrases[i].name === name) {\n this.phrases[i].sequence = array;\n }\n }\n };\n\n p5.Part.prototype.incrementStep = function(time) {\n if (this.partStep < this.length - 1) {\n this.callback(time);\n this.partStep += 1;\n } else {\n if (!this.looping && this.partStep === this.length - 1) {\n console.log('done');\n // this.callback(time);\n this.onended();\n }\n }\n };\n\n /**\n * Set the function that will be called at every step. This will clear the previous function.\n *\n * @method onStep\n * @for p5.Part\n * @param {Function} callback The name of the callback\n * you want to fire\n * on every beat/tatum.\n */\n p5.Part.prototype.onStep = function(callback) {\n this.callback = callback;\n };\n\n\n // ===============\n // p5.Score\n // ===============\n\n /**\n * A Score consists of a series of Parts. The parts will\n * be played back in order. For example, you could have an\n * A part, a B part, and a C part, and play them back in this order\n * new p5.Score(a, a, b, a, c)\n *\n * @class p5.Score\n * @constructor\n * @param {p5.Part} [...parts] One or multiple parts, to be played in sequence.\n */\n p5.Score = function() {\n // for all of the arguments\n this.parts = [];\n this.currentPart = 0;\n\n var thisScore = this;\n for (var i in arguments) {\n if (arguments[i] && this.parts[i]) {\n this.parts[i] = arguments[i];\n this.parts[i].nextPart = this.parts[i + 1];\n this.parts[i].onended = function() {\n thisScore.resetPart(i);\n playNextPart(thisScore);\n };\n }\n }\n this.looping = false;\n };\n\n p5.Score.prototype.onended = function() {\n if (this.looping) {\n // this.resetParts();\n this.parts[0].start();\n } else {\n this.parts[this.parts.length - 1].onended = function() {\n this.stop();\n this.resetParts();\n };\n }\n this.currentPart = 0;\n };\n\n /**\n * Start playback of the score.\n *\n * @method start\n * @for p5.Score\n */\n p5.Score.prototype.start = function() {\n this.parts[this.currentPart].start();\n this.scoreStep = 0;\n };\n\n /**\n * Stop playback of the score.\n *\n * @method stop\n * @for p5.Score\n */\n p5.Score.prototype.stop = function() {\n this.parts[this.currentPart].stop();\n this.currentPart = 0;\n this.scoreStep = 0;\n };\n\n /**\n * Pause playback of the score.\n *\n * @method pause\n * @for p5.Score\n */\n p5.Score.prototype.pause = function() {\n this.parts[this.currentPart].stop();\n };\n\n /**\n * Loop playback of the score.\n *\n * @method loop\n * @for p5.Score\n */\n p5.Score.prototype.loop = function() {\n this.looping = true;\n this.start();\n };\n\n /**\n * Stop looping playback of the score. If it\n * is currently playing, this will go into effect\n * after the current round of playback completes.\n *\n * @method noLoop\n * @for p5.Score\n */\n p5.Score.prototype.noLoop = function() {\n this.looping = false;\n };\n\n p5.Score.prototype.resetParts = function() {\n var self = this;\n this.parts.forEach(function(part) {\n self.resetParts[part];\n });\n };\n\n p5.Score.prototype.resetPart = function(i) {\n this.parts[i].stop();\n this.parts[i].partStep = 0;\n for (var p in this.parts[i].phrases) {\n if (this.parts[i]) {\n this.parts[i].phrases[p].phraseStep = 0;\n }\n }\n };\n\n /**\n * Set the tempo for all parts in the score\n *\n * @method setBPM\n * @for p5.Score\n * @param {Number} BPM Beats Per Minute\n * @param {Number} rampTime Seconds from now\n */\n p5.Score.prototype.setBPM = function(bpm, rampTime) {\n for (var i in this.parts) {\n if (this.parts[i]) {\n this.parts[i].setBPM(bpm, rampTime);\n }\n }\n };\n\n function playNextPart(aScore) {\n aScore.currentPart++;\n if (aScore.currentPart >= aScore.parts.length) {\n aScore.scoreStep = 0;\n aScore.onended();\n } else {\n aScore.scoreStep = 0;\n aScore.parts[aScore.currentPart - 1].stop();\n aScore.parts[aScore.currentPart].start();\n }\n }\n\n});\n","'use strict';\n\ndefine(function (require) {\n var p5sound = require('master');\n var Clock = require('Tone/core/Clock');\n\n /**\n * SoundLoop\n *\n * @class p5.SoundLoop\n * @constructor\n *\n * @param {Function} callback this function will be called on each iteration of theloop\n * @param {Number|String} [interval] amount of time or beats for each iteration of the loop\n * defaults to 1\n *\n * @example\n *
\n * var click;\n * var looper1;\n *\n * function preload() {\n * click = loadSound('assets/drum.mp3');\n * }\n *\n * function setup() {\n * //the looper's callback is passed the timeFromNow\n * //this value should be used as a reference point from\n * //which to schedule sounds\n * looper1 = new p5.SoundLoop(function(timeFromNow){\n * click.play(timeFromNow);\n * background(255 * (looper1.iterations % 2));\n * }, 2);\n *\n * //stop after 10 iteratios;\n * looper1.maxIterations = 10;\n * //start the loop\n * looper1.start();\n * }\n *
\n */\n p5.SoundLoop = function(callback, interval) {\n this.callback = callback;\n /**\n * musicalTimeMode uses Tone.Time convention\n\t * true if string, false if number\n * @property {Boolean} musicalTimeMode\n */\n this.musicalTimeMode = typeof this._interval === 'number' ? false : true;\n\n this._interval = interval || 1;\n\n /**\n * musicalTimeMode variables\n * modify these only when the interval is specified in musicalTime format as a string\n */\n this._timeSignature = 4;\n this._bpm = 60;\n\n this.isPlaying = false;\n\n /**\n * Set a limit to the number of loops to play. defaults to Infinity\n * @property {Number} maxIterations\n */\n this.maxIterations = Infinity;\n var self = this;\n\n this.clock = new Clock({\n 'callback' : function(time) {\n var timeFromNow = time - p5sound.audiocontext.currentTime;\n /**\n * Do not initiate the callback if timeFromNow is < 0\n * This ususually occurs for a few milliseconds when the page\n * is not fully loaded\n *\n * The callback should only be called until maxIterations is reached\n */\n if (timeFromNow > 0 && self.iterations <= self.maxIterations) {\n self.callback(timeFromNow);}\n },\n 'frequency' : this._calcFreq()\n });\n };\n\n /**\n * Start the loop\n * @method start\n * @for p5.SoundLoop\n * @param {Number} [timeFromNow] schedule a starting time\n */\n p5.SoundLoop.prototype.start = function(timeFromNow) {\n var t = timeFromNow || 0;\n var now = p5sound.audiocontext.currentTime;\n if (!this.isPlaying) {\n this.clock.start(now + t);\n this.isPlaying = true;\n }\n };\n\n /**\n * Stop the loop\n * @method stop\n * @for p5.SoundLoop\n * @param {Number} [timeFromNow] schedule a stopping time\n */\n p5.SoundLoop.prototype.stop = function(timeFromNow) {\n var t = timeFromNow || 0;\n var now = p5sound.audiocontext.currentTime;\n if (this.isPlaying) {\n this.clock.stop(now + t);\n this.isPlaying = false;\n }\n };\n /**\n * Pause the loop\n * @method pause\n * @for p5.SoundLoop\n * @param {Number} [timeFromNow] schedule a pausing time\n */\n p5.SoundLoop.prototype.pause = function(timeFromNow) {\n var t = timeFromNow || 0;\n var now = p5sound.audiocontext.currentTime;\n if (this.isPlaying) {\n this.clock.pause(now + t);\n this.isPlaying = false;\n }\n };\n\n\n /**\n * Synchronize loops. Use this method to start two more more loops in synchronization\n * or to start a loop in synchronization with a loop that is already playing\n * This method will schedule the implicit loop in sync with the explicit master loop\n * i.e. loopToStart.syncedStart(loopToSyncWith)\n *\n * @method syncedStart\n * @for p5.SoundLoop\n * @param {Object} otherLoop a p5.SoundLoop to sync with\n * @param {Number} [timeFromNow] Start the loops in sync after timeFromNow seconds\n */\n p5.SoundLoop.prototype.syncedStart = function(otherLoop, timeFromNow) {\n var t = timeFromNow || 0;\n var now = p5sound.audiocontext.currentTime;\n\n if (!otherLoop.isPlaying) {\n otherLoop.clock.start(now + t);\n otherLoop.isPlaying = true;\n this.clock.start(now + t);\n this.isPlaying = true;\n } else if (otherLoop.isPlaying) {\n var time = otherLoop.clock._nextTick - p5sound.audiocontext.currentTime;\n this.clock.start(now + time);\n this.isPlaying = true;\n }\n };\n\n\n /**\n * Updates frequency value, reflected in next callback\n * @private\n * @for p5.SoundLoop\n * @method _update\n */\n p5.SoundLoop.prototype._update = function() {\n this.clock.frequency.value = this._calcFreq();\n };\n\n /**\n * Calculate the frequency of the clock's callback based on bpm, interval, and timesignature\n * @private\n * @for p5.SoundLoop\n * @method _calcFreq\n * @return {Number} new clock frequency value\n */\n p5.SoundLoop.prototype._calcFreq = function() {\n //Seconds mode, bpm / timesignature has no effect\n if (typeof this._interval === 'number') {\n this.musicalTimeMode = false;\n return 1 / this._interval;\n }\n //Musical timing mode, calculate interval based bpm, interval,and time signature\n else if (typeof this._interval === 'string') {\n this.musicalTimeMode = true;\n return this._bpm / 60 / this._convertNotation(this._interval) * (this._timeSignature / 4);\n }\n };\n\n /**\n * Convert notation from musical time format to seconds\n * Uses Tone.Time convention\n * @private\n * @for p5.SoundLoop\n * @method _convertNotation\n * @param {String} value value to be converted\n * @return {Number} converted value in seconds\n */\n p5.SoundLoop.prototype._convertNotation = function(value) {\n var type = value.slice(-1);\n value = Number(value.slice(0,-1));\n switch (type) {\n case 'm':\n return this._measure(value);\n case 'n':\n return this._note(value);\n default:\n console.warn('Specified interval is not formatted correctly. See Tone.js '+\n 'timing reference for more info: https://github.com/Tonejs/Tone.js/wiki/Time');\n }\n };\n\n /**\n * Helper conversion methods of measure and note\n * @private\n * @for p5.SoundLoop\n * @method _measure\n */\n p5.SoundLoop.prototype._measure = function(value) {\n return value * this._timeSignature;\n };\n\n /**\n * @private\n * @method _note\n * @for p5.SoundLoop\n */\n p5.SoundLoop.prototype._note = function(value) {\n return this._timeSignature / value ;\n };\n\n\n /**\n * Getters and Setters, setting any paramter will result in a change in the clock's\n * frequency, that will be reflected after the next callback\n * beats per minute (defaults to 60)\n * @property {Number} bpm\n * @for p5.SoundLoop\n */\n Object.defineProperty(p5.SoundLoop.prototype, 'bpm', {\n get : function() {\n return this._bpm;\n },\n set : function(bpm) {\n if (!this.musicalTimeMode) {\n console.warn('Changing the BPM in \"seconds\" mode has no effect. '+\n 'BPM is only relevant in musicalTimeMode '+\n 'when the interval is specified as a string '+\n '(\"2n\", \"4n\", \"1m\"...etc)');\n }\n this._bpm = bpm;\n this._update();\n }\n });\n\n /**\n * number of quarter notes in a measure (defaults to 4)\n * @property {Number} timeSignature\n * @for p5.SoundLoop\n */\n Object.defineProperty(p5.SoundLoop.prototype, 'timeSignature', {\n get : function() {\n return this._timeSignature;\n },\n set : function(timeSig) {\n if (!this.musicalTimeMode) {\n console.warn('Changing the timeSignature in \"seconds\" mode has no effect. '+\n 'BPM is only relevant in musicalTimeMode '+\n 'when the interval is specified as a string '+\n '(\"2n\", \"4n\", \"1m\"...etc)');\n }\n this._timeSignature = timeSig;\n this._update();\n }\n });\n\n /**\n * length of the loops interval\n * @property {Number|String} interval\n * @for p5.SoundLoop\n */\n Object.defineProperty(p5.SoundLoop.prototype, 'interval', {\n get : function() {\n return this._interval;\n },\n set : function(interval) {\n this.musicalTimeMode = typeof interval === 'Number'? false : true;\n this._interval = interval;\n this._update();\n }\n });\n\n /**\n * how many times the callback has been called so far\n * @property {Number} iterations\n * @for p5.SoundLoop\n * @readonly\n */\n Object.defineProperty(p5.SoundLoop.prototype, 'iterations', {\n get : function() {\n return this.clock.ticks;\n }\n });\n\n return p5.SoundLoop;\n});\n","define(function (require) {\n\t'use strict';\n\n\tvar p5sound = require('master');\n\tvar Effect = require('effect');\n var CustomError = require('errorHandler');\n\n /**\n * Compressor is an audio effect class that performs dynamics compression\n * on an audio input source. This is a very commonly used technique in music\n * and sound production. Compression creates an overall louder, richer,\n * and fuller sound by lowering the volume of louds and raising that of softs.\n * Compression can be used to avoid clipping (sound distortion due to\n * peaks in volume) and is especially useful when many sounds are played\n * at once. Compression can be used on indivudal sound sources in addition\n * to the master output.\n *\n * This class extends p5.Effect.\n * Methods amp(), chain(),\n * drywet(), connect(), and\n * disconnect() are available.\n *\n * @class p5.Compressor\n * @constructor\n * @extends p5.Effect\n *\n *\n */\n\tp5.Compressor = function() {\n\t\tEffect.call(this);\n\n /**\n * The p5.Compressor is built with a Web Audio Dynamics Compressor Node\n * \n * @property {AudioNode} compressor\n */\n\n\n\t\tthis.compressor = this.ac.createDynamicsCompressor();\n\n this.input.connect(this.compressor);\n this.compressor.connect(this.wet);\n\t};\n\n\tp5.Compressor.prototype = Object.create(Effect.prototype);\n\n /**\n * Performs the same function as .connect, but also accepts\n * optional parameters to set compressor's audioParams\n * @method process\n * @for p5.Compressor\n *\n * @param {Object} src Sound source to be connected\n *\n * @param {Number} [attack] The amount of time (in seconds) to reduce the gain by 10dB,\n * default = .003, range 0 - 1\n * @param {Number} [knee] A decibel value representing the range above the\n * threshold where the curve smoothly transitions to the \"ratio\" portion.\n * default = 30, range 0 - 40\n * @param {Number} [ratio] The amount of dB change in input for a 1 dB change in output\n * default = 12, range 1 - 20\n * @param {Number} [threshold] The decibel value above which the compression will start taking effect\n * default = -24, range -100 - 0\n * @param {Number} [release] The amount of time (in seconds) to increase the gain by 10dB\n * default = .25, range 0 - 1\n */\n\tp5.Compressor.prototype.process = function(src, attack, knee,\n ratio, threshold, release) {\n\t\tsrc.connect(this.input);\n\t\tthis.set(attack, knee, ratio, threshold, release);\n\t};\n\n /**\n * Set the paramters of a compressor.\n * @method set\n * @for p5.Compressor\n * @param {Number} attack The amount of time (in seconds) to reduce the gain by 10dB,\n * default = .003, range 0 - 1\n * @param {Number} knee A decibel value representing the range above the\n * threshold where the curve smoothly transitions to the \"ratio\" portion.\n * default = 30, range 0 - 40\n * @param {Number} ratio The amount of dB change in input for a 1 dB change in output\n * default = 12, range 1 - 20\n * @param {Number} threshold The decibel value above which the compression will start taking effect\n * default = -24, range -100 - 0\n * @param {Number} release The amount of time (in seconds) to increase the gain by 10dB\n * default = .25, range 0 - 1\n */\n p5.Compressor.prototype.set = function (attack, knee,\n ratio, threshold, release) {\n\n if (typeof attack !== 'undefined') {this.attack(attack);}\n if (typeof knee !== 'undefined') {this.knee(knee);}\n if (typeof ratio !== 'undefined') {this.ratio(ratio);}\n if (typeof threshold !== 'undefined') {this.threshold(threshold);}\n if (typeof release !== 'undefined') {this.release(release);}\n };\n\n\n /**\n * Get current attack or set value w/ time ramp\n *\n *\n * @method attack\n * @for p5.Compressor\n * @param {Number} [attack] Attack is the amount of time (in seconds) to reduce the gain by 10dB,\n * default = .003, range 0 - 1\n * @param {Number} [time] Assign time value to schedule the change in value\n */\n p5.Compressor.prototype.attack = function (attack, time){\n var t = time || 0;\n if (typeof attack == 'number'){\n this.compressor.attack.value = attack;\n this.compressor.attack.cancelScheduledValues(this.ac.currentTime + 0.01 + t);\n this.compressor.attack.linearRampToValueAtTime(attack, this.ac.currentTime + 0.02 + t);\n } else if (typeof attack !== 'undefined') {\n attack.connect(this.compressor.attack);\n }\n return this.compressor.attack.value;\n };\n\n\n /**\n * Get current knee or set value w/ time ramp\n *\n * @method knee\n * @for p5.Compressor\n * @param {Number} [knee] A decibel value representing the range above the\n * threshold where the curve smoothly transitions to the \"ratio\" portion.\n * default = 30, range 0 - 40\n * @param {Number} [time] Assign time value to schedule the change in value\n */\n p5.Compressor.prototype.knee = function (knee, time){\n var t = time || 0;\n if (typeof knee == 'number'){\n this.compressor.knee.value = knee;\n this.compressor.knee.cancelScheduledValues(this.ac.currentTime + 0.01 + t);\n this.compressor.knee.linearRampToValueAtTime(knee, this.ac.currentTime + 0.02 + t);\n } else if (typeof knee !== 'undefined') {\n knee.connect(this.compressor.knee);\n }\n return this.compressor.knee.value;\n };\n\n\n /**\n * Get current ratio or set value w/ time ramp\n * @method ratio\n * @for p5.Compressor\n * @param {Number} [ratio] The amount of dB change in input for a 1 dB change in output\n * default = 12, range 1 - 20\n * @param {Number} [time] Assign time value to schedule the change in value\n */\n p5.Compressor.prototype.ratio = function (ratio, time){\n var t = time || 0;\n if (typeof ratio == 'number'){\n this.compressor.ratio.value = ratio;\n this.compressor.ratio.cancelScheduledValues(this.ac.currentTime + 0.01 + t);\n this.compressor.ratio.linearRampToValueAtTime(ratio, this.ac.currentTime + 0.02 + t);\n } else if (typeof ratio !== 'undefined') {\n ratio.connect(this.compressor.ratio);\n }\n return this.compressor.ratio.value;\n };\n\n\n /**\n * Get current threshold or set value w/ time ramp\n * @method threshold\n * @for p5.Compressor\n * @param {Number} threshold The decibel value above which the compression will start taking effect\n * default = -24, range -100 - 0\n * @param {Number} [time] Assign time value to schedule the change in value\n */\n p5.Compressor.prototype.threshold = function (threshold, time){\n var t = time || 0;\n if (typeof threshold == 'number'){\n this.compressor.threshold.value = threshold;\n this.compressor.threshold.cancelScheduledValues(this.ac.currentTime + 0.01 + t);\n this.compressor.threshold.linearRampToValueAtTime(threshold, this.ac.currentTime + 0.02 + t);\n } else if (typeof threshold !== 'undefined') {\n threshold.connect(this.compressor.threshold);\n }\n return this.compressor.threshold.value;\n };\n\n\n /**\n * Get current release or set value w/ time ramp\n * @method release\n * @for p5.Compressor\n * @param {Number} release The amount of time (in seconds) to increase the gain by 10dB\n * default = .25, range 0 - 1\n *\n * @param {Number} [time] Assign time value to schedule the change in value\n */\n p5.Compressor.prototype.release = function (release, time){\n var t = time || 0;\n if (typeof release == 'number'){\n this.compressor.release.value = release;\n this.compressor.release.cancelScheduledValues(this.ac.currentTime + 0.01 + t);\n this.compressor.release.linearRampToValueAtTime(release, this.ac.currentTime + 0.02 + t);\n } else if (typeof number !== 'undefined') {\n release.connect(this.compressor.release);\n }\n return this.compressor.release.value;\n };\n\n /**\n * Return the current reduction value\n *\n * @method reduction\n * @for p5.Compressor\n * @return {Number} Value of the amount of gain reduction that is applied to the signal\n */\n p5.Compressor.prototype.reduction =function() {\n return this.compressor.reduction.value;\n };\n\n\n\tp5.Compressor.prototype.dispose = function() {\n Effect.prototype.dispose.apply(this);\n if (this.compressor) {\n this.compressor.disconnect();\n delete this.compressor;\n }\n\t};\n\n return p5.Compressor;\n});\n","'use strict';\n\ndefine(function (require) {\n\n // inspiration: recorder.js, Tone.js & typedarray.org\n\n var p5sound = require('master');\n var convertToWav = require('helpers').convertToWav;\n var processorNames = require('./audioWorklet/processorNames');\n var ac = p5sound.audiocontext;\n\n /**\n *
Record sounds for playback and/or to save as a .wav file.\n * The p5.SoundRecorder records all sound output from your sketch,\n * or can be assigned a specific source with setInput().
\n *
The record() method accepts a p5.SoundFile as a parameter.\n * When playback is stopped (either after the given amount of time,\n * or with the stop() method), the p5.SoundRecorder will send its\n * recording to that p5.SoundFile for playback.
\n * var mic, recorder, soundFile;\n * var state = 0;\n *\n * function setup() {\n * background(200);\n * // create an audio in\n * mic = new p5.AudioIn();\n *\n * // prompts user to enable their browser mic\n * mic.start();\n *\n * // create a sound recorder\n * recorder = new p5.SoundRecorder();\n *\n * // connect the mic to the recorder\n * recorder.setInput(mic);\n *\n * // this sound file will be used to\n * // playback & save the recording\n * soundFile = new p5.SoundFile();\n *\n * text('keyPress to record', 20, 20);\n * }\n *\n * function keyPressed() {\n * // make sure user enabled the mic\n * if (state === 0 && mic.enabled) {\n *\n * // record to our p5.SoundFile\n * recorder.record(soundFile);\n *\n * background(255,0,0);\n * text('Recording!', 20, 20);\n * state++;\n * }\n * else if (state === 1) {\n * background(0,255,0);\n *\n * // stop recorder and\n * // send result to soundFile\n * recorder.stop();\n *\n * text('Stopped', 20, 20);\n * state++;\n * }\n *\n * else if (state === 2) {\n * soundFile.play(); // play the result!\n * save(soundFile, 'mySound.wav');\n * state++;\n * }\n * }\n *
\n */\n p5.SoundRecorder = function() {\n this.input = ac.createGain();\n this.output = ac.createGain();\n\n this._inputChannels = 2;\n this._outputChannels = 2; // stereo output, even if input is mono\n\n this._workletNode = new AudioWorkletNode(ac, processorNames.recorderProcessor, {\n outputChannelCount: [this._outputChannels],\n processorOptions: { numInputChannels: this._inputChannels }\n });\n\n this._workletNode.port.onmessage = function(event) {\n if (event.data.name === 'buffers') {\n const buffers = [\n new Float32Array(event.data.leftBuffer),\n new Float32Array(event.data.rightBuffer)\n ];\n this._callback(buffers);\n }\n }.bind(this);\n\n /**\n * callback invoked when the recording is over\n * @private\n * @type Function(Float32Array)\n */\n this._callback = function() {};\n\n // connections\n this._workletNode.connect(p5.soundOut._silentNode);\n this.setInput();\n\n // add this p5.SoundFile to the soundArray\n p5sound.soundArray.push(this);\n };\n\n /**\n * Connect a specific device to the p5.SoundRecorder.\n * If no parameter is given, p5.SoundRecorer will record\n * all audible p5.sound from your sketch.\n *\n * @method setInput\n * @for p5.SoundRecorder\n * @param {Object} [unit] p5.sound object or a web audio unit\n * that outputs sound\n */\n p5.SoundRecorder.prototype.setInput = function(unit) {\n this.input.disconnect();\n this.input = null;\n this.input = ac.createGain();\n this.input.connect(this._workletNode);\n this.input.connect(this.output);\n if (unit) {\n unit.connect(this.input);\n } else {\n p5.soundOut.output.connect(this.input);\n }\n };\n\n /**\n * Start recording. To access the recording, provide\n * a p5.SoundFile as the first parameter. The p5.SoundRecorder\n * will send its recording to that p5.SoundFile for playback once\n * recording is complete. Optional parameters include duration\n * (in seconds) of the recording, and a callback function that\n * will be called once the complete recording has been\n * transfered to the p5.SoundFile.\n *\n * @method record\n * @for p5.SoundRecorder\n * @param {p5.SoundFile} soundFile p5.SoundFile\n * @param {Number} [duration] Time (in seconds)\n * @param {Function} [callback] The name of a function that will be\n * called once the recording completes\n */\n p5.SoundRecorder.prototype.record = function(sFile, duration, callback) {\n this._workletNode.port.postMessage({ name: 'start', duration: duration });\n\n if (sFile && callback) {\n this._callback = function(buffer) {\n sFile.setBuffer(buffer);\n callback();\n };\n }\n else if (sFile) {\n this._callback = function(buffer) {\n sFile.setBuffer(buffer);\n };\n }\n };\n\n /**\n * Stop the recording. Once the recording is stopped,\n * the results will be sent to the p5.SoundFile that\n * was given on .record(), and if a callback function\n * was provided on record, that function will be called.\n *\n * @method stop\n * @for p5.SoundRecorder\n */\n p5.SoundRecorder.prototype.stop = function() {\n this._workletNode.port.postMessage({ name: 'stop' });\n };\n\n p5.SoundRecorder.prototype.dispose = function() {\n // remove reference from soundArray\n var index = p5sound.soundArray.indexOf(this);\n p5sound.soundArray.splice(index, 1);\n\n this._callback = function() {};\n if (this.input) {\n this.input.disconnect();\n }\n this.input = null;\n this._workletNode = null;\n };\n\n\n /**\n * Save a p5.SoundFile as a .wav file. The browser will prompt the user\n * to download the file to their device.\n * For uploading audio to a server, use\n * `p5.SoundFile.saveBlob`.\n *\n * @for p5\n * @method saveSound\n * @param {p5.SoundFile} soundFile p5.SoundFile that you wish to save\n * @param {String} fileName name of the resulting .wav file.\n */\n // add to p5.prototype as this is used by the p5 `save()` method.\n p5.prototype.saveSound = function (soundFile, fileName) {\n const dataView = convertToWav(soundFile.buffer);\n p5.prototype.writeFile([dataView], fileName, 'wav');\n };\n});\n","'use strict';\n\ndefine(function () {\n /**\n *
PeakDetect works in conjunction with p5.FFT to\n * look for onsets in some or all of the frequency spectrum.\n *
\n *
\n * To use p5.PeakDetect, call update in the draw loop\n * and pass in a p5.FFT object.\n *
\n *
\n * You can listen for a specific part of the frequency spectrum by\n * setting the range between freq1 and freq2.\n *
\n *\n *
threshold is the threshold for detecting a peak,\n * scaled between 0 and 1. It is logarithmic, so 0.1 is half as loud\n * as 1.0.
\n *\n *
\n * The update method is meant to be run in the draw loop, and\n * frames determines how many loops must pass before\n * another peak can be detected.\n * For example, if the frameRate() = 60, you could detect the beat of a\n * 120 beat-per-minute song with this equation:\n * framesPerPeak = 60 / (estimatedBPM / 60 );\n *
\n *\n *
\n * Based on example contribtued by @b2renger, and a simple beat detection\n * explanation by Felix Turner.\n *
\n *\n * @class p5.PeakDetect\n * @constructor\n * @param {Number} [freq1] lowFrequency - defaults to 20Hz\n * @param {Number} [freq2] highFrequency - defaults to 20000 Hz\n * @param {Number} [threshold] Threshold for detecting a beat between 0 and 1\n * scaled logarithmically where 0.1 is 1/2 the loudness\n * of 1.0. Defaults to 0.35.\n * @param {Number} [framesPerPeak] Defaults to 20.\n * @example\n *
\n */\n p5.PeakDetect = function(freq1, freq2, threshold, _framesPerPeak) {\n // framesPerPeak determines how often to look for a beat.\n // If a beat is provided, try to look for a beat based on bpm\n this.framesPerPeak = _framesPerPeak || 20;\n this.framesSinceLastPeak = 0;\n this.decayRate = 0.95;\n\n this.threshold = threshold || 0.35;\n this.cutoff = 0;\n\n // how much to increase the cutoff\n // TO DO: document this / figure out how to make it accessible\n this.cutoffMult = 1.5;\n\n this.energy = 0;\n this.penergy = 0;\n\n // TO DO: document this property / figure out how to make it accessible\n this.currentValue = 0;\n\n /**\n * isDetected is set to true when a peak is detected.\n *\n * @attribute isDetected {Boolean}\n * @default false\n */\n this.isDetected = false;\n\n this.f1 = freq1 || 40;\n this.f2 = freq2 || 20000;\n\n // function to call when a peak is detected\n this._onPeak = function() {};\n };\n\n\n /**\n * The update method is run in the draw loop.\n *\n * Accepts an FFT object. You must call .analyze()\n * on the FFT object prior to updating the peakDetect\n * because it relies on a completed FFT analysis.\n *\n * @method update\n * @param {p5.FFT} fftObject A p5.FFT object\n */\n p5.PeakDetect.prototype.update = function(fftObject) {\n var nrg = this.energy = fftObject.getEnergy(this.f1,this.f2)/255;\n if (nrg > this.cutoff && nrg > this.threshold && nrg-this.penergy > 0) {\n\n // trigger callback\n this._onPeak();\n this.isDetected = true;\n\n // debounce\n this.cutoff = nrg * this.cutoffMult;\n this.framesSinceLastPeak = 0;\n } else {\n this.isDetected = false;\n if (this.framesSinceLastPeak <= this.framesPerPeak) {\n this.framesSinceLastPeak++;\n } else {\n this.cutoff *= this.decayRate;\n this.cutoff = Math.max(this.cutoff, this.threshold);\n }\n }\n\n this.currentValue = nrg;\n this.penergy = nrg;\n };\n\n /**\n * onPeak accepts two arguments: a function to call when\n * a peak is detected. The value of the peak,\n * between 0.0 and 1.0, is passed to the callback.\n *\n * @method onPeak\n * @param {Function} callback Name of a function that will\n * be called when a peak is\n * detected.\n * @param {Object} [val] Optional value to pass\n * into the function when\n * a peak is detected.\n * @example\n *
\n * var cnv, soundFile, fft, peakDetect;\n * var ellipseWidth = 0;\n *\n * function preload() {\n * soundFile = loadSound('assets/beat.mp3');\n * }\n *\n * function setup() {\n * cnv = createCanvas(100,100);\n * textAlign(CENTER);\n *\n * fft = new p5.FFT();\n * peakDetect = new p5.PeakDetect();\n *\n * setupSound();\n *\n * // when a beat is detected, call triggerBeat()\n * peakDetect.onPeak(triggerBeat);\n * }\n *\n * function draw() {\n * background(0);\n * fill(255);\n * text('click to play', width/2, height/2);\n *\n * fft.analyze();\n * peakDetect.update(fft);\n *\n * ellipseWidth *= 0.95;\n * ellipse(width/2, height/2, ellipseWidth, ellipseWidth);\n * }\n *\n * // this function is called by peakDetect.onPeak\n * function triggerBeat() {\n * ellipseWidth = 50;\n * }\n *\n * // mouseclick starts/stops sound\n * function setupSound() {\n * cnv.mouseClicked( function() {\n * if (soundFile.isPlaying() ) {\n * soundFile.stop();\n * } else {\n * soundFile.play();\n * }\n * });\n * }\n *
\n */\n p5.PeakDetect.prototype.onPeak = function(callback, val) {\n var self = this;\n\n self._onPeak = function() {\n callback(self.energy, val);\n };\n };\n\n});\n","'use strict';\n\ndefine(function (require) {\n var p5sound = require('master');\n\n /**\n * A gain node is usefull to set the relative volume of sound.\n * It's typically used to build mixers.\n *\n * @class p5.Gain\n * @constructor\n * @example\n *
\n *\n * // load two soundfile and crossfade beetween them\n * var sound1,sound2;\n * var gain1, gain2, gain3;\n *\n * function preload(){\n * soundFormats('ogg', 'mp3');\n * sound1 = loadSound('assets/Damscray_-_Dancing_Tiger_01');\n * sound2 = loadSound('assets/beat.mp3');\n * }\n *\n * function setup() {\n * createCanvas(400,200);\n *\n * // create a 'master' gain to which we will connect both soundfiles\n * gain3 = new p5.Gain();\n * gain3.connect();\n *\n * // setup first sound for playing\n * sound1.rate(1);\n * sound1.loop();\n * sound1.disconnect(); // diconnect from p5 output\n *\n * gain1 = new p5.Gain(); // setup a gain node\n * gain1.setInput(sound1); // connect the first sound to its input\n * gain1.connect(gain3); // connect its output to the 'master'\n *\n * sound2.rate(1);\n * sound2.disconnect();\n * sound2.loop();\n *\n * gain2 = new p5.Gain();\n * gain2.setInput(sound2);\n * gain2.connect(gain3);\n *\n * }\n *\n * function draw(){\n * background(180);\n *\n * // calculate the horizontal distance beetween the mouse and the right of the screen\n * var d = dist(mouseX,0,width,0);\n *\n * // map the horizontal position of the mouse to values useable for volume control of sound1\n * var vol1 = map(mouseX,0,width,0,1);\n * var vol2 = 1-vol1; // when sound1 is loud, sound2 is quiet and vice versa\n *\n * gain1.amp(vol1,0.5,0);\n * gain2.amp(vol2,0.5,0);\n *\n * // map the vertical position of the mouse to values useable for 'master volume control'\n * var vol3 = map(mouseY,0,height,0,1);\n * gain3.amp(vol3,0.5,0);\n * }\n *
\n *\n */\n\n p5.Gain = function() {\n this.ac = p5sound.audiocontext;\n\n this.input = this.ac.createGain();\n this.output = this.ac.createGain();\n\n // otherwise, Safari distorts\n this.input.gain.value = 0.5;\n this.input.connect(this.output);\n\n // add to the soundArray\n p5sound.soundArray.push(this);\n };\n\n /**\n * Connect a source to the gain node.\n *\n * @method setInput\n * @for p5.Gain\n * @param {Object} src p5.sound / Web Audio object with a sound\n * output.\n */\n\n\n p5.Gain.prototype.setInput = function(src) {\n src.connect(this.input);\n };\n\n /**\n * Send output to a p5.sound or web audio object\n *\n * @method connect\n * @for p5.Gain\n * @param {Object} unit\n */\n p5.Gain.prototype.connect = function(unit) {\n var u = unit || p5.soundOut.input;\n this.output.connect(u.input ? u.input : u);\n };\n\n /**\n * Disconnect all output.\n *\n * @method disconnect\n * @for p5.Gain\n */\n p5.Gain.prototype.disconnect = function() {\n if (this.output) {\n this.output.disconnect();\n }\n };\n\n /**\n * Set the output level of the gain node.\n *\n * @method amp\n * @for p5.Gain\n * @param {Number} volume amplitude between 0 and 1.0\n * @param {Number} [rampTime] create a fade that lasts rampTime\n * @param {Number} [timeFromNow] schedule this event to happen\n * seconds from now\n */\n p5.Gain.prototype.amp = function(vol, rampTime, tFromNow) {\n var rampTime = rampTime || 0;\n var tFromNow = tFromNow || 0;\n var now = p5sound.audiocontext.currentTime;\n var currentVol = this.output.gain.value;\n this.output.gain.cancelScheduledValues(now);\n this.output.gain.linearRampToValueAtTime(currentVol, now + tFromNow);\n this.output.gain.linearRampToValueAtTime(vol, now + tFromNow + rampTime);\n };\n\n p5.Gain.prototype.dispose = function() {\n // remove reference from soundArray\n var index = p5sound.soundArray.indexOf(this);\n p5sound.soundArray.splice(index, 1);\n if (this.output) {\n this.output.disconnect();\n delete this.output;\n }\n if (this.input) {\n this.input.disconnect();\n delete this.input;\n }\n };\n\n});\n","'use strict';\n\ndefine(function (require) {\n\n var Effect = require('effect');\n\n /*\n * Adapted from [Kevin Ennis on StackOverflow](http://stackoverflow.com/questions/22312841/waveshaper-node-in-webaudio-how-to-emulate-distortion)\n */\n function makeDistortionCurve(amount) {\n var k = typeof amount === 'number' ? amount : 50;\n var numSamples = 44100;\n var curve = new Float32Array(numSamples);\n var deg = Math.PI / 180;\n var i = 0;\n var x;\n for ( ; i < numSamples; ++i ) {\n x = i * 2 / numSamples - 1;\n curve[i] = ( 3 + k ) * x * 20 * deg / ( Math.PI + k * Math.abs(x) );\n }\n return curve;\n }\n\n /**\n * A Distortion effect created with a Waveshaper Node,\n * with an approach adapted from\n * [Kevin Ennis](http://stackoverflow.com/questions/22312841/waveshaper-node-in-webaudio-how-to-emulate-distortion)\n *\n * This class extends p5.Effect.\n * Methods amp(), chain(),\n * drywet(), connect(), and\n * disconnect() are available.\n *\n * @class p5.Distortion\n * @extends p5.Effect\n * @constructor\n * @param {Number} [amount=0.25] Unbounded distortion amount.\n * Normal values range from 0-1.\n * @param {String} [oversample='none'] 'none', '2x', or '4x'.\n *\n */\n p5.Distortion = function(amount, oversample) {\n Effect.call(this);\n\n if (typeof amount === 'undefined') {\n amount = 0.25;\n } if (typeof amount !== 'number') {\n throw new Error('amount must be a number');\n } if (typeof oversample === 'undefined') {\n oversample = '2x';\n } if (typeof oversample !== 'string') {\n throw new Error('oversample must be a String');\n }\n\n var curveAmount = p5.prototype.map(amount, 0.0, 1.0, 0, 2000);\n\n /**\n * The p5.Distortion is built with a\n * \n * Web Audio WaveShaper Node.\n *\n * @property {AudioNode} WaveShaperNode\n */\n this.waveShaperNode = this.ac.createWaveShaper();\n\n this.amount = curveAmount;\n this.waveShaperNode.curve = makeDistortionCurve(curveAmount);\n this.waveShaperNode.oversample = oversample;\n\n this.input.connect(this.waveShaperNode);\n\n this.waveShaperNode.connect(this.wet);\n };\n\n p5.Distortion.prototype = Object.create(Effect.prototype);\n\n\n /**\n * Process a sound source, optionally specify amount and oversample values.\n *\n * @method process\n * @for p5.Distortion\n * @param {Number} [amount=0.25] Unbounded distortion amount.\n * Normal values range from 0-1.\n * @param {String} [oversample='none'] 'none', '2x', or '4x'.\n */\n p5.Distortion.prototype.process = function(src, amount, oversample) {\n src.connect(this.input);\n this.set(amount, oversample);\n };\n\n /**\n * Set the amount and oversample of the waveshaper distortion.\n *\n * @method set\n * @for p5.Distortion\n * @param {Number} [amount=0.25] Unbounded distortion amount.\n * Normal values range from 0-1.\n * @param {String} [oversample='none'] 'none', '2x', or '4x'.\n */\n p5.Distortion.prototype.set = function(amount, oversample) {\n if (amount) {\n var curveAmount = p5.prototype.map(amount, 0.0, 1.0, 0, 2000);\n this.amount = curveAmount;\n this.waveShaperNode.curve = makeDistortionCurve(curveAmount);\n }\n if (oversample) {\n this.waveShaperNode.oversample = oversample;\n }\n };\n\n /**\n * Return the distortion amount, typically between 0-1.\n *\n * @method getAmount\n * @for p5.Distortion\n * @return {Number} Unbounded distortion amount.\n * Normal values range from 0-1.\n */\n p5.Distortion.prototype.getAmount = function() {\n return this.amount;\n };\n\n /**\n * Return the oversampling.\n *\n * @method getOversample\n * @for p5.Distortion\n * @return {String} Oversample can either be 'none', '2x', or '4x'.\n */\n p5.Distortion.prototype.getOversample = function() {\n return this.waveShaperNode.oversample;\n };\n\n\n p5.Distortion.prototype.dispose = function() {\n Effect.prototype.dispose.apply(this);\n if (this.waveShaperNode) {\n this.waveShaperNode.disconnect();\n this.waveShaperNode = null;\n }\n };\n});\n"],"sourceRoot":""}
\ No newline at end of file
diff --git a/lib/p5.sound.min.js b/lib/p5.sound.min.js
index 7c9e7f89..df30d8f1 100644
--- a/lib/p5.sound.min.js
+++ b/lib/p5.sound.min.js
@@ -1,2 +1,2 @@
-!function(i){var n={};function o(t){if(n[t])return n[t].exports;var e=n[t]={i:t,l:!1,exports:{}};return i[t].call(e.exports,e,e.exports,o),e.l=!0,e.exports}o.m=i,o.c=n,o.d=function(t,e,i){o.o(t,e)||Object.defineProperty(t,e,{enumerable:!0,get:i})},o.r=function(t){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(t,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(t,"__esModule",{value:!0})},o.t=function(e,t){if(1&t&&(e=o(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var i=Object.create(null);if(o.r(i),Object.defineProperty(i,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var n in e)o.d(i,n,function(t){return e[t]}.bind(null,n));return i},o.n=function(t){var e=t&&t.__esModule?function(){return t.default}:function(){return t};return o.d(e,"a",e),e},o.o=function(t,e){return Object.prototype.hasOwnProperty.call(t,e)},o.p="",o(o.s=31)}([function(t,e,i){var n;void 0===(n=function(){"use strict";function c(t,e){this.isUndef(t)||1===t?this.input=this.context.createGain():1t)this.cancelScheduledValues(t),this.linearRampToValueAtTime(e,t);else{var n=this._searchAfter(t);n&&(this.cancelScheduledValues(t),n.type===u.TimelineSignal.Type.Linear?this.linearRampToValueAtTime(e,t):n.type===u.TimelineSignal.Type.Exponential&&this.exponentialRampToValueAtTime(e,t)),this.setValueAtTime(e,t)}return this},u.TimelineSignal.prototype.linearRampToValueBetween=function(t,e,i){return this.setRampPoint(e),this.linearRampToValueAtTime(t,i),this},u.TimelineSignal.prototype.exponentialRampToValueBetween=function(t,e,i){return this.setRampPoint(e),this.exponentialRampToValueAtTime(t,i),this},u.TimelineSignal.prototype._searchBefore=function(t){return this._events.get(t)},u.TimelineSignal.prototype._searchAfter=function(t){return this._events.getAfter(t)},u.TimelineSignal.prototype.getValueAtTime=function(t){t=this.toSeconds(t);var e=this._searchAfter(t),i=this._searchBefore(t),n=this._initial;if(null===i)n=this._initial;else if(i.type===u.TimelineSignal.Type.Target){var o,r=this._events.getBefore(i.time);o=null===r?this._initial:r.value,n=this._exponentialApproach(i.time,o,i.value,i.constant,t)}else n=i.type===u.TimelineSignal.Type.Curve?this._curveInterpolate(i.time,i.value,i.duration,t):null===e?i.value:e.type===u.TimelineSignal.Type.Linear?this._linearInterpolate(i.time,i.value,e.time,e.value,t):e.type===u.TimelineSignal.Type.Exponential?this._exponentialInterpolate(i.time,i.value,e.time,e.value,t):i.value;return n},u.TimelineSignal.prototype.connect=u.SignalBase.prototype.connect,u.TimelineSignal.prototype._exponentialApproach=function(t,e,i,n,o){return i+(e-i)*Math.exp(-(o-t)/n)},u.TimelineSignal.prototype._linearInterpolate=function(t,e,i,n,o){return e+(o-t)/(i-t)*(n-e)},u.TimelineSignal.prototype._exponentialInterpolate=function(t,e,i,n,o){return(e=Math.max(this._minOutput,e))*Math.pow(n/e,(o-t)/(i-t))},u.TimelineSignal.prototype._curveInterpolate=function(t,e,i,n){var o=e.length;if(t+i<=n)return e[o-1];if(n<=t)return e[0];var r=(n-t)/i,s=Math.floor((o-1)*r),a=Math.ceil((o-1)*r),u=e[s],p=e[a];return a===s?u:this._linearInterpolate(s,u,a,p,r*(o-1))},u.TimelineSignal.prototype.dispose=function(){u.Signal.prototype.dispose.call(this),u.Param.prototype.dispose.call(this),this._events.dispose(),this._events=null},u.TimelineSignal}.apply(e,n))||(t.exports=o)},function(t,e,i){"use strict";var n;void 0===(n=function(t){var e=i(4);return p5.Filter=function(t){e.call(this),this.biquad=this.ac.createBiquadFilter(),this.input.connect(this.biquad),this.biquad.connect(this.wet),t&&this.setType(t),this._on=!0,this._untoggledType=this.biquad.type},p5.Filter.prototype=Object.create(e.prototype),p5.Filter.prototype.process=function(t,e,i,n){t.connect(this.input),this.set(e,i,n)},p5.Filter.prototype.set=function(t,e,i){t&&this.freq(t,i),e&&this.res(e,i)},p5.Filter.prototype.freq=function(t,e){var i=e||0;return t<=0&&(t=1),"number"==typeof t?(this.biquad.frequency.cancelScheduledValues(this.ac.currentTime+.01+i),this.biquad.frequency.exponentialRampToValueAtTime(t,this.ac.currentTime+.02+i)):t&&t.connect(this.biquad.frequency),this.biquad.frequency.value},p5.Filter.prototype.res=function(t,e){var i=e||0;return"number"==typeof t?(this.biquad.Q.value=t,this.biquad.Q.cancelScheduledValues(this.ac.currentTime+.01+i),this.biquad.Q.linearRampToValueAtTime(t,this.ac.currentTime+.02+i)):t&&t.connect(this.biquad.Q),this.biquad.Q.value},p5.Filter.prototype.gain=function(t,e){var i=e||0;return"number"==typeof t?(this.biquad.gain.value=t,this.biquad.gain.cancelScheduledValues(this.ac.currentTime+.01+i),this.biquad.gain.linearRampToValueAtTime(t,this.ac.currentTime+.02+i)):t&&t.connect(this.biquad.gain),this.biquad.gain.value},p5.Filter.prototype.toggle=function(){return this._on=!this._on,!0===this._on?this.biquad.type=this._untoggledType:!1===this._on&&(this.biquad.type="allpass"),this._on},p5.Filter.prototype.setType=function(t){this.biquad.type=t,this._untoggledType=this.biquad.type},p5.Filter.prototype.dispose=function(){e.prototype.dispose.apply(this),this.biquad&&(this.biquad.disconnect(),delete this.biquad)},p5.LowPass=function(){p5.Filter.call(this,"lowpass")},p5.LowPass.prototype=Object.create(p5.Filter.prototype),p5.HighPass=function(){p5.Filter.call(this,"highpass")},p5.HighPass.prototype=Object.create(p5.Filter.prototype),p5.BandPass=function(){p5.Filter.call(this,"bandpass")},p5.BandPass.prototype=Object.create(p5.Filter.prototype),p5.Filter}.call(e,i,e,t))||(t.exports=n)},function(t,e,i){var n,o;n=[i(0),i(7),i(25),i(2),i(9)],void 0===(o=function(e){"use strict";return e.Subtract=function(t){this.createInsOuts(2,0),this._sum=this.input[0]=this.output=new e.Gain,this._neg=new e.Negate,this._param=this.input[1]=new e.Signal(t),this._param.chain(this._neg,this._sum)},e.extend(e.Subtract,e.Signal),e.Subtract.prototype.dispose=function(){return e.prototype.dispose.call(this),this._neg.dispose(),this._neg=null,this._sum.disconnect(),this._sum=null,this._param.dispose(),this._param=null,this},e.Subtract}.apply(e,n))||(t.exports=o)},function(n,o,r){"use strict";(function(t){var e,i;t.TONE_SILENCE_VERSION_LOGGING=!0,e=[r(35),r(11),r(0)],void 0===(i=function(n,t,e){var o=new window.AudioContext;return e.context.dispose(),e.setContext(o),p5.prototype.getAudioContext=function(){return o},p5.prototype.userStartAudio=function(t,e){var i=t;return t instanceof p5.Element?i=t.elt:t instanceof Array&&t[0]instanceof p5.Element&&(i=t.map(function(t){return t.elt})),n(o,i,e)},o}.apply(o,e))||(n.exports=i)}).call(this,r(34))},function(t,e,i){var n,o;n=[i(0)],void 0===(o=function(s){"use strict";return s.Emitter=function(){this._events={}},s.extend(s.Emitter),s.Emitter.prototype.on=function(t,e){for(var i=t.split(/\W+/),n=0;nthis.memory){var i=this.length-this.memory;this._timeline.splice(0,i)}return this},e.Timeline.prototype.remove=function(t){if(this._iterating)this._toRemove.push(t);else{var e=this._timeline.indexOf(t);-1!==e&&this._timeline.splice(e,1)}return this},e.Timeline.prototype.get=function(t){var e=this._search(t);return-1!==e?this._timeline[e]:null},e.Timeline.prototype.peek=function(){return this._timeline[0]},e.Timeline.prototype.shift=function(){return this._timeline.shift()},e.Timeline.prototype.getAfter=function(t){var e=this._search(t);return e+1=t&&(this._timeline=[]);return this},e.Timeline.prototype.cancelBefore=function(t){if(this._timeline.length){var e=this._search(t);0<=e&&(this._timeline=this._timeline.slice(e+1))}return this},e.Timeline.prototype._search=function(t){var e=0,i=this._timeline.length,n=i;if(0t)return o;r.time>t?n=o:r.time=t;)i--;return this._iterate(e,i+1),this},e.Timeline.prototype.forEachAtTime=function(e,i){var t=this._search(e);return-1!==t&&this._iterate(function(t){t.time===e&&i(t)},0,t),this},e.Timeline.prototype.dispose=function(){e.prototype.dispose.call(this),this._timeline=null,this._toRemove=null},e.Timeline}.apply(e,n))||(t.exports=o)},function(t,e,i){var n,o;n=[i(0),i(3),i(2)],void 0===(o=function(t){"use strict";return t.Negate=function(){this._multiply=this.input=this.output=new t.Multiply(-1)},t.extend(t.Negate,t.SignalBase),t.Negate.prototype.dispose=function(){return t.prototype.dispose.call(this),this._multiply.dispose(),this._multiply=null,this},t.Negate}.apply(e,n))||(t.exports=o)},function(t,e,i){var n,o;n=[i(0),i(2),i(3),i(5)],void 0===(o=function(t){"use strict";return t.GreaterThanZero=function(){this._thresh=this.output=new t.WaveShaper(function(t){return t<=0?0:1},127),this._scale=this.input=new t.Multiply(1e4),this._scale.connect(this._thresh)},t.extend(t.GreaterThanZero,t.SignalBase),t.GreaterThanZero.prototype.dispose=function(){return t.prototype.dispose.call(this),this._scale.dispose(),this._scale=null,this._thresh.dispose(),this._thresh=null,this},t.GreaterThanZero}.apply(e,n))||(t.exports=o)},function(t,e,i){var n,o;n=[i(0),i(14),i(66),i(18),i(11)],void 0===(o=function(o){"use strict";return o.Clock=function(){o.Emitter.call(this);var t=this.optionsObject(arguments,["callback","frequency"],o.Clock.defaults);this.callback=t.callback,this._nextTick=0,this._lastState=o.State.Stopped,this.frequency=new o.TimelineSignal(t.frequency,o.Type.Frequency),this._readOnly("frequency"),this.ticks=0,this._state=new o.TimelineState(o.State.Stopped),this._boundLoop=this._loop.bind(this),this.context.on("tick",this._boundLoop)},o.extend(o.Clock,o.Emitter),o.Clock.defaults={callback:o.noOp,frequency:1,lookAhead:"auto"},Object.defineProperty(o.Clock.prototype,"state",{get:function(){return this._state.getValueAtTime(this.now())}}),o.Clock.prototype.start=function(t,e){return t=this.toSeconds(t),this._state.getValueAtTime(t)!==o.State.Started&&this._state.add({state:o.State.Started,time:t,offset:e}),this},o.Clock.prototype.stop=function(t){return t=this.toSeconds(t),this._state.cancel(t),this._state.setStateAtTime(o.State.Stopped,t),this},o.Clock.prototype.pause=function(t){return t=this.toSeconds(t),this._state.getValueAtTime(t)===o.State.Started&&this._state.setStateAtTime(o.State.Paused,t),this},o.Clock.prototype._loop=function(){for(var t=this.now()+this.context.lookAhead+this.context.updateInterval+2*this.context.lag;t>this._nextTick&&this._state;){var e=this._state.getValueAtTime(this._nextTick);if(e!==this._lastState){this._lastState=e;var i=this._state.get(this._nextTick);e===o.State.Started?(this._nextTick=i.time,this.isUndef(i.offset)||(this.ticks=i.offset),this.emit("start",i.time,this.ticks)):e===o.State.Stopped?(this.ticks=0,this.emit("stop",i.time)):e===o.State.Paused&&this.emit("pause",i.time)}var n=this._nextTick;this.frequency&&(this._nextTick+=1/this.frequency.getValueAtTime(this._nextTick),e===o.State.Started&&(this.callback(n),this.ticks++))}},o.Clock.prototype.getStateAtTime=function(t){return t=this.toSeconds(t),this._state.getValueAtTime(t)},o.Clock.prototype.dispose=function(){o.Emitter.prototype.dispose.call(this),this.context.off("tick",this._boundLoop),this._writable("frequency"),this.frequency.dispose(),this.frequency=null,this._boundLoop=null,this._nextTick=1/0,this.callback=null,this._state.dispose(),this._state=null},o.Clock}.apply(e,n))||(t.exports=o)},function(t,e,n){"use strict";var i;void 0===(i=function(t){var i=n(1),e=n(29),r=n(6).noteToFreq;p5.MonoSynth=function(){e.call(this),this.oscillator=new p5.Oscillator,this.env=new p5.Envelope,this.env.setRange(1,0),this.env.setExp(!0),this.setADSR(.02,.25,.05,.35),this.oscillator.disconnect(),this.oscillator.connect(this.output),this.env.disconnect(),this.env.setInput(this.output.gain),this.oscillator.output.gain.value=1,this.oscillator.start(),this.connect(),i.soundArray.push(this)},p5.MonoSynth.prototype=Object.create(p5.AudioVoice.prototype),p5.MonoSynth.prototype.play=function(t,e,i,n){this.triggerAttack(t,e,~~i),this.triggerRelease(~~i+(n||.15))},p5.MonoSynth.prototype.triggerAttack=function(t,e,i){i=~~i;var n=r(t),o=e||.1;this.oscillator.freq(n,0,i),this.env.ramp(this.output.gain,i,o)},p5.MonoSynth.prototype.triggerRelease=function(t){t=t||0;this.env.ramp(this.output.gain,t,0)},p5.MonoSynth.prototype.setADSR=function(t,e,i,n){this.env.setADSR(t,e,i,n)},Object.defineProperties(p5.MonoSynth.prototype,{attack:{get:function(){return this.env.aTime},set:function(t){this.env.setADSR(t,this.env.dTime,this.env.sPercent,this.env.rTime)}},decay:{get:function(){return this.env.dTime},set:function(t){this.env.setADSR(this.env.aTime,t,this.env.sPercent,this.env.rTime)}},sustain:{get:function(){return this.env.sPercent},set:function(t){this.env.setADSR(this.env.aTime,this.env.dTime,t,this.env.rTime)}},release:{get:function(){return this.env.rTime},set:function(t){this.env.setADSR(this.env.aTime,this.env.dTime,this.env.sPercent,t)}}}),p5.MonoSynth.prototype.amp=function(t,e){var i=e||0;return void 0!==t&&this.oscillator.amp(t,i),this.oscillator.amp().value},p5.MonoSynth.prototype.connect=function(t){var e=t||i.input;this.output.connect(e.input?e.input:e)},p5.MonoSynth.prototype.disconnect=function(){this.output&&this.output.disconnect()},p5.MonoSynth.prototype.dispose=function(){e.prototype.dispose.apply(this),this.env&&this.env.dispose(),this.oscillator&&this.oscillator.dispose()}}.call(e,n,e,t))||(t.exports=i)},function(t,e,n){"use strict";var i;void 0===(i=function(){var i=n(1);return p5.AudioVoice=function(){this.ac=i.audiocontext,this.output=this.ac.createGain(),this.connect(),i.soundArray.push(this)},p5.AudioVoice.prototype.play=function(t,e,i,n){},p5.AudioVoice.prototype.triggerAttack=function(t,e,i){},p5.AudioVoice.prototype.triggerRelease=function(t){},p5.AudioVoice.prototype.amp=function(t,e){},p5.AudioVoice.prototype.connect=function(t){var e=t||i.input;this.output.connect(e.input?e.input:e)},p5.AudioVoice.prototype.disconnect=function(){this.output.disconnect()},p5.AudioVoice.prototype.dispose=function(){this.output&&(this.output.disconnect(),delete this.output)},p5.AudioVoice}.call(e,n,e,t))||(t.exports=i)},function(t,e,i){"use strict";var n;void 0===(n=function(t){var c=i(1),h=i(14),l=i(6).noteToFreq;p5.PolySynth=function(t,e){this.audiovoices=[],this.notes={},this._newest=0,this._oldest=0,this.maxVoices=e||8,this.AudioVoice=void 0===t?p5.MonoSynth:t,this._voicesInUse=new h(0),this.output=c.audiocontext.createGain(),this.connect(),this._allocateVoices(),c.soundArray.push(this)},p5.PolySynth.prototype._allocateVoices=function(){for(var t=0;t= this.sampleLimit) {\n this.stop();\n return true;\n }\n\n var input = inputs[0];\n var output = outputs[0];\n\n for (var channel = 0; channel < output.length; ++channel) {\n var inputChannel = input[channel];\n\n if (channel === 0) {\n this.leftBuffers.push(inputChannel);\n\n if (this.numInputChannels === 1) {\n this.rightBuffers.push(inputChannel);\n }\n } else if (channel === 1 && this.numInputChannels > 1) {\n this.rightBuffers.push(inputChannel);\n }\n }\n\n this.recordedSamples += output[0].length;\n return true;\n }\n }, {\n key: "record",\n value: function record(duration) {\n if (duration) {\n this.sampleLimit = Math.round(duration * sampleRate);\n }\n\n this.recording = true;\n }\n }, {\n key: "stop",\n value: function stop() {\n this.recording = false;\n var buffers = this.getBuffers();\n var leftBuffer = buffers[0].buffer;\n var rightBuffer = buffers[1].buffer;\n this.port.postMessage({\n name: \'buffers\',\n leftBuffer: leftBuffer,\n rightBuffer: rightBuffer\n }, [leftBuffer, rightBuffer]);\n this.clear();\n }\n }, {\n key: "getBuffers",\n value: function getBuffers() {\n var buffers = [];\n buffers.push(this.mergeBuffers(this.leftBuffers));\n buffers.push(this.mergeBuffers(this.rightBuffers));\n return buffers;\n }\n }, {\n key: "mergeBuffers",\n value: function mergeBuffers(channelBuffer) {\n var result = new Float32Array(this.recordedSamples);\n var offset = 0;\n var lng = channelBuffer.length;\n\n for (var i = 0; i < lng; i++) {\n var buffer = channelBuffer[i];\n result.set(buffer, offset);\n offset += buffer.length;\n }\n\n return result;\n }\n }, {\n key: "clear",\n value: function clear() {\n this.leftBuffers = [];\n this.rightBuffers = [];\n this.recordedSamples = 0;\n this.sampleLimit = null;\n }\n }]);\n\n return RecorderProcessor;\n}(_wrapNativeSuper(AudioWorkletProcessor));\n\nregisterProcessor(processorNames.recorderProcessor, RecorderProcessor);'},function(t,e,i){"use strict";i.r(e),e.default='function _typeof(obj) { if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof(obj); }\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }\n\nfunction _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }\n\nfunction _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }\n\nfunction _possibleConstructorReturn(self, call) { if (call && (_typeof(call) === "object" || typeof call === "function")) { return call; } return _assertThisInitialized(self); }\n\nfunction _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError("this hasn\'t been initialised - super() hasn\'t been called"); } return self; }\n\nfunction _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function"); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, writable: true, configurable: true } }); if (superClass) _setPrototypeOf(subClass, superClass); }\n\nfunction _wrapNativeSuper(Class) { var _cache = typeof Map === "function" ? new Map() : undefined; _wrapNativeSuper = function _wrapNativeSuper(Class) { if (Class === null || !_isNativeFunction(Class)) return Class; if (typeof Class !== "function") { throw new TypeError("Super expression must either be null or a function"); } if (typeof _cache !== "undefined") { if (_cache.has(Class)) return _cache.get(Class); _cache.set(Class, Wrapper); } function Wrapper() { return _construct(Class, arguments, _getPrototypeOf(this).constructor); } Wrapper.prototype = Object.create(Class.prototype, { constructor: { value: Wrapper, enumerable: false, writable: true, configurable: true } }); return _setPrototypeOf(Wrapper, Class); }; return _wrapNativeSuper(Class); }\n\nfunction isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === "function") return true; try { Date.prototype.toString.call(Reflect.construct(Date, [], function () {})); return true; } catch (e) { return false; } }\n\nfunction _construct(Parent, args, Class) { if (isNativeReflectConstruct()) { _construct = Reflect.construct; } else { _construct = function _construct(Parent, args, Class) { var a = [null]; a.push.apply(a, args); var Constructor = Function.bind.apply(Parent, a); var instance = new Constructor(); if (Class) _setPrototypeOf(instance, Class.prototype); return instance; }; } return _construct.apply(null, arguments); }\n\nfunction _isNativeFunction(fn) { return Function.toString.call(fn).indexOf("[native code]") !== -1; }\n\nfunction _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); }\n\nfunction _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); }; return _getPrototypeOf(o); }\n\n// import processor name via preval.require so that it\'s available as a value at compile time\nvar processorNames = {\n "recorderProcessor": "recorder-processor",\n "soundFileProcessor": "sound-file-processor",\n "amplitudeProcessor": "amplitude-processor"\n};\n\nvar SoundFileProcessor =\n/*#__PURE__*/\nfunction (_AudioWorkletProcesso) {\n _inherits(SoundFileProcessor, _AudioWorkletProcesso);\n\n function SoundFileProcessor() {\n var _this;\n\n _classCallCheck(this, SoundFileProcessor);\n\n _this = _possibleConstructorReturn(this, _getPrototypeOf(SoundFileProcessor).call(this));\n _this.paused = false;\n\n _this.port.onmessage = function (event) {\n var data = event.data;\n\n if (data.name === \'play\') {\n _this.paused = false;\n } else if (data.name === \'pause\') {\n _this.paused = true;\n }\n };\n\n return _this;\n }\n\n _createClass(SoundFileProcessor, [{\n key: "process",\n value: function process(inputs) {\n var input = inputs[0];\n var inputChannel = input[0];\n var position = inputChannel[inputChannel.length - 1];\n\n if (!this.paused) {\n this.port.postMessage({\n name: \'position\',\n position: position\n });\n }\n\n return true;\n }\n }]);\n\n return SoundFileProcessor;\n}(_wrapNativeSuper(AudioWorkletProcessor));\n\nregisterProcessor(processorNames.soundFileProcessor, SoundFileProcessor);'},function(t,e,i){"use strict";i.r(e),e.default='function _typeof(obj) { if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof(obj); }\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }\n\nfunction _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }\n\nfunction _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }\n\nfunction _possibleConstructorReturn(self, call) { if (call && (_typeof(call) === "object" || typeof call === "function")) { return call; } return _assertThisInitialized(self); }\n\nfunction _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError("this hasn\'t been initialised - super() hasn\'t been called"); } return self; }\n\nfunction _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function"); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, writable: true, configurable: true } }); if (superClass) _setPrototypeOf(subClass, superClass); }\n\nfunction _wrapNativeSuper(Class) { var _cache = typeof Map === "function" ? new Map() : undefined; _wrapNativeSuper = function _wrapNativeSuper(Class) { if (Class === null || !_isNativeFunction(Class)) return Class; if (typeof Class !== "function") { throw new TypeError("Super expression must either be null or a function"); } if (typeof _cache !== "undefined") { if (_cache.has(Class)) return _cache.get(Class); _cache.set(Class, Wrapper); } function Wrapper() { return _construct(Class, arguments, _getPrototypeOf(this).constructor); } Wrapper.prototype = Object.create(Class.prototype, { constructor: { value: Wrapper, enumerable: false, writable: true, configurable: true } }); return _setPrototypeOf(Wrapper, Class); }; return _wrapNativeSuper(Class); }\n\nfunction isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === "function") return true; try { Date.prototype.toString.call(Reflect.construct(Date, [], function () {})); return true; } catch (e) { return false; } }\n\nfunction _construct(Parent, args, Class) { if (isNativeReflectConstruct()) { _construct = Reflect.construct; } else { _construct = function _construct(Parent, args, Class) { var a = [null]; a.push.apply(a, args); var Constructor = Function.bind.apply(Parent, a); var instance = new Constructor(); if (Class) _setPrototypeOf(instance, Class.prototype); return instance; }; } return _construct.apply(null, arguments); }\n\nfunction _isNativeFunction(fn) { return Function.toString.call(fn).indexOf("[native code]") !== -1; }\n\nfunction _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); }\n\nfunction _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); }; return _getPrototypeOf(o); }\n\n// import processor name via preval.require so that it\'s available as a value at compile time\nvar processorNames = {\n "recorderProcessor": "recorder-processor",\n "soundFileProcessor": "sound-file-processor",\n "amplitudeProcessor": "amplitude-processor"\n};\n\nvar AmplitudeProcessor =\n/*#__PURE__*/\nfunction (_AudioWorkletProcesso) {\n _inherits(AmplitudeProcessor, _AudioWorkletProcesso);\n\n function AmplitudeProcessor(options) {\n var _this;\n\n _classCallCheck(this, AmplitudeProcessor);\n\n _this = _possibleConstructorReturn(this, _getPrototypeOf(AmplitudeProcessor).call(this));\n var processorOptions = options.processorOptions || {};\n _this.smoothing = processorOptions.smoothing || 0;\n _this.normalize = processorOptions.normalize || false;\n _this.stereoVol = [0, 0];\n _this.stereoVolNorm = [0, 0];\n _this.volMax = 0.001;\n\n _this.port.onmessage = function (event) {\n var data = event.data;\n\n if (data.name === \'toggleNormalize\') {\n _this.normalize = data.normalize;\n } else if (data.name === \'smoothing\') {\n _this.smoothing = Math.max(0, Math.min(1, data.smoothing));\n }\n };\n\n return _this;\n } // TO DO make this stereo / dependent on # of audio channels\n\n\n _createClass(AmplitudeProcessor, [{\n key: "process",\n value: function process(inputs, outputs) {\n var input = inputs[0];\n var output = outputs[0];\n var smoothing = this.smoothing;\n\n for (var channel = 0; channel < input.length; ++channel) {\n var inputBuffer = input[channel];\n var bufLength = inputBuffer.length;\n var sum = 0;\n\n for (var i = 0; i < bufLength; i++) {\n var x = inputBuffer[i];\n\n if (this.normalize) {\n sum += Math.max(Math.min(x / this.volMax, 1), -1) * Math.max(Math.min(x / this.volMax, 1), -1);\n } else {\n sum += x * x;\n }\n } // ... then take the square root of the sum.\n\n\n var rms = Math.sqrt(sum / bufLength);\n this.stereoVol[channel] = Math.max(rms, this.stereoVol[channel] * smoothing);\n this.volMax = Math.max(this.stereoVol[channel], this.volMax);\n } // calculate stero normalized volume and add volume from all channels together\n\n\n var volSum = 0;\n\n for (var index = 0; index < this.stereoVol.length; index++) {\n this.stereoVolNorm[index] = Math.max(Math.min(this.stereoVol[index] / this.volMax, 1), 0);\n volSum += this.stereoVol[index];\n } // volume is average of channels\n\n\n var volume = volSum / this.stereoVol.length; // normalized value\n\n var volNorm = Math.max(Math.min(volume / this.volMax, 1), 0);\n this.port.postMessage({\n name: \'amplitude\',\n volume: volume,\n volNorm: volNorm,\n stereoVol: this.stereoVol,\n stereoVolNorm: this.stereoVolNorm\n }); // pass input through to output\n\n for (var _channel = 0; _channel < output.length; ++_channel) {\n output[_channel].set(input[_channel]);\n }\n\n return true;\n }\n }]);\n\n return AmplitudeProcessor;\n}(_wrapNativeSuper(AudioWorkletProcessor));\n\nregisterProcessor(processorNames.amplitudeProcessor, AmplitudeProcessor);'},function(t,e,i){"use strict";var n;function o(t){return(o="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t})(t)}void 0===(n=function(t){var a=i(1).audiocontext;void 0!==a.createStereoPanner?(p5.Panner=function(t,e){this.stereoPanner=this.input=a.createStereoPanner(),t.connect(this.stereoPanner),this.stereoPanner.connect(e)},p5.Panner.prototype.pan=function(t,e){var i=e||0,n=a.currentTime+i;this.stereoPanner.pan.linearRampToValueAtTime(t,n)},p5.Panner.prototype.inputChannels=function(){},p5.Panner.prototype.connect=function(t){this.stereoPanner.connect(t)},p5.Panner.prototype.disconnect=function(){this.stereoPanner&&this.stereoPanner.disconnect()}):(p5.Panner=function(t,e,i){this.input=a.createGain(),t.connect(this.input),this.left=a.createGain(),this.right=a.createGain(),this.left.channelInterpretation="discrete",this.right.channelInterpretation="discrete",1this.buffer.duration)throw"jump time out of range";if(e>this.buffer.duration-t)throw"end time out of range";var i=t||0,n=e||void 0;this.isPlaying()&&this.stop(0),this.play(0,this.playbackRate,this.output.gain.value,i,n)},p5.SoundFile.prototype.channels=function(){return this.buffer.numberOfChannels},p5.SoundFile.prototype.sampleRate=function(){return this.buffer.sampleRate},p5.SoundFile.prototype.frames=function(){return this.buffer.length},p5.SoundFile.prototype.getPeaks=function(t){if(!this.buffer)throw"Cannot load peaks yet, buffer is not loaded";if(t=t||5*window.width,this.buffer){for(var e=this.buffer,i=e.length/t,n=~~(i/10)||1,o=e.numberOfChannels,r=new Float32Array(Math.round(t)),s=0;sr[u])&&(r[u]=h)}return r}},p5.SoundFile.prototype.reverseBuffer=function(){if(!this.buffer)throw"SoundFile is not done loading";var t=this._lastPos/p.sampleRate,e=this.getVolume();this.setVolume(0,.001);for(var i=this.buffer.numberOfChannels,n=0;ne){var r=t[o],s=new c(r,o);i[o]=s,o+=6e3}o++}return i}function m(t){if(isFinite(t)&&0!==t){for(;t<90;)t*=2;for(;180t[r].hi&&r++,o[r]=void 0!==o[r]?(o[r]+i[s])/2:i[s]}return o},p5.FFT.prototype.getOctaveBands=function(t,e){t=t||3;var i=[],n={lo:(e=e||15.625)/Math.pow(2,1/(2*t)),ctr:e,hi:e*Math.pow(2,1/(2*t))};i.push(n);for(var o=c.audiocontext.sampleRate/2;n.hi=this._maxDelay)throw new Error("Delay Time exceeds maximum delay time of "+this._maxDelay+" second.");t.connect(this.input),this.leftDelay.delayTime.setValueAtTime(r,this.ac.currentTime),this.rightDelay.delayTime.setValueAtTime(r,this.ac.currentTime),this._leftGain.gain.value=o,this._rightGain.gain.value=o,n&&(this._leftFilter.freq(n),this._rightFilter.freq(n))},p5.Delay.prototype.delayTime=function(t){"number"!=typeof t?(t.connect(this.leftDelay.delayTime),t.connect(this.rightDelay.delayTime)):(this.leftDelay.delayTime.cancelScheduledValues(this.ac.currentTime),this.rightDelay.delayTime.cancelScheduledValues(this.ac.currentTime),this.leftDelay.delayTime.linearRampToValueAtTime(t,this.ac.currentTime),this.rightDelay.delayTime.linearRampToValueAtTime(t,this.ac.currentTime))},p5.Delay.prototype.feedback=function(t){if(t&&"number"!=typeof t)t.connect(this._leftGain.gain),t.connect(this._rightGain.gain);else{if(1<=t)throw new Error("Feedback value will force a positive feedback loop.");"number"==typeof t&&(this._leftGain.gain.value=t,this._rightGain.gain.value=t)}return this._leftGain.gain.value},p5.Delay.prototype.filter=function(t,e){this._leftFilter.set(t,e),this._rightFilter.set(t,e)},p5.Delay.prototype.setType=function(t){switch(1===t&&(t="pingPong"),this._split.disconnect(),this._leftFilter.disconnect(),this._rightFilter.disconnect(),this._split.connect(this.leftDelay,0),this._split.connect(this.rightDelay,1),t){case"pingPong":this._rightFilter.setType(this._leftFilter.biquad.type),this._leftFilter.output.connect(this._merge,0,0),this._rightFilter.output.connect(this._merge,0,1),this._leftFilter.output.connect(this.rightDelay),this._rightFilter.output.connect(this.leftDelay);break;default:this._leftFilter.output.connect(this._merge,0,0),this._rightFilter.output.connect(this._merge,0,1),this._leftFilter.output.connect(this.leftDelay),this._rightFilter.output.connect(this.rightDelay)}},p5.Delay.prototype.dispose=function(){i.prototype.dispose.apply(this),this._split.disconnect(),this._leftFilter.dispose(),this._rightFilter.dispose(),this._merge.disconnect(),this._leftGain.disconnect(),this._rightGain.disconnect(),this.leftDelay.disconnect(),this.rightDelay.disconnect(),this._split=void 0,this._leftFilter=void 0,this._rightFilter=void 0,this._merge=void 0,this._leftGain=void 0,this._rightGain=void 0,this.leftDelay=void 0,this.rightDelay=void 0}}.call(e,n,e,t))||(t.exports=i)},function(t,e,i){"use strict";var n;void 0===(n=function(t){var p=i(10),e=i(4);p5.Reverb=function(){e.call(this),this._initConvolverNode(),this.input.gain.value=.5,this._seconds=3,this._decay=2,this._reverse=!1,this._buildImpulse()},p5.Reverb.prototype=Object.create(e.prototype),p5.Reverb.prototype._initConvolverNode=function(){this.convolverNode=this.ac.createConvolver(),this.input.connect(this.convolverNode),this.convolverNode.connect(this.wet)},p5.Reverb.prototype._teardownConvolverNode=function(){this.convolverNode&&(this.convolverNode.disconnect(),delete this.convolverNode)},p5.Reverb.prototype._setBuffer=function(t){this._teardownConvolverNode(),this._initConvolverNode(),this.convolverNode.buffer=t},p5.Reverb.prototype.process=function(t,e,i,n){t.connect(this.input);var o=!1;e&&(this._seconds=e,o=!0),i&&(this._decay=i),n&&(this._reverse=n),o&&this._buildImpulse()},p5.Reverb.prototype.set=function(t,e,i){var n=!1;t&&(this._seconds=t,n=!0),e&&(this._decay=e),i&&(this._reverse=i),n&&this._buildImpulse()},p5.Reverb.prototype._buildImpulse=function(){var t,e,i=this.ac.sampleRate,n=i*this._seconds,o=this._decay,r=this.ac.createBuffer(2,n,i),s=r.getChannelData(0),a=r.getChannelData(1);for(e=0;e=t.parts.length?(t.scoreStep=0,t.onended()):(t.scoreStep=0,t.parts[t.currentPart-1].stop(),t.parts[t.currentPart].start())}p5.prototype.setBPM=function(t,e){for(var i in o=t,n.parts)n.parts[i]&&n.parts[i].setBPM(t,e)},p5.Phrase=function(t,e,i){this.phraseStep=0,this.name=t,this.callback=e,this.sequence=i},p5.Part=function(t,e){this.length=t||0,this.partStep=0,this.phrases=[],this.isPlaying=!1,this.noLoop(),this.tatums=e||.0625,this.metro=new p5.Metro,this.metro._init(),this.metro.beatLength(this.tatums),this.metro.setBPM(o),n.parts.push(this),this.callback=function(){}},p5.Part.prototype.setBPM=function(t,e){this.metro.setBPM(t,e)},p5.Part.prototype.getBPM=function(){return this.metro.getBPM()},p5.Part.prototype.start=function(t){if(!this.isPlaying){this.isPlaying=!0,this.metro.resetSync(this);var e=t||0;this.metro.start(e)}},p5.Part.prototype.loop=function(t){this.looping=!0,this.onended=function(){this.partStep=0};var e=t||0;this.start(e)},p5.Part.prototype.noLoop=function(){this.looping=!1,this.onended=function(){this.stop()}},p5.Part.prototype.stop=function(t){this.partStep=0,this.pause(t)},p5.Part.prototype.pause=function(t){this.isPlaying=!1;var e=t||0;this.metro.stop(e)},p5.Part.prototype.addPhrase=function(t,e,i){var n;if(3===arguments.length)n=new p5.Phrase(t,e,i);else{if(!(t instanceof p5.Phrase))throw"invalid input. addPhrase accepts name, callback, array or a p5.Phrase";n=t}this.phrases.push(n),n.sequence.length>this.length&&(this.length=n.sequence.length)},p5.Part.prototype.removePhrase=function(t){for(var e in this.phrases)this.phrases[e].name===t&&this.phrases.splice(e,1)},p5.Part.prototype.getPhrase=function(t){for(var e in this.phrases)if(this.phrases[e].name===t)return this.phrases[e]},p5.Part.prototype.replaceSequence=function(t,e){for(var i in this.phrases)this.phrases[i].name===t&&(this.phrases[i].sequence=e)},p5.Part.prototype.incrementStep=function(t){this.partStepthis.cutoff&&e>this.threshold&&0t)this.cancelScheduledValues(t),this.linearRampToValueAtTime(e,t);else{var n=this._searchAfter(t);n&&(this.cancelScheduledValues(t),n.type===u.TimelineSignal.Type.Linear?this.linearRampToValueAtTime(e,t):n.type===u.TimelineSignal.Type.Exponential&&this.exponentialRampToValueAtTime(e,t)),this.setValueAtTime(e,t)}return this},u.TimelineSignal.prototype.linearRampToValueBetween=function(t,e,i){return this.setRampPoint(e),this.linearRampToValueAtTime(t,i),this},u.TimelineSignal.prototype.exponentialRampToValueBetween=function(t,e,i){return this.setRampPoint(e),this.exponentialRampToValueAtTime(t,i),this},u.TimelineSignal.prototype._searchBefore=function(t){return this._events.get(t)},u.TimelineSignal.prototype._searchAfter=function(t){return this._events.getAfter(t)},u.TimelineSignal.prototype.getValueAtTime=function(t){t=this.toSeconds(t);var e=this._searchAfter(t),i=this._searchBefore(t),n=this._initial;if(null===i)n=this._initial;else if(i.type===u.TimelineSignal.Type.Target){var o,r=this._events.getBefore(i.time);o=null===r?this._initial:r.value,n=this._exponentialApproach(i.time,o,i.value,i.constant,t)}else n=i.type===u.TimelineSignal.Type.Curve?this._curveInterpolate(i.time,i.value,i.duration,t):null===e?i.value:e.type===u.TimelineSignal.Type.Linear?this._linearInterpolate(i.time,i.value,e.time,e.value,t):e.type===u.TimelineSignal.Type.Exponential?this._exponentialInterpolate(i.time,i.value,e.time,e.value,t):i.value;return n},u.TimelineSignal.prototype.connect=u.SignalBase.prototype.connect,u.TimelineSignal.prototype._exponentialApproach=function(t,e,i,n,o){return i+(e-i)*Math.exp(-(o-t)/n)},u.TimelineSignal.prototype._linearInterpolate=function(t,e,i,n,o){return e+(o-t)/(i-t)*(n-e)},u.TimelineSignal.prototype._exponentialInterpolate=function(t,e,i,n,o){return(e=Math.max(this._minOutput,e))*Math.pow(n/e,(o-t)/(i-t))},u.TimelineSignal.prototype._curveInterpolate=function(t,e,i,n){var o=e.length;if(t+i<=n)return e[o-1];if(n<=t)return e[0];var r=(n-t)/i,s=Math.floor((o-1)*r),a=Math.ceil((o-1)*r),u=e[s],p=e[a];return a===s?u:this._linearInterpolate(s,u,a,p,r*(o-1))},u.TimelineSignal.prototype.dispose=function(){u.Signal.prototype.dispose.call(this),u.Param.prototype.dispose.call(this),this._events.dispose(),this._events=null},u.TimelineSignal}.apply(e,n))||(t.exports=o)},function(t,e,i){"use strict";var n;void 0===(n=function(t){var e=i(4);return p5.Filter=function(t){e.call(this),this.biquad=this.ac.createBiquadFilter(),this.input.connect(this.biquad),this.biquad.connect(this.wet),t&&this.setType(t),this._on=!0,this._untoggledType=this.biquad.type},p5.Filter.prototype=Object.create(e.prototype),p5.Filter.prototype.process=function(t,e,i,n){t.connect(this.input),this.set(e,i,n)},p5.Filter.prototype.set=function(t,e,i){t&&this.freq(t,i),e&&this.res(e,i)},p5.Filter.prototype.freq=function(t,e){var i=e||0;return t<=0&&(t=1),"number"==typeof t?(this.biquad.frequency.cancelScheduledValues(this.ac.currentTime+.01+i),this.biquad.frequency.exponentialRampToValueAtTime(t,this.ac.currentTime+.02+i)):t&&t.connect(this.biquad.frequency),this.biquad.frequency.value},p5.Filter.prototype.res=function(t,e){var i=e||0;return"number"==typeof t?(this.biquad.Q.value=t,this.biquad.Q.cancelScheduledValues(this.ac.currentTime+.01+i),this.biquad.Q.linearRampToValueAtTime(t,this.ac.currentTime+.02+i)):t&&t.connect(this.biquad.Q),this.biquad.Q.value},p5.Filter.prototype.gain=function(t,e){var i=e||0;return"number"==typeof t?(this.biquad.gain.value=t,this.biquad.gain.cancelScheduledValues(this.ac.currentTime+.01+i),this.biquad.gain.linearRampToValueAtTime(t,this.ac.currentTime+.02+i)):t&&t.connect(this.biquad.gain),this.biquad.gain.value},p5.Filter.prototype.toggle=function(){return this._on=!this._on,!0===this._on?this.biquad.type=this._untoggledType:!1===this._on&&(this.biquad.type="allpass"),this._on},p5.Filter.prototype.setType=function(t){this.biquad.type=t,this._untoggledType=this.biquad.type},p5.Filter.prototype.dispose=function(){e.prototype.dispose.apply(this),this.biquad&&(this.biquad.disconnect(),delete this.biquad)},p5.LowPass=function(){p5.Filter.call(this,"lowpass")},p5.LowPass.prototype=Object.create(p5.Filter.prototype),p5.HighPass=function(){p5.Filter.call(this,"highpass")},p5.HighPass.prototype=Object.create(p5.Filter.prototype),p5.BandPass=function(){p5.Filter.call(this,"bandpass")},p5.BandPass.prototype=Object.create(p5.Filter.prototype),p5.Filter}.call(e,i,e,t))||(t.exports=n)},function(t,e,i){var n,o;n=[i(0),i(7),i(25),i(2),i(9)],void 0===(o=function(e){"use strict";return e.Subtract=function(t){this.createInsOuts(2,0),this._sum=this.input[0]=this.output=new e.Gain,this._neg=new e.Negate,this._param=this.input[1]=new e.Signal(t),this._param.chain(this._neg,this._sum)},e.extend(e.Subtract,e.Signal),e.Subtract.prototype.dispose=function(){return e.prototype.dispose.call(this),this._neg.dispose(),this._neg=null,this._sum.disconnect(),this._sum=null,this._param.dispose(),this._param=null,this},e.Subtract}.apply(e,n))||(t.exports=o)},function(n,o,r){"use strict";(function(t){var e,i;t.TONE_SILENCE_VERSION_LOGGING=!0,e=[r(35),r(11),r(0)],void 0===(i=function(n,t,e){var o=new window.AudioContext;return e.context.dispose(),e.setContext(o),p5.prototype.getAudioContext=function(){return o},p5.prototype.userStartAudio=function(t,e){var i=t;return t instanceof p5.Element?i=t.elt:t instanceof Array&&t[0]instanceof p5.Element&&(i=t.map(function(t){return t.elt})),n(o,i,e)},o}.apply(o,e))||(n.exports=i)}).call(this,r(34))},function(t,e,i){var n,o;n=[i(0)],void 0===(o=function(s){"use strict";return s.Emitter=function(){this._events={}},s.extend(s.Emitter),s.Emitter.prototype.on=function(t,e){for(var i=t.split(/\W+/),n=0;nthis.memory){var i=this.length-this.memory;this._timeline.splice(0,i)}return this},e.Timeline.prototype.remove=function(t){if(this._iterating)this._toRemove.push(t);else{var e=this._timeline.indexOf(t);-1!==e&&this._timeline.splice(e,1)}return this},e.Timeline.prototype.get=function(t){var e=this._search(t);return-1!==e?this._timeline[e]:null},e.Timeline.prototype.peek=function(){return this._timeline[0]},e.Timeline.prototype.shift=function(){return this._timeline.shift()},e.Timeline.prototype.getAfter=function(t){var e=this._search(t);return e+1=t&&(this._timeline=[]);return this},e.Timeline.prototype.cancelBefore=function(t){if(this._timeline.length){var e=this._search(t);0<=e&&(this._timeline=this._timeline.slice(e+1))}return this},e.Timeline.prototype._search=function(t){var e=0,i=this._timeline.length,n=i;if(0t)return o;r.time>t?n=o:r.time=t;)i--;return this._iterate(e,i+1),this},e.Timeline.prototype.forEachAtTime=function(e,i){var t=this._search(e);return-1!==t&&this._iterate(function(t){t.time===e&&i(t)},0,t),this},e.Timeline.prototype.dispose=function(){e.prototype.dispose.call(this),this._timeline=null,this._toRemove=null},e.Timeline}.apply(e,n))||(t.exports=o)},function(t,e,i){var n,o;n=[i(0),i(3),i(2)],void 0===(o=function(t){"use strict";return t.Negate=function(){this._multiply=this.input=this.output=new t.Multiply(-1)},t.extend(t.Negate,t.SignalBase),t.Negate.prototype.dispose=function(){return t.prototype.dispose.call(this),this._multiply.dispose(),this._multiply=null,this},t.Negate}.apply(e,n))||(t.exports=o)},function(t,e,i){var n,o;n=[i(0),i(2),i(3),i(5)],void 0===(o=function(t){"use strict";return t.GreaterThanZero=function(){this._thresh=this.output=new t.WaveShaper(function(t){return t<=0?0:1},127),this._scale=this.input=new t.Multiply(1e4),this._scale.connect(this._thresh)},t.extend(t.GreaterThanZero,t.SignalBase),t.GreaterThanZero.prototype.dispose=function(){return t.prototype.dispose.call(this),this._scale.dispose(),this._scale=null,this._thresh.dispose(),this._thresh=null,this},t.GreaterThanZero}.apply(e,n))||(t.exports=o)},function(t,e,i){var n,o;n=[i(0),i(14),i(66),i(18),i(11)],void 0===(o=function(o){"use strict";return o.Clock=function(){o.Emitter.call(this);var t=this.optionsObject(arguments,["callback","frequency"],o.Clock.defaults);this.callback=t.callback,this._nextTick=0,this._lastState=o.State.Stopped,this.frequency=new o.TimelineSignal(t.frequency,o.Type.Frequency),this._readOnly("frequency"),this.ticks=0,this._state=new o.TimelineState(o.State.Stopped),this._boundLoop=this._loop.bind(this),this.context.on("tick",this._boundLoop)},o.extend(o.Clock,o.Emitter),o.Clock.defaults={callback:o.noOp,frequency:1,lookAhead:"auto"},Object.defineProperty(o.Clock.prototype,"state",{get:function(){return this._state.getValueAtTime(this.now())}}),o.Clock.prototype.start=function(t,e){return t=this.toSeconds(t),this._state.getValueAtTime(t)!==o.State.Started&&this._state.add({state:o.State.Started,time:t,offset:e}),this},o.Clock.prototype.stop=function(t){return t=this.toSeconds(t),this._state.cancel(t),this._state.setStateAtTime(o.State.Stopped,t),this},o.Clock.prototype.pause=function(t){return t=this.toSeconds(t),this._state.getValueAtTime(t)===o.State.Started&&this._state.setStateAtTime(o.State.Paused,t),this},o.Clock.prototype._loop=function(){for(var t=this.now()+this.context.lookAhead+this.context.updateInterval+2*this.context.lag;t>this._nextTick&&this._state;){var e=this._state.getValueAtTime(this._nextTick);if(e!==this._lastState){this._lastState=e;var i=this._state.get(this._nextTick);e===o.State.Started?(this._nextTick=i.time,this.isUndef(i.offset)||(this.ticks=i.offset),this.emit("start",i.time,this.ticks)):e===o.State.Stopped?(this.ticks=0,this.emit("stop",i.time)):e===o.State.Paused&&this.emit("pause",i.time)}var n=this._nextTick;this.frequency&&(this._nextTick+=1/this.frequency.getValueAtTime(this._nextTick),e===o.State.Started&&(this.callback(n),this.ticks++))}},o.Clock.prototype.getStateAtTime=function(t){return t=this.toSeconds(t),this._state.getValueAtTime(t)},o.Clock.prototype.dispose=function(){o.Emitter.prototype.dispose.call(this),this.context.off("tick",this._boundLoop),this._writable("frequency"),this.frequency.dispose(),this.frequency=null,this._boundLoop=null,this._nextTick=1/0,this.callback=null,this._state.dispose(),this._state=null},o.Clock}.apply(e,n))||(t.exports=o)},function(t,e,n){"use strict";var i;void 0===(i=function(t){var i=n(1),e=n(29),r=n(6).noteToFreq;p5.MonoSynth=function(){e.call(this),this.oscillator=new p5.Oscillator,this.env=new p5.Envelope,this.env.setRange(1,0),this.env.setExp(!0),this.setADSR(.02,.25,.05,.35),this.oscillator.disconnect(),this.oscillator.connect(this.output),this.env.disconnect(),this.env.setInput(this.output.gain),this.oscillator.output.gain.value=1,this.oscillator.start(),this.connect(),i.soundArray.push(this)},p5.MonoSynth.prototype=Object.create(p5.AudioVoice.prototype),p5.MonoSynth.prototype.play=function(t,e,i,n){this.triggerAttack(t,e,~~i),this.triggerRelease(~~i+(n||.15))},p5.MonoSynth.prototype.triggerAttack=function(t,e,i){i=~~i;var n=r(t),o=e||.1;this.oscillator.freq(n,0,i),this.env.ramp(this.output.gain,i,o)},p5.MonoSynth.prototype.triggerRelease=function(t){t=t||0;this.env.ramp(this.output.gain,t,0)},p5.MonoSynth.prototype.setADSR=function(t,e,i,n){this.env.setADSR(t,e,i,n)},Object.defineProperties(p5.MonoSynth.prototype,{attack:{get:function(){return this.env.aTime},set:function(t){this.env.setADSR(t,this.env.dTime,this.env.sPercent,this.env.rTime)}},decay:{get:function(){return this.env.dTime},set:function(t){this.env.setADSR(this.env.aTime,t,this.env.sPercent,this.env.rTime)}},sustain:{get:function(){return this.env.sPercent},set:function(t){this.env.setADSR(this.env.aTime,this.env.dTime,t,this.env.rTime)}},release:{get:function(){return this.env.rTime},set:function(t){this.env.setADSR(this.env.aTime,this.env.dTime,this.env.sPercent,t)}}}),p5.MonoSynth.prototype.amp=function(t,e){var i=e||0;return void 0!==t&&this.oscillator.amp(t,i),this.oscillator.amp().value},p5.MonoSynth.prototype.connect=function(t){var e=t||i.input;this.output.connect(e.input?e.input:e)},p5.MonoSynth.prototype.disconnect=function(){this.output&&this.output.disconnect()},p5.MonoSynth.prototype.dispose=function(){e.prototype.dispose.apply(this),this.env&&this.env.dispose(),this.oscillator&&this.oscillator.dispose()}}.call(e,n,e,t))||(t.exports=i)},function(t,e,n){"use strict";var i;void 0===(i=function(){var i=n(1);return p5.AudioVoice=function(){this.ac=i.audiocontext,this.output=this.ac.createGain(),this.connect(),i.soundArray.push(this)},p5.AudioVoice.prototype.play=function(t,e,i,n){},p5.AudioVoice.prototype.triggerAttack=function(t,e,i){},p5.AudioVoice.prototype.triggerRelease=function(t){},p5.AudioVoice.prototype.amp=function(t,e){},p5.AudioVoice.prototype.connect=function(t){var e=t||i.input;this.output.connect(e.input?e.input:e)},p5.AudioVoice.prototype.disconnect=function(){this.output.disconnect()},p5.AudioVoice.prototype.dispose=function(){this.output&&(this.output.disconnect(),delete this.output)},p5.AudioVoice}.call(e,n,e,t))||(t.exports=i)},function(t,e,i){"use strict";var n;void 0===(n=function(t){var c=i(1),h=i(14),l=i(6).noteToFreq;p5.PolySynth=function(t,e){this.audiovoices=[],this.notes={},this._newest=0,this._oldest=0,this.maxVoices=e||8,this.AudioVoice=void 0===t?p5.MonoSynth:t,this._voicesInUse=new h(0),this.output=c.audiocontext.createGain(),this.connect(),this._allocateVoices(),c.soundArray.push(this)},p5.PolySynth.prototype._allocateVoices=function(){for(var t=0;t= this.sampleLimit) {\n this.stop();\n return true;\n }\n\n var input = inputs[0];\n var output = outputs[0];\n\n for (var channel = 0; channel < output.length; ++channel) {\n var inputChannel = input[channel];\n\n if (channel === 0) {\n this.leftBuffers.push(inputChannel);\n\n if (this.numInputChannels === 1) {\n this.rightBuffers.push(inputChannel);\n }\n } else if (channel === 1 && this.numInputChannels > 1) {\n this.rightBuffers.push(inputChannel);\n }\n }\n\n this.recordedSamples += output[0].length;\n return true;\n }\n }, {\n key: "record",\n value: function record(duration) {\n if (duration) {\n this.sampleLimit = Math.round(duration * sampleRate);\n }\n\n this.recording = true;\n }\n }, {\n key: "stop",\n value: function stop() {\n this.recording = false;\n var buffers = this.getBuffers();\n var leftBuffer = buffers[0].buffer;\n var rightBuffer = buffers[1].buffer;\n this.port.postMessage({\n name: \'buffers\',\n leftBuffer: leftBuffer,\n rightBuffer: rightBuffer\n }, [leftBuffer, rightBuffer]);\n this.clear();\n }\n }, {\n key: "getBuffers",\n value: function getBuffers() {\n var buffers = [];\n buffers.push(this.mergeBuffers(this.leftBuffers));\n buffers.push(this.mergeBuffers(this.rightBuffers));\n return buffers;\n }\n }, {\n key: "mergeBuffers",\n value: function mergeBuffers(channelBuffer) {\n var result = new Float32Array(this.recordedSamples);\n var offset = 0;\n var lng = channelBuffer.length;\n\n for (var i = 0; i < lng; i++) {\n var buffer = channelBuffer[i];\n result.set(buffer, offset);\n offset += buffer.length;\n }\n\n return result;\n }\n }, {\n key: "clear",\n value: function clear() {\n this.leftBuffers = [];\n this.rightBuffers = [];\n this.recordedSamples = 0;\n this.sampleLimit = null;\n }\n }]);\n\n return RecorderProcessor;\n}(_wrapNativeSuper(AudioWorkletProcessor));\n\nregisterProcessor(processorNames.recorderProcessor, RecorderProcessor);'},function(t,e,i){"use strict";i.r(e),e.default='function _typeof(obj) { if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof(obj); }\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }\n\nfunction _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }\n\nfunction _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }\n\nfunction _possibleConstructorReturn(self, call) { if (call && (_typeof(call) === "object" || typeof call === "function")) { return call; } return _assertThisInitialized(self); }\n\nfunction _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError("this hasn\'t been initialised - super() hasn\'t been called"); } return self; }\n\nfunction _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function"); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, writable: true, configurable: true } }); if (superClass) _setPrototypeOf(subClass, superClass); }\n\nfunction _wrapNativeSuper(Class) { var _cache = typeof Map === "function" ? new Map() : undefined; _wrapNativeSuper = function _wrapNativeSuper(Class) { if (Class === null || !_isNativeFunction(Class)) return Class; if (typeof Class !== "function") { throw new TypeError("Super expression must either be null or a function"); } if (typeof _cache !== "undefined") { if (_cache.has(Class)) return _cache.get(Class); _cache.set(Class, Wrapper); } function Wrapper() { return _construct(Class, arguments, _getPrototypeOf(this).constructor); } Wrapper.prototype = Object.create(Class.prototype, { constructor: { value: Wrapper, enumerable: false, writable: true, configurable: true } }); return _setPrototypeOf(Wrapper, Class); }; return _wrapNativeSuper(Class); }\n\nfunction isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === "function") return true; try { Date.prototype.toString.call(Reflect.construct(Date, [], function () {})); return true; } catch (e) { return false; } }\n\nfunction _construct(Parent, args, Class) { if (isNativeReflectConstruct()) { _construct = Reflect.construct; } else { _construct = function _construct(Parent, args, Class) { var a = [null]; a.push.apply(a, args); var Constructor = Function.bind.apply(Parent, a); var instance = new Constructor(); if (Class) _setPrototypeOf(instance, Class.prototype); return instance; }; } return _construct.apply(null, arguments); }\n\nfunction _isNativeFunction(fn) { return Function.toString.call(fn).indexOf("[native code]") !== -1; }\n\nfunction _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); }\n\nfunction _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); }; return _getPrototypeOf(o); }\n\n// import processor name via preval.require so that it\'s available as a value at compile time\nvar processorNames = {\n "recorderProcessor": "recorder-processor",\n "soundFileProcessor": "sound-file-processor",\n "amplitudeProcessor": "amplitude-processor"\n};\n\nvar SoundFileProcessor =\n/*#__PURE__*/\nfunction (_AudioWorkletProcesso) {\n _inherits(SoundFileProcessor, _AudioWorkletProcesso);\n\n function SoundFileProcessor() {\n _classCallCheck(this, SoundFileProcessor);\n\n return _possibleConstructorReturn(this, _getPrototypeOf(SoundFileProcessor).apply(this, arguments));\n }\n\n _createClass(SoundFileProcessor, [{\n key: "process",\n value: function process(inputs) {\n var input = inputs[0];\n var inputChannel = input[0];\n var position = inputChannel[inputChannel.length - 1] || 0;\n this.port.postMessage({\n name: \'position\',\n position: position\n });\n return true;\n }\n }]);\n\n return SoundFileProcessor;\n}(_wrapNativeSuper(AudioWorkletProcessor));\n\nregisterProcessor(processorNames.soundFileProcessor, SoundFileProcessor);'},function(t,e,i){"use strict";i.r(e),e.default='function _typeof(obj) { if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof(obj); }\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }\n\nfunction _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }\n\nfunction _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }\n\nfunction _possibleConstructorReturn(self, call) { if (call && (_typeof(call) === "object" || typeof call === "function")) { return call; } return _assertThisInitialized(self); }\n\nfunction _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError("this hasn\'t been initialised - super() hasn\'t been called"); } return self; }\n\nfunction _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function"); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, writable: true, configurable: true } }); if (superClass) _setPrototypeOf(subClass, superClass); }\n\nfunction _wrapNativeSuper(Class) { var _cache = typeof Map === "function" ? new Map() : undefined; _wrapNativeSuper = function _wrapNativeSuper(Class) { if (Class === null || !_isNativeFunction(Class)) return Class; if (typeof Class !== "function") { throw new TypeError("Super expression must either be null or a function"); } if (typeof _cache !== "undefined") { if (_cache.has(Class)) return _cache.get(Class); _cache.set(Class, Wrapper); } function Wrapper() { return _construct(Class, arguments, _getPrototypeOf(this).constructor); } Wrapper.prototype = Object.create(Class.prototype, { constructor: { value: Wrapper, enumerable: false, writable: true, configurable: true } }); return _setPrototypeOf(Wrapper, Class); }; return _wrapNativeSuper(Class); }\n\nfunction isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === "function") return true; try { Date.prototype.toString.call(Reflect.construct(Date, [], function () {})); return true; } catch (e) { return false; } }\n\nfunction _construct(Parent, args, Class) { if (isNativeReflectConstruct()) { _construct = Reflect.construct; } else { _construct = function _construct(Parent, args, Class) { var a = [null]; a.push.apply(a, args); var Constructor = Function.bind.apply(Parent, a); var instance = new Constructor(); if (Class) _setPrototypeOf(instance, Class.prototype); return instance; }; } return _construct.apply(null, arguments); }\n\nfunction _isNativeFunction(fn) { return Function.toString.call(fn).indexOf("[native code]") !== -1; }\n\nfunction _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); }\n\nfunction _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); }; return _getPrototypeOf(o); }\n\n// import processor name via preval.require so that it\'s available as a value at compile time\nvar processorNames = {\n "recorderProcessor": "recorder-processor",\n "soundFileProcessor": "sound-file-processor",\n "amplitudeProcessor": "amplitude-processor"\n};\n\nvar AmplitudeProcessor =\n/*#__PURE__*/\nfunction (_AudioWorkletProcesso) {\n _inherits(AmplitudeProcessor, _AudioWorkletProcesso);\n\n function AmplitudeProcessor(options) {\n var _this;\n\n _classCallCheck(this, AmplitudeProcessor);\n\n _this = _possibleConstructorReturn(this, _getPrototypeOf(AmplitudeProcessor).call(this));\n var processorOptions = options.processorOptions || {};\n _this.smoothing = processorOptions.smoothing || 0;\n _this.normalize = processorOptions.normalize || false;\n _this.stereoVol = [0, 0];\n _this.stereoVolNorm = [0, 0];\n _this.volMax = 0.001;\n\n _this.port.onmessage = function (event) {\n var data = event.data;\n\n if (data.name === \'toggleNormalize\') {\n _this.normalize = data.normalize;\n } else if (data.name === \'smoothing\') {\n _this.smoothing = Math.max(0, Math.min(1, data.smoothing));\n }\n };\n\n return _this;\n } // TO DO make this stereo / dependent on # of audio channels\n\n\n _createClass(AmplitudeProcessor, [{\n key: "process",\n value: function process(inputs, outputs) {\n var input = inputs[0];\n var output = outputs[0];\n var smoothing = this.smoothing;\n\n for (var channel = 0; channel < input.length; ++channel) {\n var inputBuffer = input[channel];\n var bufLength = inputBuffer.length;\n var sum = 0;\n\n for (var i = 0; i < bufLength; i++) {\n var x = inputBuffer[i];\n\n if (this.normalize) {\n sum += Math.max(Math.min(x / this.volMax, 1), -1) * Math.max(Math.min(x / this.volMax, 1), -1);\n } else {\n sum += x * x;\n }\n } // ... then take the square root of the sum.\n\n\n var rms = Math.sqrt(sum / bufLength);\n this.stereoVol[channel] = Math.max(rms, this.stereoVol[channel] * smoothing);\n this.volMax = Math.max(this.stereoVol[channel], this.volMax);\n } // calculate stero normalized volume and add volume from all channels together\n\n\n var volSum = 0;\n\n for (var index = 0; index < this.stereoVol.length; index++) {\n this.stereoVolNorm[index] = Math.max(Math.min(this.stereoVol[index] / this.volMax, 1), 0);\n volSum += this.stereoVol[index];\n } // volume is average of channels\n\n\n var volume = volSum / this.stereoVol.length; // normalized value\n\n var volNorm = Math.max(Math.min(volume / this.volMax, 1), 0);\n this.port.postMessage({\n name: \'amplitude\',\n volume: volume,\n volNorm: volNorm,\n stereoVol: this.stereoVol,\n stereoVolNorm: this.stereoVolNorm\n }); // pass input through to output\n\n for (var _channel = 0; _channel < output.length; ++_channel) {\n output[_channel].set(input[_channel]);\n }\n\n return true;\n }\n }]);\n\n return AmplitudeProcessor;\n}(_wrapNativeSuper(AudioWorkletProcessor));\n\nregisterProcessor(processorNames.amplitudeProcessor, AmplitudeProcessor);'},function(t,e,i){"use strict";var n;function o(t){return(o="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t})(t)}void 0===(n=function(t){var a=i(1).audiocontext;void 0!==a.createStereoPanner?(p5.Panner=function(t,e){this.stereoPanner=this.input=a.createStereoPanner(),t.connect(this.stereoPanner),this.stereoPanner.connect(e)},p5.Panner.prototype.pan=function(t,e){var i=e||0,n=a.currentTime+i;this.stereoPanner.pan.linearRampToValueAtTime(t,n)},p5.Panner.prototype.inputChannels=function(){},p5.Panner.prototype.connect=function(t){this.stereoPanner.connect(t)},p5.Panner.prototype.disconnect=function(){this.stereoPanner&&this.stereoPanner.disconnect()}):(p5.Panner=function(t,e,i){this.input=a.createGain(),t.connect(this.input),this.left=a.createGain(),this.right=a.createGain(),this.left.channelInterpretation="discrete",this.right.channelInterpretation="discrete",1this.buffer.duration)throw"jump time out of range";if(e>this.buffer.duration-t)throw"end time out of range";var i=t||0,n=e||void 0;this.isPlaying()&&this.stop(0),this.play(0,this.playbackRate,this.output.gain.value,i,n)},p5.SoundFile.prototype.channels=function(){return this.buffer.numberOfChannels},p5.SoundFile.prototype.sampleRate=function(){return this.buffer.sampleRate},p5.SoundFile.prototype.frames=function(){return this.buffer.length},p5.SoundFile.prototype.getPeaks=function(t){if(!this.buffer)throw"Cannot load peaks yet, buffer is not loaded";if(t=t||5*window.width,this.buffer){for(var e=this.buffer,i=e.length/t,n=~~(i/10)||1,o=e.numberOfChannels,r=new Float32Array(Math.round(t)),s=0;sr[u])&&(r[u]=h)}return r}},p5.SoundFile.prototype.reverseBuffer=function(){if(!this.buffer)throw"SoundFile is not done loading";var t=this._lastPos/p.sampleRate,e=this.getVolume();this.setVolume(0,.001);for(var i=this.buffer.numberOfChannels,n=0;ne){var r=t[o],s=new c(r,o);i[o]=s,o+=6e3}o++}return i}function m(t){if(isFinite(t)&&0!==t){for(;t<90;)t*=2;for(;180t[r].hi&&r++,o[r]=void 0!==o[r]?(o[r]+i[s])/2:i[s]}return o},p5.FFT.prototype.getOctaveBands=function(t,e){t=t||3;var i=[],n={lo:(e=e||15.625)/Math.pow(2,1/(2*t)),ctr:e,hi:e*Math.pow(2,1/(2*t))};i.push(n);for(var o=c.audiocontext.sampleRate/2;n.hi=this._maxDelay)throw new Error("Delay Time exceeds maximum delay time of "+this._maxDelay+" second.");t.connect(this.input),this.leftDelay.delayTime.setValueAtTime(r,this.ac.currentTime),this.rightDelay.delayTime.setValueAtTime(r,this.ac.currentTime),this._leftGain.gain.value=o,this._rightGain.gain.value=o,n&&(this._leftFilter.freq(n),this._rightFilter.freq(n))},p5.Delay.prototype.delayTime=function(t){"number"!=typeof t?(t.connect(this.leftDelay.delayTime),t.connect(this.rightDelay.delayTime)):(this.leftDelay.delayTime.cancelScheduledValues(this.ac.currentTime),this.rightDelay.delayTime.cancelScheduledValues(this.ac.currentTime),this.leftDelay.delayTime.linearRampToValueAtTime(t,this.ac.currentTime),this.rightDelay.delayTime.linearRampToValueAtTime(t,this.ac.currentTime))},p5.Delay.prototype.feedback=function(t){if(t&&"number"!=typeof t)t.connect(this._leftGain.gain),t.connect(this._rightGain.gain);else{if(1<=t)throw new Error("Feedback value will force a positive feedback loop.");"number"==typeof t&&(this._leftGain.gain.value=t,this._rightGain.gain.value=t)}return this._leftGain.gain.value},p5.Delay.prototype.filter=function(t,e){this._leftFilter.set(t,e),this._rightFilter.set(t,e)},p5.Delay.prototype.setType=function(t){switch(1===t&&(t="pingPong"),this._split.disconnect(),this._leftFilter.disconnect(),this._rightFilter.disconnect(),this._split.connect(this.leftDelay,0),this._split.connect(this.rightDelay,1),t){case"pingPong":this._rightFilter.setType(this._leftFilter.biquad.type),this._leftFilter.output.connect(this._merge,0,0),this._rightFilter.output.connect(this._merge,0,1),this._leftFilter.output.connect(this.rightDelay),this._rightFilter.output.connect(this.leftDelay);break;default:this._leftFilter.output.connect(this._merge,0,0),this._rightFilter.output.connect(this._merge,0,1),this._leftFilter.output.connect(this.leftDelay),this._rightFilter.output.connect(this.rightDelay)}},p5.Delay.prototype.dispose=function(){i.prototype.dispose.apply(this),this._split.disconnect(),this._leftFilter.dispose(),this._rightFilter.dispose(),this._merge.disconnect(),this._leftGain.disconnect(),this._rightGain.disconnect(),this.leftDelay.disconnect(),this.rightDelay.disconnect(),this._split=void 0,this._leftFilter=void 0,this._rightFilter=void 0,this._merge=void 0,this._leftGain=void 0,this._rightGain=void 0,this.leftDelay=void 0,this.rightDelay=void 0}}.call(e,n,e,t))||(t.exports=i)},function(t,e,i){"use strict";var n;void 0===(n=function(t){var p=i(10),e=i(4);p5.Reverb=function(){e.call(this),this._initConvolverNode(),this.input.gain.value=.5,this._seconds=3,this._decay=2,this._reverse=!1,this._buildImpulse()},p5.Reverb.prototype=Object.create(e.prototype),p5.Reverb.prototype._initConvolverNode=function(){this.convolverNode=this.ac.createConvolver(),this.input.connect(this.convolverNode),this.convolverNode.connect(this.wet)},p5.Reverb.prototype._teardownConvolverNode=function(){this.convolverNode&&(this.convolverNode.disconnect(),delete this.convolverNode)},p5.Reverb.prototype._setBuffer=function(t){this._teardownConvolverNode(),this._initConvolverNode(),this.convolverNode.buffer=t},p5.Reverb.prototype.process=function(t,e,i,n){t.connect(this.input);var o=!1;e&&(this._seconds=e,o=!0),i&&(this._decay=i),n&&(this._reverse=n),o&&this._buildImpulse()},p5.Reverb.prototype.set=function(t,e,i){var n=!1;t&&(this._seconds=t,n=!0),e&&(this._decay=e),i&&(this._reverse=i),n&&this._buildImpulse()},p5.Reverb.prototype._buildImpulse=function(){var t,e,i=this.ac.sampleRate,n=i*this._seconds,o=this._decay,r=this.ac.createBuffer(2,n,i),s=r.getChannelData(0),a=r.getChannelData(1);for(e=0;e=t.parts.length?(t.scoreStep=0,t.onended()):(t.scoreStep=0,t.parts[t.currentPart-1].stop(),t.parts[t.currentPart].start())}p5.prototype.setBPM=function(t,e){for(var i in o=t,n.parts)n.parts[i]&&n.parts[i].setBPM(t,e)},p5.Phrase=function(t,e,i){this.phraseStep=0,this.name=t,this.callback=e,this.sequence=i},p5.Part=function(t,e){this.length=t||0,this.partStep=0,this.phrases=[],this.isPlaying=!1,this.noLoop(),this.tatums=e||.0625,this.metro=new p5.Metro,this.metro._init(),this.metro.beatLength(this.tatums),this.metro.setBPM(o),n.parts.push(this),this.callback=function(){}},p5.Part.prototype.setBPM=function(t,e){this.metro.setBPM(t,e)},p5.Part.prototype.getBPM=function(){return this.metro.getBPM()},p5.Part.prototype.start=function(t){if(!this.isPlaying){this.isPlaying=!0,this.metro.resetSync(this);var e=t||0;this.metro.start(e)}},p5.Part.prototype.loop=function(t){this.looping=!0,this.onended=function(){this.partStep=0};var e=t||0;this.start(e)},p5.Part.prototype.noLoop=function(){this.looping=!1,this.onended=function(){this.stop()}},p5.Part.prototype.stop=function(t){this.partStep=0,this.pause(t)},p5.Part.prototype.pause=function(t){this.isPlaying=!1;var e=t||0;this.metro.stop(e)},p5.Part.prototype.addPhrase=function(t,e,i){var n;if(3===arguments.length)n=new p5.Phrase(t,e,i);else{if(!(t instanceof p5.Phrase))throw"invalid input. addPhrase accepts name, callback, array or a p5.Phrase";n=t}this.phrases.push(n),n.sequence.length>this.length&&(this.length=n.sequence.length)},p5.Part.prototype.removePhrase=function(t){for(var e in this.phrases)this.phrases[e].name===t&&this.phrases.splice(e,1)},p5.Part.prototype.getPhrase=function(t){for(var e in this.phrases)if(this.phrases[e].name===t)return this.phrases[e]},p5.Part.prototype.replaceSequence=function(t,e){for(var i in this.phrases)this.phrases[i].name===t&&(this.phrases[i].sequence=e)},p5.Part.prototype.incrementStep=function(t){this.partStepthis.cutoff&&e>this.threshold&&0 1){\n\t\t\tthis.input = new Array(inputs);\n\t\t}\n\n\t\t/**\n\t\t * the output node(s)\n\t\t * @type {GainNode|Array}\n\t\t */\n\t\tif (this.isUndef(outputs) || outputs === 1){\n\t\t\tthis.output = this.context.createGain();\n\t\t} else if (outputs > 1){\n\t\t\tthis.output = new Array(inputs);\n\t\t}\n\t};\n\n\t/**\n\t * Set the parameters at once. Either pass in an\n\t * object mapping parameters to values, or to set a\n\t * single parameter, by passing in a string and value.\n\t * The last argument is an optional ramp time which \n\t * will ramp any signal values to their destination value\n\t * over the duration of the rampTime.\n\t * @param {Object|string} params\n\t * @param {number=} value\n\t * @param {Time=} rampTime\n\t * @returns {Tone} this\n\t * @example\n\t * //set values using an object\n\t * filter.set({\n\t * \t\"frequency\" : 300,\n\t * \t\"type\" : highpass\n\t * });\n\t * @example\n\t * filter.set(\"type\", \"highpass\");\n\t * @example\n\t * //ramp to the value 220 over 3 seconds. \n\t * oscillator.set({\n\t * \t\"frequency\" : 220\n\t * }, 3);\n\t */\n\tTone.prototype.set = function(params, value, rampTime){\n\t\tif (this.isObject(params)){\n\t\t\trampTime = value;\n\t\t} else if (this.isString(params)){\n\t\t\tvar tmpObj = {};\n\t\t\ttmpObj[params] = value;\n\t\t\tparams = tmpObj;\n\t\t}\n\n\t\tparamLoop:\n\t\tfor (var attr in params){\n\t\t\tvalue = params[attr];\n\t\t\tvar parent = this;\n\t\t\tif (attr.indexOf(\".\") !== -1){\n\t\t\t\tvar attrSplit = attr.split(\".\");\n\t\t\t\tfor (var i = 0; i < attrSplit.length - 1; i++){\n\t\t\t\t\tparent = parent[attrSplit[i]];\n\t\t\t\t\tif (parent instanceof Tone) {\n\t\t\t\t\t\tattrSplit.splice(0,i+1);\n\t\t\t\t\t\tvar innerParam = attrSplit.join(\".\");\n\t\t\t\t\t\tparent.set(innerParam, value);\n\t\t\t\t\t\tcontinue paramLoop;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tattr = attrSplit[attrSplit.length - 1];\n\t\t\t}\n\t\t\tvar param = parent[attr];\n\t\t\tif (this.isUndef(param)){\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tif ((Tone.Signal && param instanceof Tone.Signal) || \n\t\t\t\t\t(Tone.Param && param instanceof Tone.Param)){\n\t\t\t\tif (param.value !== value){\n\t\t\t\t\tif (this.isUndef(rampTime)){\n\t\t\t\t\t\tparam.value = value;\n\t\t\t\t\t} else {\n\t\t\t\t\t\tparam.rampTo(value, rampTime);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} else if (param instanceof AudioParam){\n\t\t\t\tif (param.value !== value){\n\t\t\t\t\tparam.value = value;\n\t\t\t\t}\t\t\t\t\n\t\t\t} else if (param instanceof Tone){\n\t\t\t\tparam.set(value);\n\t\t\t} else if (param !== value){\n\t\t\t\tparent[attr] = value;\n\t\t\t}\n\t\t}\n\t\treturn this;\n\t};\n\n\t/**\n\t * Get the object's attributes. Given no arguments get\n\t * will return all available object properties and their corresponding\n\t * values. Pass in a single attribute to retrieve or an array\n\t * of attributes. The attribute strings can also include a \".\"\n\t * to access deeper properties.\n\t * @example\n\t * osc.get();\n\t * //returns {\"type\" : \"sine\", \"frequency\" : 440, ...etc}\n\t * @example\n\t * osc.get(\"type\");\n\t * //returns { \"type\" : \"sine\"}\n\t * @example\n\t * //use dot notation to access deep properties\n\t * synth.get([\"envelope.attack\", \"envelope.release\"]);\n\t * //returns {\"envelope\" : {\"attack\" : 0.2, \"release\" : 0.4}}\n\t * @param {Array=|string|undefined} params the parameters to get, otherwise will return \n\t * \t\t\t\t\t all available.\n\t * @returns {Object}\n\t */\n\tTone.prototype.get = function(params){\n\t\tif (this.isUndef(params)){\n\t\t\tparams = this._collectDefaults(this.constructor);\n\t\t} else if (this.isString(params)){\n\t\t\tparams = [params];\n\t\t} \n\t\tvar ret = {};\n\t\tfor (var i = 0; i < params.length; i++){\n\t\t\tvar attr = params[i];\n\t\t\tvar parent = this;\n\t\t\tvar subRet = ret;\n\t\t\tif (attr.indexOf(\".\") !== -1){\n\t\t\t\tvar attrSplit = attr.split(\".\");\n\t\t\t\tfor (var j = 0; j < attrSplit.length - 1; j++){\n\t\t\t\t\tvar subAttr = attrSplit[j];\n\t\t\t\t\tsubRet[subAttr] = subRet[subAttr] || {};\n\t\t\t\t\tsubRet = subRet[subAttr];\n\t\t\t\t\tparent = parent[subAttr];\n\t\t\t\t}\n\t\t\t\tattr = attrSplit[attrSplit.length - 1];\n\t\t\t}\n\t\t\tvar param = parent[attr];\n\t\t\tif (this.isObject(params[attr])){\n\t\t\t\tsubRet[attr] = param.get();\n\t\t\t} else if (Tone.Signal && param instanceof Tone.Signal){\n\t\t\t\tsubRet[attr] = param.value;\n\t\t\t} else if (Tone.Param && param instanceof Tone.Param){\n\t\t\t\tsubRet[attr] = param.value;\n\t\t\t} else if (param instanceof AudioParam){\n\t\t\t\tsubRet[attr] = param.value;\n\t\t\t} else if (param instanceof Tone){\n\t\t\t\tsubRet[attr] = param.get();\n\t\t\t} else if (!this.isFunction(param) && !this.isUndef(param)){\n\t\t\t\tsubRet[attr] = param;\n\t\t\t} \n\t\t}\n\t\treturn ret;\n\t};\n\n\t/**\n\t * collect all of the default attributes in one\n\t * @private\n\t * @param {function} constr the constructor to find the defaults from\n\t * @return {Array} all of the attributes which belong to the class\n\t */\n\tTone.prototype._collectDefaults = function(constr){\n\t\tvar ret = [];\n\t\tif (!this.isUndef(constr.defaults)){\n\t\t\tret = Object.keys(constr.defaults);\n\t\t}\n\t\tif (!this.isUndef(constr._super)){\n\t\t\tvar superDefs = this._collectDefaults(constr._super);\n\t\t\t//filter out repeats\n\t\t\tfor (var i = 0; i < superDefs.length; i++){\n\t\t\t\tif (ret.indexOf(superDefs[i]) === -1){\n\t\t\t\t\tret.push(superDefs[i]);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\treturn ret;\n\t};\n\n\t/**\n\t * @returns {string} returns the name of the class as a string\n\t */\n\tTone.prototype.toString = function(){\n\t\tfor (var className in Tone){\n\t\t\tvar isLetter = className[0].match(/^[A-Z]$/);\n\t\t\tvar sameConstructor = Tone[className] === this.constructor;\n\t\t\tif (this.isFunction(Tone[className]) && isLetter && sameConstructor){\n\t\t\t\treturn className;\n\t\t\t}\n\t\t}\n\t\treturn \"Tone\";\n\t};\n\n\t///////////////////////////////////////////////////////////////////////////\n\t//\tCLASS VARS\n\t///////////////////////////////////////////////////////////////////////////\n\n\t/**\n\t * The number of inputs feeding into the AudioNode. \n\t * For source nodes, this will be 0.\n\t * @memberOf Tone#\n\t * @name numberOfInputs\n\t * @readOnly\n\t */\n\tObject.defineProperty(Tone.prototype, \"numberOfInputs\", {\n\t\tget : function(){\n\t\t\tif (this.input){\n\t\t\t\tif (this.isArray(this.input)){\n\t\t\t\t\treturn this.input.length;\n\t\t\t\t} else {\n\t\t\t\t\treturn 1;\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\treturn 0;\n\t\t\t}\n\t\t}\n\t});\n\n\t/**\n\t * The number of outputs coming out of the AudioNode. \n\t * For source nodes, this will be 0.\n\t * @memberOf Tone#\n\t * @name numberOfInputs\n\t * @readOnly\n\t */\n\tObject.defineProperty(Tone.prototype, \"numberOfOutputs\", {\n\t\tget : function(){\n\t\t\tif (this.output){\n\t\t\t\tif (this.isArray(this.output)){\n\t\t\t\t\treturn this.output.length;\n\t\t\t\t} else {\n\t\t\t\t\treturn 1;\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\treturn 0;\n\t\t\t}\n\t\t}\n\t});\n\t\n\t///////////////////////////////////////////////////////////////////////////\n\t//\tCONNECTIONS\n\t///////////////////////////////////////////////////////////////////////////\n\n\t/**\n\t * disconnect and dispose\n\t * @returns {Tone} this\n\t */\n\tTone.prototype.dispose = function(){\n\t\tif (!this.isUndef(this.input)){\n\t\t\tif (this.input instanceof AudioNode){\n\t\t\t\tthis.input.disconnect();\n\t\t\t} \n\t\t\tthis.input = null;\n\t\t}\n\t\tif (!this.isUndef(this.output)){\n\t\t\tif (this.output instanceof AudioNode){\n\t\t\t\tthis.output.disconnect();\n\t\t\t} \n\t\t\tthis.output = null;\n\t\t}\n\t\treturn this;\n\t};\n\n\t/**\n\t * connect the output of a ToneNode to an AudioParam, AudioNode, or ToneNode\n\t * @param {Tone | AudioParam | AudioNode} unit \n\t * @param {number} [outputNum=0] optionally which output to connect from\n\t * @param {number} [inputNum=0] optionally which input to connect to\n\t * @returns {Tone} this\n\t */\n\tTone.prototype.connect = function(unit, outputNum, inputNum){\n\t\tif (Array.isArray(this.output)){\n\t\t\toutputNum = this.defaultArg(outputNum, 0);\n\t\t\tthis.output[outputNum].connect(unit, 0, inputNum);\n\t\t} else {\n\t\t\tthis.output.connect(unit, outputNum, inputNum);\n\t\t}\n\t\treturn this;\n\t};\n\n\t/**\n\t * disconnect the output\n\t * @param {Number|AudioNode} output Either the output index to disconnect\n\t * if the output is an array, or the\n\t * node to disconnect from.\n\t * @returns {Tone} this\n\t */\n\tTone.prototype.disconnect = function(destination, outputNum, inputNum){\n\t\tif (this.isArray(this.output)){\n\t\t\tif (this.isNumber(destination)){\n\t\t\t\tthis.output[destination].disconnect();\n\t\t\t} else {\n\t\t\t\toutputNum = this.defaultArg(outputNum, 0);\n\t\t\t\tthis.output[outputNum].disconnect(destination, 0, inputNum);\n\t\t\t}\n\t\t} else {\n\t\t\tthis.output.disconnect.apply(this.output, arguments);\n\t\t}\n\t};\n\n\t/**\n\t * connect together all of the arguments in series\n\t * @param {...AudioParam|Tone|AudioNode} nodes\n\t * @returns {Tone} this\n\t */\n\tTone.prototype.connectSeries = function(){\n\t\tif (arguments.length > 1){\n\t\t\tvar currentUnit = arguments[0];\n\t\t\tfor (var i = 1; i < arguments.length; i++){\n\t\t\t\tvar toUnit = arguments[i];\n\t\t\t\tcurrentUnit.connect(toUnit);\n\t\t\t\tcurrentUnit = toUnit;\n\t\t\t}\n\t\t}\n\t\treturn this;\n\t};\n\n\t/**\n\t * Connect the output of this node to the rest of the nodes in series.\n\t * @example\n\t * //connect a node to an effect, panVol and then to the master output\n\t * node.chain(effect, panVol, Tone.Master);\n\t * @param {...AudioParam|Tone|AudioNode} nodes\n\t * @returns {Tone} this\n\t */\n\tTone.prototype.chain = function(){\n\t\tif (arguments.length > 0){\n\t\t\tvar currentUnit = this;\n\t\t\tfor (var i = 0; i < arguments.length; i++){\n\t\t\t\tvar toUnit = arguments[i];\n\t\t\t\tcurrentUnit.connect(toUnit);\n\t\t\t\tcurrentUnit = toUnit;\n\t\t\t}\n\t\t}\n\t\treturn this;\n\t};\n\n\t/**\n\t * connect the output of this node to the rest of the nodes in parallel.\n\t * @param {...AudioParam|Tone|AudioNode} nodes\n\t * @returns {Tone} this\n\t */\n\tTone.prototype.fan = function(){\n\t\tif (arguments.length > 0){\n\t\t\tfor (var i = 0; i < arguments.length; i++){\n\t\t\t\tthis.connect(arguments[i]);\n\t\t\t}\n\t\t}\n\t\treturn this;\n\t};\n\n\t//give native nodes chain and fan methods\n\tAudioNode.prototype.chain = Tone.prototype.chain;\n\tAudioNode.prototype.fan = Tone.prototype.fan;\n\n\t///////////////////////////////////////////////////////////////////////////\n\t//\tUTILITIES / HELPERS / MATHS\n\t///////////////////////////////////////////////////////////////////////////\n\n\t/**\n\t * If the `given` parameter is undefined, use the `fallback`. \n\t * If both `given` and `fallback` are object literals, it will\n\t * return a deep copy which includes all of the parameters from both \n\t * objects. If a parameter is undefined in given, it will return\n\t * the fallback property. \n\t *
\n\t * WARNING: if object is self referential, it will go into an an \n\t * infinite recursive loop.\n\t * \n\t * @param {*} given \n\t * @param {*} fallback \n\t * @return {*} \n\t */\n\tTone.prototype.defaultArg = function(given, fallback){\n\t\tif (this.isObject(given) && this.isObject(fallback)){\n\t\t\tvar ret = {};\n\t\t\t//make a deep copy of the given object\n\t\t\tfor (var givenProp in given) {\n\t\t\t\tret[givenProp] = this.defaultArg(fallback[givenProp], given[givenProp]);\n\t\t\t}\n\t\t\tfor (var fallbackProp in fallback) {\n\t\t\t\tret[fallbackProp] = this.defaultArg(given[fallbackProp], fallback[fallbackProp]);\n\t\t\t}\n\t\t\treturn ret;\n\t\t} else {\n\t\t\treturn this.isUndef(given) ? fallback : given;\n\t\t}\n\t};\n\n\t/**\n\t * returns the args as an options object with given arguments\n\t * mapped to the names provided. \n\t *\n\t * if the args given is an array containing only one object, it is assumed\n\t * that that's already the options object and will just return it. \n\t * \n\t * @param {Array} values the 'arguments' object of the function\n\t * @param {Array} keys the names of the arguments as they\n\t * should appear in the options object\n\t * @param {Object=} defaults optional defaults to mixin to the returned \n\t * options object \n\t * @return {Object} the options object with the names mapped to the arguments\n\t */\n\tTone.prototype.optionsObject = function(values, keys, defaults){\n\t\tvar options = {};\n\t\tif (values.length === 1 && this.isObject(values[0])){\n\t\t\toptions = values[0];\n\t\t} else {\n\t\t\tfor (var i = 0; i < keys.length; i++){\n\t\t\t\toptions[keys[i]] = values[i];\n\t\t\t}\n\t\t}\n\t\tif (!this.isUndef(defaults)){\n\t\t\treturn this.defaultArg(options, defaults);\n\t\t} else {\n\t\t\treturn options;\n\t\t}\n\t};\n\n\t///////////////////////////////////////////////////////////////////////////\n\t// TYPE CHECKING\n\t///////////////////////////////////////////////////////////////////////////\n\n\t/**\n\t * test if the arg is undefined\n\t * @param {*} arg the argument to test\n\t * @returns {boolean} true if the arg is undefined\n\t * @function\n\t */\n\tTone.prototype.isUndef = function(val){\n\t\treturn typeof val === \"undefined\";\n\t};\n\n\t/**\n\t * test if the arg is a function\n\t * @param {*} arg the argument to test\n\t * @returns {boolean} true if the arg is a function\n\t * @function\n\t */\n\tTone.prototype.isFunction = function(val){\n\t\treturn typeof val === \"function\";\n\t};\n\n\t/**\n\t * Test if the argument is a number.\n\t * @param {*} arg the argument to test\n\t * @returns {boolean} true if the arg is a number\n\t */\n\tTone.prototype.isNumber = function(arg){\n\t\treturn (typeof arg === \"number\");\n\t};\n\n\t/**\n\t * Test if the given argument is an object literal (i.e. `{}`);\n\t * @param {*} arg the argument to test\n\t * @returns {boolean} true if the arg is an object literal.\n\t */\n\tTone.prototype.isObject = function(arg){\n\t\treturn (Object.prototype.toString.call(arg) === \"[object Object]\" && arg.constructor === Object);\n\t};\n\n\t/**\n\t * Test if the argument is a boolean.\n\t * @param {*} arg the argument to test\n\t * @returns {boolean} true if the arg is a boolean\n\t */\n\tTone.prototype.isBoolean = function(arg){\n\t\treturn (typeof arg === \"boolean\");\n\t};\n\n\t/**\n\t * Test if the argument is an Array\n\t * @param {*} arg the argument to test\n\t * @returns {boolean} true if the arg is an array\n\t */\n\tTone.prototype.isArray = function(arg){\n\t\treturn (Array.isArray(arg));\n\t};\n\n\t/**\n\t * Test if the argument is a string.\n\t * @param {*} arg the argument to test\n\t * @returns {boolean} true if the arg is a string\n\t */\n\tTone.prototype.isString = function(arg){\n\t\treturn (typeof arg === \"string\");\n\t};\n\n \t/**\n\t * An empty function.\n\t * @static\n\t */\n\tTone.noOp = function(){};\n\n\t/**\n\t * Make the property not writable. Internal use only. \n\t * @private\n\t * @param {string} property the property to make not writable\n\t */\n\tTone.prototype._readOnly = function(property){\n\t\tif (Array.isArray(property)){\n\t\t\tfor (var i = 0; i < property.length; i++){\n\t\t\t\tthis._readOnly(property[i]);\n\t\t\t}\n\t\t} else {\n\t\t\tObject.defineProperty(this, property, { \n\t\t\t\twritable: false,\n\t\t\t\tenumerable : true,\n\t\t\t});\n\t\t}\n\t};\n\n\t/**\n\t * Make an attribute writeable. Interal use only. \n\t * @private\n\t * @param {string} property the property to make writable\n\t */\n\tTone.prototype._writable = function(property){\n\t\tif (Array.isArray(property)){\n\t\t\tfor (var i = 0; i < property.length; i++){\n\t\t\t\tthis._writable(property[i]);\n\t\t\t}\n\t\t} else {\n\t\t\tObject.defineProperty(this, property, { \n\t\t\t\twritable: true,\n\t\t\t});\n\t\t}\n\t};\n\n\t/**\n\t * Possible play states. \n\t * @enum {string}\n\t */\n\tTone.State = {\n\t\tStarted : \"started\",\n\t\tStopped : \"stopped\",\n\t\tPaused : \"paused\",\n \t};\n\n\t///////////////////////////////////////////////////////////////////////////\n\t// CONVERSIONS\n\t///////////////////////////////////////////////////////////////////////////\n\n\t/**\n\t * Equal power gain scale. Good for cross-fading.\n\t * @param {NormalRange} percent (0-1)\n\t * @return {Number} output gain (0-1)\n\t */\n\tTone.prototype.equalPowerScale = function(percent){\n\t\tvar piFactor = 0.5 * Math.PI;\n\t\treturn Math.sin(percent * piFactor);\n\t};\n\n\t/**\n\t * Convert decibels into gain.\n\t * @param {Decibels} db\n\t * @return {Number} \n\t */\n\tTone.prototype.dbToGain = function(db) {\n\t\treturn Math.pow(2, db / 6);\n\t};\n\n\t/**\n\t * Convert gain to decibels.\n\t * @param {Number} gain (0-1)\n\t * @return {Decibels} \n\t */\n\tTone.prototype.gainToDb = function(gain) {\n\t\treturn 20 * (Math.log(gain) / Math.LN10);\n\t};\n\n\t/**\n\t * Convert an interval (in semitones) to a frequency ratio.\n\t * @param {Interval} interval the number of semitones above the base note\n\t * @return {number} the frequency ratio\n\t * @example\n\t * tone.intervalToFrequencyRatio(0); // 1\n\t * tone.intervalToFrequencyRatio(12); // 2\n\t * tone.intervalToFrequencyRatio(-12); // 0.5\n\t */\n\tTone.prototype.intervalToFrequencyRatio = function(interval){\n\t\treturn Math.pow(2,(interval/12));\n\t};\n\n\t///////////////////////////////////////////////////////////////////////////\n\t//\tTIMING\n\t///////////////////////////////////////////////////////////////////////////\n\n\t/**\n\t * Return the current time of the AudioContext clock.\n\t * @return {Number} the currentTime from the AudioContext\n\t */\n\tTone.prototype.now = function(){\n\t\treturn Tone.context.now();\n\t};\n\n\t/**\n\t * Return the current time of the AudioContext clock.\n\t * @return {Number} the currentTime from the AudioContext\n\t * @static\n\t */\n\tTone.now = function(){\n\t\treturn Tone.context.now();\n\t};\n\n\t///////////////////////////////////////////////////////////////////////////\n\t//\tINHERITANCE\n\t///////////////////////////////////////////////////////////////////////////\n\n\t/**\n\t * have a child inherit all of Tone's (or a parent's) prototype\n\t * to inherit the parent's properties, make sure to call \n\t * Parent.call(this) in the child's constructor\n\t *\n\t * based on closure library's inherit function\n\t *\n\t * @static\n\t * @param {function} \tchild \n\t * @param {function=} parent (optional) parent to inherit from\n\t * if no parent is supplied, the child\n\t * will inherit from Tone\n\t */\n\tTone.extend = function(child, parent){\n\t\tif (Tone.prototype.isUndef(parent)){\n\t\t\tparent = Tone;\n\t\t}\n\t\tfunction TempConstructor(){}\n\t\tTempConstructor.prototype = parent.prototype;\n\t\tchild.prototype = new TempConstructor();\n\t\t/** @override */\n\t\tchild.prototype.constructor = child;\n\t\tchild._super = parent;\n\t};\n\n\t///////////////////////////////////////////////////////////////////////////\n\t//\tCONTEXT\n\t///////////////////////////////////////////////////////////////////////////\n\n\t/**\n\t * The private audio context shared by all Tone Nodes. \n\t * @private\n\t * @type {Tone.Context|undefined}\n\t */\n\tvar audioContext;\n\n\t/**\n\t * A static pointer to the audio context accessible as Tone.context. \n\t * @type {Tone.Context}\n\t * @name context\n\t * @memberOf Tone\n\t */\n\tObject.defineProperty(Tone, \"context\", {\n\t\tget : function(){\n\t\t\treturn audioContext;\n\t\t},\n\t\tset : function(context){\n\t\t\tif (Tone.Context && context instanceof Tone.Context){\n\t\t\t\taudioContext = context;\n\t\t\t} else {\n\t\t\t\taudioContext = new Tone.Context(context);\n\t\t\t}\n\t\t\t//initialize the new audio context\n\t\t\tif (Tone.Context){\n\t\t\t\tTone.Context.emit(\"init\", audioContext);\n\t\t\t}\n\t\t}\n\t});\n\n\t/**\n\t * The AudioContext\n\t * @type {Tone.Context}\n\t * @name context\n\t * @memberOf Tone#\n\t * @readOnly\n\t */\n\tObject.defineProperty(Tone.prototype, \"context\", {\n\t\tget : function(){\n\t\t\treturn Tone.context;\n\t\t}\n\t});\n\n\t/**\n\t * Tone automatically creates a context on init, but if you are working\n\t * with other libraries which also create an AudioContext, it can be\n\t * useful to set your own. If you are going to set your own context, \n\t * be sure to do it at the start of your code, before creating any objects.\n\t * @static\n\t * @param {AudioContext} ctx The new audio context to set\n\t */\n\tTone.setContext = function(ctx){\n\t\tTone.context = ctx;\n\t};\n\n\t/**\n\t * The number of seconds of 1 processing block (128 samples)\n\t * @type {Number}\n\t * @name blockTime\n\t * @memberOf Tone#\n\t * @readOnly\n\t */\n\tObject.defineProperty(Tone.prototype, \"blockTime\", {\n\t\tget : function(){\n\t\t\treturn 128 / this.context.sampleRate;\n\t\t}\n\t});\n\n\t/**\n\t * The duration in seconds of one sample.\n\t * @type {Number}\n\t * @name sampleTime\n\t * @memberOf Tone#\n\t * @readOnly\n\t */\n\tObject.defineProperty(Tone.prototype, \"sampleTime\", {\n\t\tget : function(){\n\t\t\treturn 1 / this.context.sampleRate;\n\t\t}\n\t});\n\n\t/**\n\t * Whether or not all the technologies that Tone.js relies on are supported by the current browser. \n\t * @type {Boolean}\n\t * @name supported\n\t * @memberOf Tone\n\t * @readOnly\n\t */\n\tObject.defineProperty(Tone, \"supported\", {\n\t\tget : function(){\n\t\t\tvar hasAudioContext = window.hasOwnProperty(\"AudioContext\") || window.hasOwnProperty(\"webkitAudioContext\");\n\t\t\tvar hasPromises = window.hasOwnProperty(\"Promise\");\n\t\t\tvar hasWorkers = window.hasOwnProperty(\"Worker\");\n\t\t\treturn hasAudioContext && hasPromises && hasWorkers;\n\t\t}\n\t});\n\n\tTone.version = \"r10\";\n\n\t// allow optional silencing of this log\n\tif (!window.TONE_SILENCE_VERSION_LOGGING) {\n\t\tconsole.log(\"%c * Tone.js \" + Tone.version + \" * \", \"background: #000; color: #fff\");\n\t}\n\n\treturn Tone;\n});\n","'use strict';\n\n\ndefine(['audiocontext'], function (audiocontext) {\n /**\n * Master contains AudioContext and the master sound output.\n * @for p5\n */\n var Master = function() {\n this.input = audiocontext.createGain();\n this.output = audiocontext.createGain();\n\n //put a hard limiter on the output\n this.limiter = audiocontext.createDynamicsCompressor();\n this.limiter.threshold.value = -3;\n this.limiter.ratio.value = 20;\n this.limiter.knee.value = 1;\n\n this.audiocontext = audiocontext;\n\n this.output.disconnect();\n\n // connect input to limiter\n this.input.connect(this.limiter);\n\n // connect limiter to output\n this.limiter.connect(this.output);\n\n // meter is just for global Amplitude / FFT analysis\n this.meter = audiocontext.createGain();\n this.fftMeter = audiocontext.createGain();\n this.output.connect(this.meter);\n this.output.connect(this.fftMeter);\n\n // connect output to destination\n this.output.connect(this.audiocontext.destination);\n\n // an array of all sounds in the sketch\n this.soundArray = [];\n // an array of all musical parts in the sketch\n this.parts = [];\n\n // file extensions to search for\n this.extensions = [];\n };\n\n // create a single instance of the p5Sound / master output for use within this sketch\n var p5sound = new Master();\n\n /**\n * Returns a number representing the master amplitude (volume) for sound\n * in this sketch.\n *\n * @method getMasterVolume\n * @return {Number} Master amplitude (volume) for sound in this sketch.\n * Should be between 0.0 (silence) and 1.0.\n */\n p5.prototype.getMasterVolume = function() {\n return p5sound.output.gain.value;\n };\n\n /**\n *
Scale the output of all sound in this sketch
\n * Scaled between 0.0 (silence) and 1.0 (full volume).\n * 1.0 is the maximum amplitude of a digital sound, so multiplying\n * by greater than 1.0 may cause digital distortion. To\n * fade, provide a rampTime parameter. For more\n * complex fades, see the Envelope class.\n *\n * Alternately, you can pass in a signal source such as an\n * oscillator to modulate the amplitude with an audio signal.\n *\n *
How This Works: When you load the p5.sound module, it\n * creates a single instance of p5sound. All sound objects in this\n * module output to p5sound before reaching your computer's output.\n * So if you change the amplitude of p5sound, it impacts all of the\n * sound in this module.
\n *\n *
If no value is provided, returns a Web Audio API Gain Node
\n *\n * @method masterVolume\n * @param {Number|Object} volume Volume (amplitude) between 0.0\n * and 1.0 or modulating signal/oscillator\n * @param {Number} [rampTime] Fade for t seconds\n * @param {Number} [timeFromNow] Schedule this event to happen at\n * t seconds in the future\n */\n p5.prototype.masterVolume = function(vol, rampTime, tFromNow) {\n if (typeof vol === 'number') {\n var rampTime = rampTime || 0;\n var tFromNow = tFromNow || 0;\n var now = p5sound.audiocontext.currentTime;\n var currentVol = p5sound.output.gain.value;\n p5sound.output.gain.cancelScheduledValues(now + tFromNow);\n p5sound.output.gain.linearRampToValueAtTime(currentVol, now + tFromNow);\n p5sound.output.gain.linearRampToValueAtTime(vol, now + tFromNow + rampTime);\n }\n else if (vol) {\n vol.connect(p5sound.output.gain);\n } else {\n // return the Gain Node\n return p5sound.output.gain;\n }\n };\n\n /**\n * `p5.soundOut` is the p5.sound master output. It sends output to\n * the destination of this window's web audio context. It contains\n * Web Audio API nodes including a dyanmicsCompressor (.limiter),\n * and Gain Nodes for .input and .output.\n *\n * @property {Object} soundOut\n */\n p5.prototype.soundOut = p5.soundOut = p5sound;\n\n /**\n * a silent connection to the DesinationNode\n * which will ensure that anything connected to it\n * will not be garbage collected\n *\n * @private\n */\n p5.soundOut._silentNode = p5sound.audiocontext.createGain();\n p5.soundOut._silentNode.gain.value = 0;\n p5.soundOut._silentNode.connect(p5sound.audiocontext.destination);\n\n\n return p5sound;\n});\n","define([\"Tone/core/Tone\", \"Tone/signal/WaveShaper\", \"Tone/type/Type\", \"Tone/core/Param\", \"Tone/core/Gain\"], function(Tone){\n\n\t\"use strict\";\n\n\t/**\n\t * @class A signal is an audio-rate value. Tone.Signal is a core component of the library.\n\t * Unlike a number, Signals can be scheduled with sample-level accuracy. Tone.Signal\n\t * has all of the methods available to native Web Audio \n\t * [AudioParam](http://webaudio.github.io/web-audio-api/#the-audioparam-interface)\n\t * as well as additional conveniences. Read more about working with signals \n\t * [here](https://github.com/Tonejs/Tone.js/wiki/Signals).\n\t *\n\t * @constructor\n\t * @extends {Tone.Param}\n\t * @param {Number|AudioParam} [value] Initial value of the signal. If an AudioParam\n\t * is passed in, that parameter will be wrapped\n\t * and controlled by the Signal. \n\t * @param {string} [units=Number] unit The units the signal is in. \n\t * @example\n\t * var signal = new Tone.Signal(10);\n\t */\n\tTone.Signal = function(){\n\n\t\tvar options = this.optionsObject(arguments, [\"value\", \"units\"], Tone.Signal.defaults);\n\n\t\t/**\n\t\t * The node where the constant signal value is scaled.\n\t\t * @type {GainNode}\n\t\t * @private\n\t\t */\n\t\tthis.output = this._gain = this.context.createGain();\n\n\t\toptions.param = this._gain.gain;\n\t\tTone.Param.call(this, options);\n\n\t\t/**\n\t\t * The node where the value is set.\n\t\t * @type {Tone.Param}\n\t\t * @private\n\t\t */\n\t\tthis.input = this._param = this._gain.gain;\n\n\t\t//connect the const output to the node output\n\t\tthis.context.getConstant(1).chain(this._gain);\n\t};\n\n\tTone.extend(Tone.Signal, Tone.Param);\n\n\t/**\n\t * The default values\n\t * @type {Object}\n\t * @static\n\t * @const\n\t */\n\tTone.Signal.defaults = {\n\t\t\"value\" : 0,\n\t\t\"units\" : Tone.Type.Default,\n\t\t\"convert\" : true,\n\t};\n\n\t/**\n\t * When signals connect to other signals or AudioParams, \n\t * they take over the output value of that signal or AudioParam. \n\t * For all other nodes, the behavior is the same as a default connect. \n\t *\n\t * @override\n\t * @param {AudioParam|AudioNode|Tone.Signal|Tone} node \n\t * @param {number} [outputNumber=0] The output number to connect from.\n\t * @param {number} [inputNumber=0] The input number to connect to.\n\t * @returns {Tone.SignalBase} this\n\t * @method\n\t */\n\tTone.Signal.prototype.connect = Tone.SignalBase.prototype.connect;\n\n\t/**\n\t * dispose and disconnect\n\t * @returns {Tone.Signal} this\n\t */\n\tTone.Signal.prototype.dispose = function(){\n\t\tTone.Param.prototype.dispose.call(this);\n\t\tthis._param = null;\n\t\tthis._gain.disconnect();\n\t\tthis._gain = null;\n\t\treturn this;\n\t};\n\n\treturn Tone.Signal;\n});","define([\"Tone/core/Tone\", \"Tone/signal/Signal\", \"Tone/core/Gain\"], function(Tone){\n\n\t\"use strict\";\n\n\t/**\n\t * @class Multiply two incoming signals. Or, if a number is given in the constructor, \n\t * multiplies the incoming signal by that value. \n\t *\n\t * @constructor\n\t * @extends {Tone.Signal}\n\t * @param {number=} value Constant value to multiple. If no value is provided,\n\t * it will return the product of the first and second inputs\n\t * @example\n\t * var mult = new Tone.Multiply();\n\t * var sigA = new Tone.Signal(3);\n\t * var sigB = new Tone.Signal(4);\n\t * sigA.connect(mult, 0, 0);\n\t * sigB.connect(mult, 0, 1);\n\t * //output of mult is 12.\n\t * @example\n\t * var mult = new Tone.Multiply(10);\n\t * var sig = new Tone.Signal(2).connect(mult);\n\t * //the output of mult is 20. \n\t */\n\tTone.Multiply = function(value){\n\n\t\tthis.createInsOuts(2, 0);\n\n\t\t/**\n\t\t * the input node is the same as the output node\n\t\t * it is also the GainNode which handles the scaling of incoming signal\n\t\t * \n\t\t * @type {GainNode}\n\t\t * @private\n\t\t */\n\t\tthis._mult = this.input[0] = this.output = new Tone.Gain();\n\n\t\t/**\n\t\t * the scaling parameter\n\t\t * @type {AudioParam}\n\t\t * @private\n\t\t */\n\t\tthis._param = this.input[1] = this.output.gain;\n\t\t\n\t\tthis._param.value = this.defaultArg(value, 0);\n\t};\n\n\tTone.extend(Tone.Multiply, Tone.Signal);\n\n\t/**\n\t * clean up\n\t * @returns {Tone.Multiply} this\n\t */\n\tTone.Multiply.prototype.dispose = function(){\n\t\tTone.prototype.dispose.call(this);\n\t\tthis._mult.dispose();\n\t\tthis._mult = null;\n\t\tthis._param = null;\n\t\treturn this;\n\t}; \n\n\treturn Tone.Multiply;\n});\n","'use strict';\ndefine(function (require) {\n\n var p5sound = require('master');\n var CrossFade = require('Tone/component/CrossFade');\n\n /**\n * Effect is a base class for audio effects in p5. \n * This module handles the nodes and methods that are\n * common and useful for current and future effects.\n *\n *\n * This class is extended by p5.Distortion,\n * p5.Compressor,\n * p5.Delay,\n * p5.Filter,\n * p5.Reverb.\n *\n * @class p5.Effect\n * @constructor\n *\n * @param {Object} [ac] Reference to the audio context of the p5 object\n * @param {AudioNode} [input] Gain Node effect wrapper\n * @param {AudioNode} [output] Gain Node effect wrapper\n * @param {Object} [_drywet] Tone.JS CrossFade node (defaults to value: 1)\n * @param {AudioNode} [wet] Effects that extend this class should connect\n * to the wet signal to this gain node, so that dry and wet\n * signals are mixed properly.\n */\n p5.Effect = function() {\n this.ac = p5sound.audiocontext;\n\n this.input = this.ac.createGain();\n this.output = this.ac.createGain();\n\n /**\n *\tThe p5.Effect class is built\n * \tusing Tone.js CrossFade\n * \t@private\n */\n\n this._drywet = new CrossFade(1);\n\n /**\n *\tIn classes that extend\n *\tp5.Effect, connect effect nodes\n *\tto the wet parameter\n */\n this.wet = this.ac.createGain();\n\n this.input.connect(this._drywet.a);\n this.wet.connect(this._drywet.b);\n this._drywet.connect(this.output);\n\n this.connect();\n\n //Add to the soundArray\n p5sound.soundArray.push(this);\n };\n\n /**\n * Set the output volume of the filter.\n *\n * @method amp\n * @for p5.Effect\n * @param {Number} [vol] amplitude between 0 and 1.0\n * @param {Number} [rampTime] create a fade that lasts until rampTime\n * @param {Number} [tFromNow] schedule this event to happen in tFromNow seconds\n */\n p5.Effect.prototype.amp = function(vol, rampTime, tFromNow){\n var rampTime = rampTime || 0;\n var tFromNow = tFromNow || 0;\n var now = p5sound.audiocontext.currentTime;\n var currentVol = this.output.gain.value;\n this.output.gain.cancelScheduledValues(now);\n this.output.gain.linearRampToValueAtTime(currentVol, now + tFromNow + .001);\n this.output.gain.linearRampToValueAtTime(vol, now + tFromNow + rampTime + .001);\n };\n\n /**\n * Link effects together in a chain\n * Example usage: filter.chain(reverb, delay, panner);\n * May be used with an open-ended number of arguments\n *\n * @method chain\n * @for p5.Effect\n * @param {Object} [arguments] Chain together multiple sound objects\n */\n p5.Effect.prototype.chain = function(){\n if (arguments.length>0){\n this.connect(arguments[0]);\n for(var i=1;i\n * var notes = [60, 64, 67, 72];\n * var i = 0;\n *\n * function setup() {\n * osc = new p5.Oscillator('Triangle');\n * osc.start();\n * frameRate(1);\n * }\n *\n * function draw() {\n * var freq = midiToFreq(notes[i]);\n * osc.freq(freq);\n * i++;\n * if (i >= notes.length){\n * i = 0;\n * }\n * }\n * \n */\n var midiToFreq = p5.prototype.midiToFreq = function(m) {\n return 440 * Math.pow(2, (m-69)/12.0);\n };\n\n // This method converts ANSI notes specified as a string \"C4\", \"Eb3\" to a frequency\n var noteToFreq = function(note) {\n if (typeof note !== 'string') {\n return note;\n }\n var wholeNotes = {A:21, B:23, C:24, D:26, E:28, F:29, G:31};\n var value = wholeNotes[ note[0].toUpperCase() ];\n var octave = ~~note.slice(-1);\n value += 12 * (octave -1);\n\n switch(note[1]) {\n case '#':\n value += 1;\n break;\n case 'b':\n value -= 1;\n break;\n default:\n break;\n }\n return midiToFreq(value);\n };\n\n /**\n * List the SoundFile formats that you will include. LoadSound\n * will search your directory for these extensions, and will pick\n * a format that is compatable with the client's web browser.\n * Here is a free online file\n * converter.\n *\n * @method soundFormats\n * @param {String} [...formats] i.e. 'mp3', 'wav', 'ogg'\n * @example\n *
\n * function preload() {\n * // set the global sound formats\n * soundFormats('mp3', 'ogg');\n *\n * // load either beatbox.mp3, or .ogg, depending on browser\n * mySound = loadSound('assets/beatbox.mp3');\n * }\n *\n * function setup() {\n * mySound.play();\n * }\n *
\n */\n p5.prototype.soundFormats = function() {\n // reset extensions array\n p5sound.extensions = [];\n // add extensions\n for (var i = 0; i < arguments.length; i++) {\n arguments[i] = arguments[i].toLowerCase();\n if (['mp3','wav','ogg', 'm4a', 'aac'].indexOf(arguments[i]) > -1) {\n p5sound.extensions.push(arguments[i]);\n } else {\n throw arguments[i] + ' is not a valid sound format!';\n }\n }\n };\n\n p5.prototype.disposeSound = function() {\n for (var i = 0; i < p5sound.soundArray.length; i++) {\n p5sound.soundArray[i].dispose();\n }\n };\n\n // register removeSound to dispose of p5sound SoundFiles, Convolvers,\n // Oscillators etc when sketch ends\n p5.prototype.registerMethod('remove', p5.prototype.disposeSound);\n\n p5.prototype._checkFileFormats = function(paths) {\n var path;\n // if path is a single string, check to see if extension is provided\n if (typeof paths === 'string') {\n path = paths;\n // see if extension is provided\n var extTest = path.split('.').pop();\n // if an extension is provided...\n if (['mp3','wav','ogg', 'm4a', 'aac'].indexOf(extTest) > -1) {\n if (p5.prototype.isFileSupported(extTest)) {\n path = path;\n }\n else {\n var pathSplit = path.split('.');\n var pathCore = pathSplit[pathSplit.length - 1];\n for (var i = 0; i 1) {\n rightChannel = audioBuffer.getChannelData(1);\n } else {\n rightChannel = leftChannel;\n }\n\n var interleaved = interleave(leftChannel, rightChannel);\n\n // create the buffer and view to create the .WAV file\n var buffer = new window.ArrayBuffer(44 + interleaved.length * 2);\n var view = new window.DataView(buffer);\n\n // write the WAV container,\n // check spec at: https://web.archive.org/web/20171215131933/http://tiny.systems/software/soundProgrammer/WavFormatDocs.pdf\n\n // RIFF chunk descriptor\n writeUTFBytes(view, 0, 'RIFF');\n view.setUint32(4, 36 + interleaved.length * 2, true);\n writeUTFBytes(view, 8, 'WAVE');\n // FMT sub-chunk\n writeUTFBytes(view, 12, 'fmt ');\n view.setUint32(16, 16, true);\n view.setUint16(20, 1, true);\n // stereo (2 channels)\n view.setUint16(22, 2, true);\n view.setUint32(24, p5sound.audiocontext.sampleRate, true);\n view.setUint32(28, p5sound.audiocontext.sampleRate * 4, true);\n view.setUint16(32, 4, true);\n view.setUint16(34, 16, true);\n // data sub-chunk\n writeUTFBytes(view, 36, 'data');\n view.setUint32(40, interleaved.length * 2, true);\n\n // write the PCM samples\n var lng = interleaved.length;\n var index = 44;\n var volume = 1;\n for (var i = 0; i < lng; i++) {\n view.setInt16(index, interleaved[i] * (0x7FFF * volume), true);\n index += 2;\n }\n\n return view;\n }\n\n // helper methods to save waves\n function interleave(leftChannel, rightChannel) {\n var length = leftChannel.length + rightChannel.length;\n var result = new Float32Array(length);\n\n var inputIndex = 0;\n\n for (var index = 0; index < length;) {\n result[index++] = leftChannel[inputIndex];\n result[index++] = rightChannel[inputIndex];\n inputIndex++;\n }\n return result;\n }\n\n function writeUTFBytes(view, offset, string) {\n var lng = string.length;\n for (var i = 0; i < lng; i++) {\n view.setUint8(offset + i, string.charCodeAt(i));\n }\n }\n\n return {\n convertToWav: convertToWav,\n midiToFreq: midiToFreq,\n noteToFreq: noteToFreq\n };\n\n});\n","define([\"Tone/core/Tone\", \"Tone/signal/Signal\", \"Tone/core/Gain\"], function(Tone){\n\n\t\"use strict\";\n\n\t/**\n\t * @class Add a signal and a number or two signals. When no value is\n\t * passed into the constructor, Tone.Add will sum input[0]\n\t * and input[1]. If a value is passed into the constructor, \n\t * the it will be added to the input.\n\t * \n\t * @constructor\n\t * @extends {Tone.Signal}\n\t * @param {number=} value If no value is provided, Tone.Add will sum the first\n\t * and second inputs. \n\t * @example\n\t * var signal = new Tone.Signal(2);\n\t * var add = new Tone.Add(2);\n\t * signal.connect(add);\n\t * //the output of add equals 4\n\t * @example\n\t * //if constructed with no arguments\n\t * //it will add the first and second inputs\n\t * var add = new Tone.Add();\n\t * var sig0 = new Tone.Signal(3).connect(add, 0, 0);\n\t * var sig1 = new Tone.Signal(4).connect(add, 0, 1);\n\t * //the output of add equals 7. \n\t */\n\tTone.Add = function(value){\n\n\t\tthis.createInsOuts(2, 0);\n\n\t\t/**\n\t\t * the summing node\n\t\t * @type {GainNode}\n\t\t * @private\n\t\t */\n\t\tthis._sum = this.input[0] = this.input[1] = this.output = new Tone.Gain();\n\n\t\t/**\n\t\t * @private\n\t\t * @type {Tone.Signal}\n\t\t */\n\t\tthis._param = this.input[1] = new Tone.Signal(value);\n\n\t\tthis._param.connect(this._sum);\n\t};\n\n\tTone.extend(Tone.Add, Tone.Signal);\n\t\n\t/**\n\t * Clean up.\n\t * @returns {Tone.Add} this\n\t */\n\tTone.Add.prototype.dispose = function(){\n\t\tTone.prototype.dispose.call(this);\n\t\tthis._sum.dispose();\n\t\tthis._sum = null;\n\t\tthis._param.dispose();\n\t\tthis._param = null;\n\t\treturn this;\n\t}; \n\n\treturn Tone.Add;\n});","define([\"Tone/core/Tone\", \"Tone/type/Time\", \"Tone/type/Frequency\", \"Tone/type/TransportTime\", \"Tone/core/Context\"],\nfunction (Tone) {\t\n\n\t///////////////////////////////////////////////////////////////////////////\n\t//\tTYPES\n\t///////////////////////////////////////////////////////////////////////////\n\n\t/**\n\t * Units which a value can take on.\n\t * @enum {String}\n\t */\n\tTone.Type = {\n\t\t/** \n\t\t * Default units\n\t\t * @typedef {Default}\n\t\t */\n\t\tDefault : \"number\",\n\t\t/**\n\t\t * Time can be described in a number of ways. Read more [Time](https://github.com/Tonejs/Tone.js/wiki/Time).\n\t\t *\n\t\t *
\n\t\t *
Numbers, which will be taken literally as the time (in seconds).
\n\t\t *
Notation, (\"4n\", \"8t\") describes time in BPM and time signature relative values.
\n\t\t *
TransportTime, (\"4:3:2\") will also provide tempo and time signature relative times \n\t\t * in the form BARS:QUARTERS:SIXTEENTHS.
\n\t\t *
Frequency, (\"8hz\") is converted to the length of the cycle in seconds.
\n\t\t *
Now-Relative, (\"+1\") prefix any of the above with \"+\" and it will be interpreted as \n\t\t * \"the current time plus whatever expression follows\".
\n\t\t *
Expressions, (\"3:0 + 2 - (1m / 7)\") any of the above can also be combined \n\t\t * into a mathematical expression which will be evaluated to compute the desired time.
\n\t\t *
No Argument, for methods which accept time, no argument will be interpreted as \n\t\t * \"now\" (i.e. the currentTime).
\n\t\t *
\n\t\t * \n\t\t * @typedef {Time}\n\t\t */\n\t\tTime : \"time\",\n\t\t/**\n\t\t * Frequency can be described similar to time, except ultimately the\n\t\t * values are converted to frequency instead of seconds. A number\n\t\t * is taken literally as the value in hertz. Additionally any of the \n\t\t * Time encodings can be used. Note names in the form\n\t\t * of NOTE OCTAVE (i.e. C4) are also accepted and converted to their\n\t\t * frequency value. \n\t\t * @typedef {Frequency}\n\t\t */\n\t\tFrequency : \"frequency\",\n\t\t/**\n\t\t * TransportTime describes a position along the Transport's timeline. It is\n\t\t * similar to Time in that it uses all the same encodings, but TransportTime specifically\n\t\t * pertains to the Transport's timeline, which is startable, stoppable, loopable, and seekable. \n\t\t * [Read more](https://github.com/Tonejs/Tone.js/wiki/TransportTime)\n\t\t * @typedef {TransportTime}\n\t\t */\n\t\tTransportTime : \"transportTime\",\n\t\t/** \n\t\t * Ticks are the basic subunit of the Transport. They are\n\t\t * the smallest unit of time that the Transport supports.\n\t\t * @typedef {Ticks}\n\t\t */\n\t\tTicks : \"ticks\",\n\t\t/** \n\t\t * Normal values are within the range [0, 1].\n\t\t * @typedef {NormalRange}\n\t\t */\n\t\tNormalRange : \"normalRange\",\n\t\t/** \n\t\t * AudioRange values are between [-1, 1].\n\t\t * @typedef {AudioRange}\n\t\t */\n\t\tAudioRange : \"audioRange\",\n\t\t/** \n\t\t * Decibels are a logarithmic unit of measurement which is useful for volume\n\t\t * because of the logarithmic way that we perceive loudness. 0 decibels \n\t\t * means no change in volume. -10db is approximately half as loud and 10db \n\t\t * is twice is loud. \n\t\t * @typedef {Decibels}\n\t\t */\n\t\tDecibels : \"db\",\n\t\t/** \n\t\t * Half-step note increments, i.e. 12 is an octave above the root. and 1 is a half-step up.\n\t\t * @typedef {Interval}\n\t\t */\n\t\tInterval : \"interval\",\n\t\t/** \n\t\t * Beats per minute. \n\t\t * @typedef {BPM}\n\t\t */\n\t\tBPM : \"bpm\",\n\t\t/** \n\t\t * The value must be greater than or equal to 0.\n\t\t * @typedef {Positive}\n\t\t */\n\t\tPositive : \"positive\",\n\t\t/** \n\t\t * A cent is a hundredth of a semitone. \n\t\t * @typedef {Cents}\n\t\t */\n\t\tCents : \"cents\",\n\t\t/** \n\t\t * Angle between 0 and 360. \n\t\t * @typedef {Degrees}\n\t\t */\n\t\tDegrees : \"degrees\",\n\t\t/** \n\t\t * A number representing a midi note.\n\t\t * @typedef {MIDI}\n\t\t */\n\t\tMIDI : \"midi\",\n\t\t/** \n\t\t * A colon-separated representation of time in the form of\n\t\t * Bars:Beats:Sixteenths. \n\t\t * @typedef {BarsBeatsSixteenths}\n\t\t */\n\t\tBarsBeatsSixteenths : \"barsBeatsSixteenths\",\n\t\t/** \n\t\t * Sampling is the reduction of a continuous signal to a discrete signal.\n\t\t * Audio is typically sampled 44100 times per second. \n\t\t * @typedef {Samples}\n\t\t */\n\t\tSamples : \"samples\",\n\t\t/** \n\t\t * Hertz are a frequency representation defined as one cycle per second.\n\t\t * @typedef {Hertz}\n\t\t */\n\t\tHertz : \"hertz\",\n\t\t/** \n\t\t * A frequency represented by a letter name, \n\t\t * accidental and octave. This system is known as\n\t\t * [Scientific Pitch Notation](https://en.wikipedia.org/wiki/Scientific_pitch_notation).\n\t\t * @typedef {Note}\n\t\t */\n\t\tNote : \"note\",\n\t\t/** \n\t\t * One millisecond is a thousandth of a second. \n\t\t * @typedef {Milliseconds}\n\t\t */\n\t\tMilliseconds : \"milliseconds\",\n\t\t/** \n\t\t * Seconds are the time unit of the AudioContext. In the end, \n\t\t * all values need to be evaluated to seconds. \n\t\t * @typedef {Seconds}\n\t\t */\n\t\tSeconds : \"seconds\",\n\t\t/** \n\t\t * A string representing a duration relative to a measure. \n\t\t *
\n\t\t * \t
\"4n\" = quarter note
\n\t\t * \t
\"2m\" = two measures
\n\t\t * \t
\"8t\" = eighth-note triplet
\n\t\t *
\n\t\t * @typedef {Notation}\n\t\t */\n\t\tNotation : \"notation\",\n\t};\n\n\t///////////////////////////////////////////////////////////////////////////\n\t// AUGMENT TONE's PROTOTYPE\n\t///////////////////////////////////////////////////////////////////////////\n\n\t/**\n\t * Convert Time into seconds.\n\t * \n\t * Unlike the method which it overrides, this takes into account \n\t * transporttime and musical notation.\n\t *\n\t * Time : 1.40\n\t * Notation: 4n|1m|2t\n\t * Now Relative: +3n\n\t * Math: 3n+16n or even complicated expressions ((3n*2)/6 + 1)\n\t *\n\t * @param {Time} time \n\t * @return {Seconds} \n\t */\n\tTone.prototype.toSeconds = function(time){\n\t\tif (this.isNumber(time)){\n\t\t\treturn time;\n\t\t} else if (this.isUndef(time)){\n\t\t\treturn this.now();\t\t\t\n\t\t} else if (this.isString(time)){\n\t\t\treturn (new Tone.Time(time)).toSeconds();\n\t\t} else if (time instanceof Tone.TimeBase){\n\t\t\treturn time.toSeconds();\n\t\t}\n\t};\n\n\t/**\n\t * Convert a frequency representation into a number.\n\t * @param {Frequency} freq \n\t * @return {Hertz} the frequency in hertz\n\t */\n\tTone.prototype.toFrequency = function(freq){\n\t\tif (this.isNumber(freq)){\n\t\t\treturn freq;\n\t\t} else if (this.isString(freq) || this.isUndef(freq)){\n\t\t\treturn (new Tone.Frequency(freq)).valueOf();\n\t\t} else if (freq instanceof Tone.TimeBase){\n\t\t\treturn freq.toFrequency();\n\t\t}\n\t};\n\n\t/**\n\t * Convert a time representation into ticks.\n\t * @param {Time} time\n\t * @return {Ticks} the time in ticks\n\t */\n\tTone.prototype.toTicks = function(time){\n\t\tif (this.isNumber(time) || this.isString(time)){\n\t\t\treturn (new Tone.TransportTime(time)).toTicks();\n\t\t} else if (this.isUndef(time)){\n\t\t\treturn Tone.Transport.ticks;\t\t\t\n\t\t} else if (time instanceof Tone.TimeBase){\n\t\t\treturn time.toTicks();\n\t\t}\n\t};\n\n\treturn Tone;\n});","define([\"Tone/core/Tone\", \"Tone/core/Param\", \"Tone/type/Type\"], function (Tone) {\n\n\t\"use strict\";\n\n\t/**\n\t * createGain shim\n\t * @private\n\t */\n\tif (window.GainNode && !AudioContext.prototype.createGain){\n\t\tAudioContext.prototype.createGain = AudioContext.prototype.createGainNode;\n\t}\n\n\t/**\n\t * @class A thin wrapper around the Native Web Audio GainNode.\n\t * The GainNode is a basic building block of the Web Audio\n\t * API and is useful for routing audio and adjusting gains. \n\t * @extends {Tone}\n\t * @param {Number=} gain The initial gain of the GainNode\n\t * @param {Tone.Type=} units The units of the gain parameter. \n\t */\n\tTone.Gain = function(){\n\n\t\tvar options = this.optionsObject(arguments, [\"gain\", \"units\"], Tone.Gain.defaults);\n\n\t\t/**\n\t\t * The GainNode\n\t\t * @type {GainNode}\n\t\t * @private\n\t\t */\n\t\tthis.input = this.output = this._gainNode = this.context.createGain();\n\n\t\t/**\n\t\t * The gain parameter of the gain node.\n\t\t * @type {Tone.Param}\n\t\t * @signal\n\t\t */\n\t\tthis.gain = new Tone.Param({\n\t\t\t\"param\" : this._gainNode.gain, \n\t\t\t\"units\" : options.units,\n\t\t\t\"value\" : options.gain,\n\t\t\t\"convert\" : options.convert\n\t\t});\n\t\tthis._readOnly(\"gain\");\n\t};\n\n\tTone.extend(Tone.Gain);\n\n\t/**\n\t * The defaults\n\t * @const\n\t * @type {Object}\n\t */\n\tTone.Gain.defaults = {\n\t\t\"gain\" : 1,\n\t\t\"convert\" : true,\n\t};\n\n\t/**\n\t * Clean up.\n\t * @return {Tone.Gain} this\n\t */\n\tTone.Gain.prototype.dispose = function(){\n\t\tTone.Param.prototype.dispose.call(this);\n\t\tthis._gainNode.disconnect();\n\t\tthis._gainNode = null;\n\t\tthis._writable(\"gain\");\n\t\tthis.gain.dispose();\n\t\tthis.gain = null;\n\t};\n\n\t//STATIC///////////////////////////////////////////////////////////////////\n\n\t/**\n\t * Create input and outputs for this object.\n\t * @param {Number} input The number of inputs\n\t * @param {Number=} outputs The number of outputs\n\t * @return {Tone} this\n\t * @internal\n\t */\n\tTone.prototype.createInsOuts = function(inputs, outputs){\n\n\t\tif (inputs === 1){\n\t\t\tthis.input = new Tone.Gain();\n\t\t} else if (inputs > 1){\n\t\t\tthis.input = new Array(inputs);\n\t\t}\n\n\t\tif (outputs === 1){\n\t\t\tthis.output = new Tone.Gain();\n\t\t} else if (outputs > 1){\n\t\t\tthis.output = new Array(inputs);\n\t\t}\n\t};\n\n\t///////////////////////////////////////////////////////////////////////////\n\n\treturn Tone.Gain;\n});","'use strict';\n\ndefine(function () {\n /*\n Helper function to generate an error\n with a custom stack trace that points to the sketch\n and removes other parts of the stack trace.\n\n @private\n @class customError\n @constructor\n @param {String} name custom error name\n @param {String} errorTrace custom error trace\n @param {String} failedPath path to the file that failed to load\n @property {String} name custom error name\n @property {String} message custom error message\n @property {String} stack trace the error back to a line in the user's sketch.\n Note: this edits out stack trace within p5.js and p5.sound.\n @property {String} originalStack unedited, original stack trace\n @property {String} failedPath path to the file that failed to load\n @return {Error} returns a custom Error object\n */\n var CustomError = function(name, errorTrace, failedPath) {\n var err = new Error();\n var tempStack, splitStack;\n\n err.name = name;\n err.originalStack = err.stack + errorTrace;\n tempStack = err.stack + errorTrace;\n err.failedPath = failedPath;\n\n // only print the part of the stack trace that refers to the user code:\n var splitStack = tempStack.split('\\n');\n splitStack = splitStack.filter(function(ln) {\n return !ln.match(/(p5.|native code|globalInit)/g);\n });\n err.stack = splitStack.join('\\n');\n\n return err; // TODO: is this really a constructor?\n };\n\n return CustomError;\n});\n","define([\"Tone/core/Tone\", \"Tone/core/Emitter\"], function (Tone) {\n\n\t/**\n\t * shim\n\t * @private\n\t */\n\tif (!window.hasOwnProperty(\"AudioContext\") && window.hasOwnProperty(\"webkitAudioContext\")){\n\t\twindow.AudioContext = window.webkitAudioContext;\n\t}\n\n\t/**\n\t * @class Wrapper around the native AudioContext.\n\t * @extends {Tone.Emitter}\n\t * @param {AudioContext=} context optionally pass in a context\n\t */\n\tTone.Context = function(context){\n\n\t\tTone.Emitter.call(this);\n\n\t\tif (!context){\n\t\t\tcontext = new window.AudioContext();\n\t\t}\n\t\tthis._context = context;\n\t\t// extend all of the methods\n\t\tfor (var prop in this._context){\n\t\t\tthis._defineProperty(this._context, prop);\n\t\t}\n\n\t\t///////////////////////////////////////////////////////////////////////\n\t\t// WORKER\n\t\t///////////////////////////////////////////////////////////////////////\n\n\t\t/**\n\t\t * The default latency hint\n\t\t * @type {String}\n\t\t * @private\n\t\t */\n\t\tthis._latencyHint = \"interactive\";\n\n\t\t/**\n\t\t * The amount of time events are scheduled\n\t\t * into the future\n\t\t * @type {Number}\n\t\t * @private\n\t\t */\n\t\tthis._lookAhead = 0.1;\n\n\t\t/**\n\t\t * How often the update look runs\n\t\t * @type {Number}\n\t\t * @private\n\t\t */\n\t\tthis._updateInterval = this._lookAhead/3;\n\n\t\t/**\n\t\t * A reference to the actual computed update interval\n\t\t * @type {Number}\n\t\t * @private\n\t\t */\n\t\tthis._computedUpdateInterval = 0;\n\n\t\t/**\n\t\t * The web worker which is used to update Tone.Clock\n\t\t * @private\n\t\t * @type {WebWorker}\n\t\t */\n\t\tthis._worker = this._createWorker();\n\n\t\t/**\n\t\t * An object containing all of the constants AudioBufferSourceNodes\n\t\t * @type {Object}\n\t\t * @private\n\t\t */\n\t\tthis._constants = {};\n\n\t};\n\n\tTone.extend(Tone.Context, Tone.Emitter);\n\tTone.Emitter.mixin(Tone.Context);\n\n\t/**\n\t * Define a property on this Tone.Context. \n\t * This is used to extend the native AudioContext\n\t * @param {AudioContext} context\n\t * @param {String} prop \n\t * @private\n\t */\n\tTone.Context.prototype._defineProperty = function(context, prop){\n\t\tif (this.isUndef(this[prop])){\n\t\t\tObject.defineProperty(this, prop, {\n\t\t\t\tget : function(){\n\t\t\t\t\tif (typeof context[prop] === \"function\"){\n\t\t\t\t\t\treturn context[prop].bind(context);\n\t\t\t\t\t} else {\n\t\t\t\t\t\treturn context[prop];\n\t\t\t\t\t}\n\t\t\t\t},\n\t\t\t\tset : function(val){\n\t\t\t\t\tcontext[prop] = val;\n\t\t\t\t}\n\t\t\t});\n\t\t}\n\t};\n\n\t/**\n\t * The current audio context time\n\t * @return {Number}\n\t */\n\tTone.Context.prototype.now = function(){\n\t\treturn this._context.currentTime;\n\t};\n\n\t/**\n\t * Generate a web worker\n\t * @return {WebWorker}\n\t * @private\n\t */\n\tTone.Context.prototype._createWorker = function(){\n\t\t\n\t\t//URL Shim\n\t\twindow.URL = window.URL || window.webkitURL;\n\n\t\tvar blob = new Blob([\n\t\t\t//the initial timeout time\n\t\t\t\"var timeoutTime = \"+(this._updateInterval * 1000).toFixed(1)+\";\" +\n\t\t\t//onmessage callback\n\t\t\t\"self.onmessage = function(msg){\" +\n\t\t\t\"\ttimeoutTime = parseInt(msg.data);\" + \n\t\t\t\"};\" + \n\t\t\t//the tick function which posts a message\n\t\t\t//and schedules a new tick\n\t\t\t\"function tick(){\" +\n\t\t\t\"\tsetTimeout(tick, timeoutTime);\" +\n\t\t\t\"\tself.postMessage('tick');\" +\n\t\t\t\"}\" +\n\t\t\t//call tick initially\n\t\t\t\"tick();\"\n\t\t]);\n\t\tvar blobUrl = URL.createObjectURL(blob);\n\t\tvar worker = new Worker(blobUrl);\n\n\t\tworker.addEventListener(\"message\", function(){\n\t\t\t// tick the clock\n\t\t\tthis.emit(\"tick\");\n\t\t}.bind(this));\n\n\t\t//lag compensation\n\t\tworker.addEventListener(\"message\", function(){\n\t\t\tvar now = this.now();\n\t\t\tif (this.isNumber(this._lastUpdate)){\n\t\t\t\tvar diff = now - this._lastUpdate;\n\t\t\t\tthis._computedUpdateInterval = Math.max(diff, this._computedUpdateInterval * 0.97);\n\t\t\t}\n\t\t\tthis._lastUpdate = now;\n\t\t}.bind(this));\n\n\t\treturn worker;\n\t};\n\n\t/**\n\t * Generate a looped buffer at some constant value.\n\t * @param {Number} val\n\t * @return {BufferSourceNode}\n\t */\n\tTone.Context.prototype.getConstant = function(val){\n\t\tif (this._constants[val]){\n\t\t\treturn this._constants[val];\n\t\t} else {\n\t\t\tvar buffer = this._context.createBuffer(1, 128, this._context.sampleRate);\n\t\t\tvar arr = buffer.getChannelData(0);\n\t\t\tfor (var i = 0; i < arr.length; i++){\n\t\t\t\tarr[i] = val;\n\t\t\t}\n\t\t\tvar constant = this._context.createBufferSource();\n\t\t\tconstant.channelCount = 1;\n\t\t\tconstant.channelCountMode = \"explicit\";\n\t\t\tconstant.buffer = buffer;\n\t\t\tconstant.loop = true;\n\t\t\tconstant.start(0);\n\t\t\tthis._constants[val] = constant;\n\t\t\treturn constant;\n\t\t}\n\t};\n\n\t/**\n\t * This is the time that the clock is falling behind\n\t * the scheduled update interval. The Context automatically\n\t * adjusts for the lag and schedules further in advance.\n\t * @type {Number}\n\t * @memberOf Tone.Context\n\t * @name lag\n\t * @static\n\t * @readOnly\n\t */\n\tObject.defineProperty(Tone.Context.prototype, \"lag\", {\n\t\tget : function(){\n\t\t\tvar diff = this._computedUpdateInterval - this._updateInterval;\n\t\t\tdiff = Math.max(diff, 0);\n\t\t\treturn diff;\n\t\t}\n\t});\n\n\t/**\n\t * The amount of time in advance that events are scheduled.\n\t * The lookAhead will adjust slightly in response to the \n\t * measured update time to try to avoid clicks.\n\t * @type {Number}\n\t * @memberOf Tone.Context\n\t * @name lookAhead\n\t * @static\n\t */\n\tObject.defineProperty(Tone.Context.prototype, \"lookAhead\", {\n\t\tget : function(){\n\t\t\treturn this._lookAhead;\n\t\t},\n\t\tset : function(lA){\n\t\t\tthis._lookAhead = lA;\n\t\t}\n\t});\n\n\t/**\n\t * How often the Web Worker callback is invoked.\n\t * This number corresponds to how responsive the scheduling\n\t * can be. Context.updateInterval + Context.lookAhead gives you the\n\t * total latency between scheduling an event and hearing it.\n\t * @type {Number}\n\t * @memberOf Tone.Context\n\t * @name updateInterval\n\t * @static\n\t */\n\tObject.defineProperty(Tone.Context.prototype, \"updateInterval\", {\n\t\tget : function(){\n\t\t\treturn this._updateInterval;\n\t\t},\n\t\tset : function(interval){\n\t\t\tthis._updateInterval = Math.max(interval, Tone.prototype.blockTime);\n\t\t\tthis._worker.postMessage(Math.max(interval * 1000, 1));\n\t\t}\n\t});\n\n\t/**\n\t * The type of playback, which affects tradeoffs between audio \n\t * output latency and responsiveness. \n\t * \n\t * In addition to setting the value in seconds, the latencyHint also\n\t * accepts the strings \"interactive\" (prioritizes low latency), \n\t * \"playback\" (prioritizes sustained playback), \"balanced\" (balances\n\t * latency and performance), and \"fastest\" (lowest latency, might glitch more often). \n\t * @type {String|Seconds}\n\t * @memberOf Tone.Context#\n\t * @name latencyHint\n\t * @static\n\t * @example\n\t * //set the lookAhead to 0.3 seconds\n\t * Tone.context.latencyHint = 0.3;\n\t */\n\tObject.defineProperty(Tone.Context.prototype, \"latencyHint\", {\n\t\tget : function(){\n\t\t\treturn this._latencyHint;\n\t\t},\n\t\tset : function(hint){\n\t\t\tvar lookAhead = hint;\n\t\t\tthis._latencyHint = hint;\n\t\t\tif (this.isString(hint)){\n\t\t\t\tswitch(hint){\n\t\t\t\t\tcase \"interactive\" :\n\t\t\t\t\t\tlookAhead = 0.1;\n\t\t\t\t\t\tthis._context.latencyHint = hint;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase \"playback\" :\n\t\t\t\t\t\tlookAhead = 0.8;\n\t\t\t\t\t\tthis._context.latencyHint = hint;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase \"balanced\" :\n\t\t\t\t\t\tlookAhead = 0.25;\n\t\t\t\t\t\tthis._context.latencyHint = hint;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase \"fastest\" :\n\t\t\t\t\t\tlookAhead = 0.01;\n\t\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t\tthis.lookAhead = lookAhead;\n\t\t\tthis.updateInterval = lookAhead/3;\n\t\t}\n\t});\n\n\t/**\n\t * Shim all connect/disconnect and some deprecated methods which are still in\n\t * some older implementations.\n\t * @private\n\t */\n\tfunction shimConnect(){\n\n\t\tvar nativeConnect = AudioNode.prototype.connect;\n\t\tvar nativeDisconnect = AudioNode.prototype.disconnect;\n\n\t\t//replace the old connect method\n\t\tfunction toneConnect(B, outNum, inNum){\n\t\t\tif (B.input){\n\t\t\t\tif (Array.isArray(B.input)){\n\t\t\t\t\tif (Tone.prototype.isUndef(inNum)){\n\t\t\t\t\t\tinNum = 0;\n\t\t\t\t\t}\n\t\t\t\t\tthis.connect(B.input[inNum]);\n\t\t\t\t} else {\n\t\t\t\t\tthis.connect(B.input, outNum, inNum);\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\ttry {\n\t\t\t\t\tif (B instanceof AudioNode){\n\t\t\t\t\t\tnativeConnect.call(this, B, outNum, inNum);\n\t\t\t\t\t} else {\n\t\t\t\t\t\tnativeConnect.call(this, B, outNum);\n\t\t\t\t\t}\n\t\t\t\t} catch (e) {\n\t\t\t\t\tthrow new Error(\"error connecting to node: \"+B+\"\\n\"+e);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t//replace the old disconnect method\n\t\tfunction toneDisconnect(B, outNum, inNum){\n\t\t\tif (B && B.input && Array.isArray(B.input)){\n\t\t\t\tif (Tone.prototype.isUndef(inNum)){\n\t\t\t\t\tinNum = 0;\n\t\t\t\t}\n\t\t\t\tthis.disconnect(B.input[inNum], outNum, inNum);\n\t\t\t} else if (B && B.input){\n\t\t\t\tthis.disconnect(B.input, outNum, inNum);\n\t\t\t} else {\n\t\t\t\ttry {\n\t\t\t\t\tnativeDisconnect.apply(this, arguments);\n\t\t\t\t} catch (e) {\n\t\t\t\t\tthrow new Error(\"error disconnecting node: \"+B+\"\\n\"+e);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tif (AudioNode.prototype.connect !== toneConnect){\n\t\t\tAudioNode.prototype.connect = toneConnect;\n\t\t\tAudioNode.prototype.disconnect = toneDisconnect;\n\t\t}\n\t}\n\n\t// set the audio context initially\n\tif (Tone.supported){\n\t\tshimConnect();\n\t\tTone.context = new Tone.Context();\n\t} else {\n\t\tconsole.warn(\"This browser does not support Tone.js\");\n\t}\n\n\treturn Tone.Context;\n});","module.exports = {\n recorderProcessor: 'recorder-processor',\n soundFileProcessor: 'sound-file-processor',\n amplitudeProcessor: 'amplitude-processor'\n};\n","define([\"Tone/core/Tone\", \"Tone/signal/Add\", \"Tone/signal/Multiply\", \"Tone/signal/Signal\"], function(Tone){\n\n\t\"use strict\";\n\t\n\t/**\n\t * @class Performs a linear scaling on an input signal.\n\t * Scales a NormalRange input to between\n\t * outputMin and outputMax.\n\t *\n\t * @constructor\n\t * @extends {Tone.SignalBase}\n\t * @param {number} [outputMin=0] The output value when the input is 0. \n\t * @param {number} [outputMax=1]\tThe output value when the input is 1. \n\t * @example\n\t * var scale = new Tone.Scale(50, 100);\n\t * var signal = new Tone.Signal(0.5).connect(scale);\n\t * //the output of scale equals 75\n\t */\n\tTone.Scale = function(outputMin, outputMax){\n\n\t\t/** \n\t\t * @private\n\t\t * @type {number}\n\t\t */\n\t\tthis._outputMin = this.defaultArg(outputMin, 0);\n\n\t\t/** \n\t\t * @private\n\t\t * @type {number}\n\t\t */\n\t\tthis._outputMax = this.defaultArg(outputMax, 1);\n\n\n\t\t/** \n\t\t * @private\n\t\t * @type {Tone.Multiply}\n\t\t * @private\n\t\t */\n\t\tthis._scale = this.input = new Tone.Multiply(1);\n\t\t\n\t\t/** \n\t\t * @private\n\t\t * @type {Tone.Add}\n\t\t * @private\n\t\t */\n\t\tthis._add = this.output = new Tone.Add(0);\n\n\t\tthis._scale.connect(this._add);\n\t\tthis._setRange();\n\t};\n\n\tTone.extend(Tone.Scale, Tone.SignalBase);\n\n\t/**\n\t * The minimum output value. This number is output when \n\t * the value input value is 0. \n\t * @memberOf Tone.Scale#\n\t * @type {number}\n\t * @name min\n\t */\n\tObject.defineProperty(Tone.Scale.prototype, \"min\", {\n\t\tget : function(){\n\t\t\treturn this._outputMin;\n\t\t},\n\t\tset : function(min){\n\t\t\tthis._outputMin = min;\n\t\t\tthis._setRange();\n\t\t}\n\t});\n\n\t/**\n\t * The maximum output value. This number is output when \n\t * the value input value is 1. \n\t * @memberOf Tone.Scale#\n\t * @type {number}\n\t * @name max\n\t */\n\tObject.defineProperty(Tone.Scale.prototype, \"max\", {\n\t\tget : function(){\n\t\t\treturn this._outputMax;\n\t\t},\n\t\tset : function(max){\n\t\t\tthis._outputMax = max;\n\t\t\tthis._setRange();\n\t\t}\n\t});\n\n\t/**\n\t * set the values\n\t * @private\n\t */\n\tTone.Scale.prototype._setRange = function() {\n\t\tthis._add.value = this._outputMin;\n\t\tthis._scale.value = this._outputMax - this._outputMin;\n\t};\n\n\t/**\n\t * Clean up.\n\t * @returns {Tone.Scale} this\n\t */\n\tTone.Scale.prototype.dispose = function(){\n\t\tTone.prototype.dispose.call(this);\n\t\tthis._add.dispose();\n\t\tthis._add = null;\n\t\tthis._scale.dispose();\n\t\tthis._scale = null;\n\t\treturn this;\n\t}; \n\n\treturn Tone.Scale;\n});\n","define([\"Tone/core/Tone\", \"Tone/signal/Signal\", \"Tone/core/Timeline\"], function (Tone) {\n\n\t\"use strict\";\n\n\t/**\n\t * @class A signal which adds the method getValueAtTime. \n\t * Code and inspiration from https://github.com/jsantell/web-audio-automation-timeline\n\t * @extends {Tone.Param}\n\t * @param {Number=} value The initial value of the signal\n\t * @param {String=} units The conversion units of the signal.\n\t */\n\tTone.TimelineSignal = function(){\n\n\t\tvar options = this.optionsObject(arguments, [\"value\", \"units\"], Tone.Signal.defaults);\n\t\t\n\t\t/**\n\t\t * The scheduled events\n\t\t * @type {Tone.Timeline}\n\t\t * @private\n\t\t */\n\t\tthis._events = new Tone.Timeline(10);\n\n\t\t//constructors\n\t\tTone.Signal.apply(this, options);\n\t\toptions.param = this._param;\n\t\tTone.Param.call(this, options);\n\n\t\t/**\n\t\t * The initial scheduled value\n\t\t * @type {Number}\n\t\t * @private\n\t\t */\n\t\tthis._initial = this._fromUnits(this._param.value);\n\t};\n\n\tTone.extend(Tone.TimelineSignal, Tone.Param);\n\n\t/**\n\t * The event types of a schedulable signal.\n\t * @enum {String}\n\t * @private\n\t */\n\tTone.TimelineSignal.Type = {\n\t\tLinear : \"linear\",\n\t\tExponential : \"exponential\",\n\t\tTarget : \"target\",\n\t\tCurve : \"curve\",\n\t\tSet : \"set\"\n\t};\n\n\t/**\n\t * The current value of the signal. \n\t * @memberOf Tone.TimelineSignal#\n\t * @type {Number}\n\t * @name value\n\t */\n\tObject.defineProperty(Tone.TimelineSignal.prototype, \"value\", {\n\t\tget : function(){\n\t\t\tvar now = this.now();\n\t\t\tvar val = this.getValueAtTime(now);\n\t\t\treturn this._toUnits(val);\n\t\t},\n\t\tset : function(value){\n\t\t\tvar convertedVal = this._fromUnits(value);\n\t\t\tthis._initial = convertedVal;\n\t\t\tthis.cancelScheduledValues();\n\t\t\tthis._param.value = convertedVal;\n\t\t}\n\t});\n\n\t///////////////////////////////////////////////////////////////////////////\n\t//\tSCHEDULING\n\t///////////////////////////////////////////////////////////////////////////\n\n\t/**\n\t * Schedules a parameter value change at the given time.\n\t * @param {*}\tvalue The value to set the signal.\n\t * @param {Time} time The time when the change should occur.\n\t * @returns {Tone.TimelineSignal} this\n\t * @example\n\t * //set the frequency to \"G4\" in exactly 1 second from now. \n\t * freq.setValueAtTime(\"G4\", \"+1\");\n\t */\n\tTone.TimelineSignal.prototype.setValueAtTime = function (value, startTime) {\n\t\tvalue = this._fromUnits(value);\n\t\tstartTime = this.toSeconds(startTime);\n\t\tthis._events.add({\n\t\t\t\"type\" : Tone.TimelineSignal.Type.Set,\n\t\t\t\"value\" : value,\n\t\t\t\"time\" : startTime\n\t\t});\n\t\t//invoke the original event\n\t\tthis._param.setValueAtTime(value, startTime);\n\t\treturn this;\n\t};\n\n\t/**\n\t * Schedules a linear continuous change in parameter value from the \n\t * previous scheduled parameter value to the given value.\n\t * \n\t * @param {number} value \n\t * @param {Time} endTime \n\t * @returns {Tone.TimelineSignal} this\n\t */\n\tTone.TimelineSignal.prototype.linearRampToValueAtTime = function (value, endTime) {\n\t\tvalue = this._fromUnits(value);\n\t\tendTime = this.toSeconds(endTime);\n\t\tthis._events.add({\n\t\t\t\"type\" : Tone.TimelineSignal.Type.Linear,\n\t\t\t\"value\" : value,\n\t\t\t\"time\" : endTime\n\t\t});\n\t\tthis._param.linearRampToValueAtTime(value, endTime);\n\t\treturn this;\n\t};\n\n\t/**\n\t * Schedules an exponential continuous change in parameter value from \n\t * the previous scheduled parameter value to the given value.\n\t * \n\t * @param {number} value \n\t * @param {Time} endTime \n\t * @returns {Tone.TimelineSignal} this\n\t */\n\tTone.TimelineSignal.prototype.exponentialRampToValueAtTime = function (value, endTime) {\n\t\t//get the previous event and make sure it's not starting from 0\n\t\tendTime = this.toSeconds(endTime);\n\t\tvar beforeEvent = this._searchBefore(endTime);\n\t\tif (beforeEvent && beforeEvent.value === 0){\n\t\t\t//reschedule that event\n\t\t\tthis.setValueAtTime(this._minOutput, beforeEvent.time);\n\t\t}\n\t\tvalue = this._fromUnits(value);\n\t\tvar setValue = Math.max(value, this._minOutput);\n\t\tthis._events.add({\n\t\t\t\"type\" : Tone.TimelineSignal.Type.Exponential,\n\t\t\t\"value\" : setValue,\n\t\t\t\"time\" : endTime\n\t\t});\n\t\t//if the ramped to value is 0, make it go to the min output, and then set to 0.\n\t\tif (value < this._minOutput){\n\t\t\tthis._param.exponentialRampToValueAtTime(this._minOutput, endTime - this.sampleTime);\n\t\t\tthis.setValueAtTime(0, endTime);\n\t\t} else {\n\t\t\tthis._param.exponentialRampToValueAtTime(value, endTime);\n\t\t}\n\t\treturn this;\n\t};\n\n\t/**\n\t * Start exponentially approaching the target value at the given time with\n\t * a rate having the given time constant.\n\t * @param {number} value \n\t * @param {Time} startTime \n\t * @param {number} timeConstant \n\t * @returns {Tone.TimelineSignal} this \n\t */\n\tTone.TimelineSignal.prototype.setTargetAtTime = function (value, startTime, timeConstant) {\n\t\tvalue = this._fromUnits(value);\n\t\tvalue = Math.max(this._minOutput, value);\n\t\ttimeConstant = Math.max(this._minOutput, timeConstant);\n\t\tstartTime = this.toSeconds(startTime);\n\t\tthis._events.add({\n\t\t\t\"type\" : Tone.TimelineSignal.Type.Target,\n\t\t\t\"value\" : value,\n\t\t\t\"time\" : startTime,\n\t\t\t\"constant\" : timeConstant\n\t\t});\n\t\tthis._param.setTargetAtTime(value, startTime, timeConstant);\n\t\treturn this;\n\t};\n\n\t/**\n\t * Set an array of arbitrary values starting at the given time for the given duration.\n\t * @param {Float32Array} values \n\t * @param {Time} startTime \n\t * @param {Time} duration\n\t * @param {NormalRange} [scaling=1] If the values in the curve should be scaled by some value\n\t * @returns {Tone.TimelineSignal} this \n\t */\n\tTone.TimelineSignal.prototype.setValueCurveAtTime = function (values, startTime, duration, scaling) {\n\t\tscaling = this.defaultArg(scaling, 1);\n\t\t//copy the array\n\t\tvar floats = new Array(values.length);\n\t\tfor (var i = 0; i < floats.length; i++){\n\t\t\tfloats[i] = this._fromUnits(values[i]) * scaling;\n\t\t}\n\t\tstartTime = this.toSeconds(startTime);\n\t\tduration = this.toSeconds(duration);\n\t\tthis._events.add({\n\t\t\t\"type\" : Tone.TimelineSignal.Type.Curve,\n\t\t\t\"value\" : floats,\n\t\t\t\"time\" : startTime,\n\t\t\t\"duration\" : duration\n\t\t});\n\t\t//set the first value\n\t\tthis._param.setValueAtTime(floats[0], startTime);\n\t\t//schedule a lienar ramp for each of the segments\n\t\tfor (var j = 1; j < floats.length; j++){\n\t\t\tvar segmentTime = startTime + (j / (floats.length - 1) * duration);\n\t\t\tthis._param.linearRampToValueAtTime(floats[j], segmentTime);\n\t\t}\n\t\treturn this;\n\t};\n\n\t/**\n\t * Cancels all scheduled parameter changes with times greater than or \n\t * equal to startTime.\n\t * \n\t * @param {Time} startTime\n\t * @returns {Tone.TimelineSignal} this\n\t */\n\tTone.TimelineSignal.prototype.cancelScheduledValues = function (after) {\n\t\tafter = this.toSeconds(after);\n\t\tthis._events.cancel(after);\n\t\tthis._param.cancelScheduledValues(after);\n\t\treturn this;\n\t};\n\n\t/**\n\t * Sets the computed value at the given time. This provides\n\t * a point from which a linear or exponential curve\n\t * can be scheduled after. Will cancel events after \n\t * the given time and shorten the currently scheduled\n\t * linear or exponential ramp so that it ends at `time` .\n\t * This is to avoid discontinuities and clicks in envelopes. \n\t * @param {Time} time When to set the ramp point\n\t * @returns {Tone.TimelineSignal} this\n\t */\n\tTone.TimelineSignal.prototype.setRampPoint = function (time) {\n\t\ttime = this.toSeconds(time);\n\t\t//get the value at the given time\n\t\tvar val = this._toUnits(this.getValueAtTime(time));\n\t\t//if there is an event at the given time\n\t\t//and that even is not a \"set\"\n\t\tvar before = this._searchBefore(time);\n\t\tif (before && before.time === time){\n\t\t\t//remove everything after\n\t\t\tthis.cancelScheduledValues(time + this.sampleTime);\n\t\t} else if (before && \n\t\t\t\t before.type === Tone.TimelineSignal.Type.Curve &&\n\t\t\t\t before.time + before.duration > time){\n\t\t\t//if the curve is still playing\n\t\t\t//cancel the curve\n\t\t\tthis.cancelScheduledValues(time);\n\t\t\tthis.linearRampToValueAtTime(val, time);\n\t\t} else {\n\t\t\t//reschedule the next event to end at the given time\n\t\t\tvar after = this._searchAfter(time);\n\t\t\tif (after){\n\t\t\t\t//cancel the next event(s)\n\t\t\t\tthis.cancelScheduledValues(time);\n\t\t\t\tif (after.type === Tone.TimelineSignal.Type.Linear){\n\t\t\t\t\tthis.linearRampToValueAtTime(val, time);\n\t\t\t\t} else if (after.type === Tone.TimelineSignal.Type.Exponential){\n\t\t\t\t\tthis.exponentialRampToValueAtTime(val, time);\n\t\t\t\t}\n\t\t\t}\n\t\t\tthis.setValueAtTime(val, time);\n\t\t}\n\t\treturn this;\n\t};\n\n\t/**\n\t * Do a linear ramp to the given value between the start and finish times.\n\t * @param {Number} value The value to ramp to.\n\t * @param {Time} start The beginning anchor point to do the linear ramp\n\t * @param {Time} finish The ending anchor point by which the value of\n\t * the signal will equal the given value.\n\t * @returns {Tone.TimelineSignal} this\n\t */\n\tTone.TimelineSignal.prototype.linearRampToValueBetween = function (value, start, finish) {\n\t\tthis.setRampPoint(start);\n\t\tthis.linearRampToValueAtTime(value, finish);\n\t\treturn this;\n\t};\n\n\t/**\n\t * Do a exponential ramp to the given value between the start and finish times.\n\t * @param {Number} value The value to ramp to.\n\t * @param {Time} start The beginning anchor point to do the exponential ramp\n\t * @param {Time} finish The ending anchor point by which the value of\n\t * the signal will equal the given value.\n\t * @returns {Tone.TimelineSignal} this\n\t */\n\tTone.TimelineSignal.prototype.exponentialRampToValueBetween = function (value, start, finish) {\n\t\tthis.setRampPoint(start);\n\t\tthis.exponentialRampToValueAtTime(value, finish);\n\t\treturn this;\n\t};\n\n\t///////////////////////////////////////////////////////////////////////////\n\t//\tGETTING SCHEDULED VALUES\n\t///////////////////////////////////////////////////////////////////////////\n\n\t/**\n\t * Returns the value before or equal to the given time\n\t * @param {Number} time The time to query\n\t * @return {Object} The event at or before the given time.\n\t * @private\n\t */\n\tTone.TimelineSignal.prototype._searchBefore = function(time){\n\t\treturn this._events.get(time);\n\t};\n\n\t/**\n\t * The event after the given time\n\t * @param {Number} time The time to query.\n\t * @return {Object} The next event after the given time\n\t * @private\n\t */\n\tTone.TimelineSignal.prototype._searchAfter = function(time){\n\t\treturn this._events.getAfter(time);\n\t};\n\n\t/**\n\t * Get the scheduled value at the given time. This will\n\t * return the unconverted (raw) value.\n\t * @param {Number} time The time in seconds.\n\t * @return {Number} The scheduled value at the given time.\n\t */\n\tTone.TimelineSignal.prototype.getValueAtTime = function(time){\n\t\ttime = this.toSeconds(time);\n\t\tvar after = this._searchAfter(time);\n\t\tvar before = this._searchBefore(time);\n\t\tvar value = this._initial;\n\t\t//if it was set by\n\t\tif (before === null){\n\t\t\tvalue = this._initial;\n\t\t} else if (before.type === Tone.TimelineSignal.Type.Target){\n\t\t\tvar previous = this._events.getBefore(before.time);\n\t\t\tvar previouVal;\n\t\t\tif (previous === null){\n\t\t\t\tpreviouVal = this._initial;\n\t\t\t} else {\n\t\t\t\tpreviouVal = previous.value;\n\t\t\t}\n\t\t\tvalue = this._exponentialApproach(before.time, previouVal, before.value, before.constant, time);\n\t\t} else if (before.type === Tone.TimelineSignal.Type.Curve){\n\t\t\tvalue = this._curveInterpolate(before.time, before.value, before.duration, time);\n\t\t} else if (after === null){\n\t\t\tvalue = before.value;\n\t\t} else if (after.type === Tone.TimelineSignal.Type.Linear){\n\t\t\tvalue = this._linearInterpolate(before.time, before.value, after.time, after.value, time);\n\t\t} else if (after.type === Tone.TimelineSignal.Type.Exponential){\n\t\t\tvalue = this._exponentialInterpolate(before.time, before.value, after.time, after.value, time);\n\t\t} else {\n\t\t\tvalue = before.value;\n\t\t}\n\t\treturn value;\n\t};\n\n\t/**\n\t * When signals connect to other signals or AudioParams, \n\t * they take over the output value of that signal or AudioParam. \n\t * For all other nodes, the behavior is the same as a default connect. \n\t *\n\t * @override\n\t * @param {AudioParam|AudioNode|Tone.Signal|Tone} node \n\t * @param {number} [outputNumber=0] The output number to connect from.\n\t * @param {number} [inputNumber=0] The input number to connect to.\n\t * @returns {Tone.TimelineSignal} this\n\t * @method\n\t */\n\tTone.TimelineSignal.prototype.connect = Tone.SignalBase.prototype.connect;\n\n\n\t///////////////////////////////////////////////////////////////////////////\n\t//\tAUTOMATION CURVE CALCULATIONS\n\t//\tMIT License, copyright (c) 2014 Jordan Santell\n\t///////////////////////////////////////////////////////////////////////////\n\n\t/**\n\t * Calculates the the value along the curve produced by setTargetAtTime\n\t * @private\n\t */\n\tTone.TimelineSignal.prototype._exponentialApproach = function (t0, v0, v1, timeConstant, t) {\n\t\treturn v1 + (v0 - v1) * Math.exp(-(t - t0) / timeConstant);\n\t};\n\n\t/**\n\t * Calculates the the value along the curve produced by linearRampToValueAtTime\n\t * @private\n\t */\n\tTone.TimelineSignal.prototype._linearInterpolate = function (t0, v0, t1, v1, t) {\n\t\treturn v0 + (v1 - v0) * ((t - t0) / (t1 - t0));\n\t};\n\n\t/**\n\t * Calculates the the value along the curve produced by exponentialRampToValueAtTime\n\t * @private\n\t */\n\tTone.TimelineSignal.prototype._exponentialInterpolate = function (t0, v0, t1, v1, t) {\n\t\tv0 = Math.max(this._minOutput, v0);\n\t\treturn v0 * Math.pow(v1 / v0, (t - t0) / (t1 - t0));\n\t};\n\n\t/**\n\t * Calculates the the value along the curve produced by setValueCurveAtTime\n\t * @private\n\t */\n\tTone.TimelineSignal.prototype._curveInterpolate = function (start, curve, duration, time) {\n\t\tvar len = curve.length;\n\t\t// If time is after duration, return the last curve value\n\t\tif (time >= start + duration) {\n\t\t\treturn curve[len - 1];\n\t\t} else if (time <= start){\n\t\t\treturn curve[0];\n\t\t} else {\n\t\t\tvar progress = (time - start) / duration;\n\t\t\tvar lowerIndex = Math.floor((len - 1) * progress);\n\t\t\tvar upperIndex = Math.ceil((len - 1) * progress);\n\t\t\tvar lowerVal = curve[lowerIndex];\n\t\t\tvar upperVal = curve[upperIndex];\n\t\t\tif (upperIndex === lowerIndex){\n\t\t\t\treturn lowerVal;\n\t\t\t} else {\n\t\t\t\treturn this._linearInterpolate(lowerIndex, lowerVal, upperIndex, upperVal, progress * (len - 1));\n\t\t\t}\n\t\t}\n\t};\n\n\t/**\n\t * Clean up.\n\t * @return {Tone.TimelineSignal} this\n\t */\n\tTone.TimelineSignal.prototype.dispose = function(){\n\t\tTone.Signal.prototype.dispose.call(this);\n\t\tTone.Param.prototype.dispose.call(this);\n\t\tthis._events.dispose();\n\t\tthis._events = null;\n\t};\n\n\treturn Tone.TimelineSignal;\n});","'use strict';\n\ndefine(function (require) {\n var Effect = require('effect');\n\n /**\n *
A p5.Filter uses a Web Audio Biquad Filter to filter\n * the frequency response of an input source. Subclasses\n * include:
\n * p5.LowPass:\n * Allows frequencies below the cutoff frequency to pass through,\n * and attenuates frequencies above the cutoff. \n * p5.HighPass:\n * The opposite of a lowpass filter. \n * p5.BandPass:\n * Allows a range of frequencies to pass through and attenuates\n * the frequencies below and above this frequency range. \n *\n * The .res() method controls either width of the\n * bandpass, or resonance of the low/highpass cutoff frequency.\n *\n * This class extends p5.Effect.\n * Methods amp(), chain(),\n * drywet(), connect(), and\n * disconnect() are available.\n *\n * @class p5.Filter\n * @extends p5.Effect\n * @constructor\n * @param {String} [type] 'lowpass' (default), 'highpass', 'bandpass'\n * @example\n *
\n * var fft, noise, filter;\n *\n * function setup() {\n * fill(255, 40, 255);\n *\n * filter = new p5.BandPass();\n *\n * noise = new p5.Noise();\n * // disconnect unfiltered noise,\n * // and connect to filter\n * noise.disconnect();\n * noise.connect(filter);\n * noise.start();\n *\n * fft = new p5.FFT();\n * }\n *\n * function draw() {\n * background(30);\n *\n * // set the BandPass frequency based on mouseX\n * var freq = map(mouseX, 0, width, 20, 10000);\n * filter.freq(freq);\n * // give the filter a narrow band (lower res = wider bandpass)\n * filter.res(50);\n *\n * // draw filtered spectrum\n * var spectrum = fft.analyze();\n * noStroke();\n * for (var i = 0; i < spectrum.length; i++) {\n * var x = map(i, 0, spectrum.length, 0, width);\n * var h = -height + map(spectrum[i], 0, 255, height, 0);\n * rect(x, height, width/spectrum.length, h);\n * }\n *\n * isMouseOverCanvas();\n * }\n *\n * function isMouseOverCanvas() {\n * var mX = mouseX, mY = mouseY;\n * if (mX > 0 && mX < width && mY < height && mY > 0) {\n * noise.amp(0.5, 0.2);\n * } else {\n * noise.amp(0, 0.2);\n * }\n * }\n *
\n */\n p5.Filter = function (type) {\n\n Effect.call(this);\n //add extend Effect by adding a Biquad Filter\n\n /**\n * The p5.Filter is built with a\n * \n * Web Audio BiquadFilter Node.\n *\n * @property {DelayNode} biquadFilter\n\t */\n\n this.biquad = this.ac.createBiquadFilter();\n\n this.input.connect(this.biquad);\n\n this.biquad.connect(this.wet);\n\n if (type) {\n this.setType(type);\n }\n\n //Properties useful for the toggle method.\n this._on = true;\n this._untoggledType = this.biquad.type;\n };\n p5.Filter.prototype = Object.create(Effect.prototype);\n\n\n /**\n * Filter an audio signal according to a set\n * of filter parameters.\n *\n * @method process\n * @param {Object} Signal An object that outputs audio\n * @param {Number} [freq] Frequency in Hz, from 10 to 22050\n * @param {Number} [res] Resonance/Width of the filter frequency\n * from 0.001 to 1000\n */\n p5.Filter.prototype.process = function(src, freq, res, time) {\n src.connect(this.input);\n this.set(freq, res, time);\n };\n\n\n /**\n * Set the frequency and the resonance of the filter.\n *\n * @method set\n * @param {Number} [freq] Frequency in Hz, from 10 to 22050\n * @param {Number} [res] Resonance (Q) from 0.001 to 1000\n * @param {Number} [timeFromNow] schedule this event to happen\n * seconds from now\n */\n p5.Filter.prototype.set = function(freq, res, time) {\n if (freq) {\n this.freq(freq, time);\n }\n if (res) {\n this.res(res, time);\n }\n };\n\n /**\n * Set the filter frequency, in Hz, from 10 to 22050 (the range of\n * human hearing, although in reality most people hear in a narrower\n * range).\n *\n * @method freq\n * @param {Number} freq Filter Frequency\n * @param {Number} [timeFromNow] schedule this event to happen\n * seconds from now\n * @return {Number} value Returns the current frequency value\n */\n p5.Filter.prototype.freq = function(freq, time) {\n var t = time || 0;\n if (freq <= 0) {\n freq = 1;\n }\n if (typeof freq === 'number') {\n this.biquad.frequency.cancelScheduledValues(this.ac.currentTime + 0.01 + t);\n this.biquad.frequency.exponentialRampToValueAtTime(freq, this.ac.currentTime + 0.02 + t);\n } else if (freq) {\n freq.connect(this.biquad.frequency);\n }\n return this.biquad.frequency.value;\n };\n\n /**\n * Controls either width of a bandpass frequency,\n * or the resonance of a low/highpass cutoff frequency.\n *\n * @method res\n * @param {Number} res Resonance/Width of filter freq\n * from 0.001 to 1000\n * @param {Number} [timeFromNow] schedule this event to happen\n * seconds from now\n * @return {Number} value Returns the current res value\n */\n p5.Filter.prototype.res = function(res, time) {\n var t = time || 0;\n if (typeof res === 'number') {\n this.biquad.Q.value = res;\n this.biquad.Q.cancelScheduledValues(this.ac.currentTime + 0.01 + t);\n this.biquad.Q.linearRampToValueAtTime(res, this.ac.currentTime + 0.02 + t);\n } else if (res) {\n res.connect(this.biquad.Q);\n }\n return this.biquad.Q.value;\n };\n\n /**\n * Controls the gain attribute of a Biquad Filter.\n * This is distinctly different from .amp() which is inherited from p5.Effect\n * .amp() controls the volume via the output gain node\n * p5.Filter.gain() controls the gain parameter of a Biquad Filter node.\n *\n * @method gain\n * @param {Number} gain\n * @return {Number} Returns the current or updated gain value\n */\n p5.Filter.prototype.gain = function(gain, time) {\n var t = time || 0;\n if (typeof gain === 'number') {\n this.biquad.gain.value = gain;\n this.biquad.gain.cancelScheduledValues(this.ac.currentTime + 0.01 + t);\n this.biquad.gain.linearRampToValueAtTime(gain, this.ac.currentTime + 0.02 + t);\n } else if (gain) {\n gain.connect(this.biquad.gain);\n }\n return this.biquad.gain.value;\n };\n\n\n /**\n * Toggle function. Switches between the specified type and allpass\n *\n * @method toggle\n * @return {boolean} [Toggle value]\n */\n p5.Filter.prototype.toggle = function() {\n this._on = !this._on;\n\n if (this._on === true) {\n this.biquad.type = this._untoggledType;\n } else if (this._on === false) {\n this.biquad.type = 'allpass';\n }\n\n return this._on;\n };\n\n /**\n * Set the type of a p5.Filter. Possible types include:\n * \"lowpass\" (default), \"highpass\", \"bandpass\",\n * \"lowshelf\", \"highshelf\", \"peaking\", \"notch\",\n * \"allpass\".\n *\n * @method setType\n * @param {String} t\n */\n p5.Filter.prototype.setType = function(t) {\n this.biquad.type = t;\n this._untoggledType = this.biquad.type;\n };\n\n p5.Filter.prototype.dispose = function() {\n // remove reference from soundArray\n Effect.prototype.dispose.apply(this);\n if (this.biquad) {\n this.biquad.disconnect();\n delete this.biquad;\n }\n };\n\n /**\n * Constructor: new p5.LowPass() Filter.\n * This is the same as creating a p5.Filter and then calling\n * its method setType('lowpass').\n * See p5.Filter for methods.\n *\n * @class p5.LowPass\n * @constructor\n * @extends p5.Filter\n */\n p5.LowPass = function() {\n p5.Filter.call(this, 'lowpass');\n };\n p5.LowPass.prototype = Object.create(p5.Filter.prototype);\n\n /**\n * Constructor: new p5.HighPass() Filter.\n * This is the same as creating a p5.Filter and then calling\n * its method setType('highpass').\n * See p5.Filter for methods.\n *\n * @class p5.HighPass\n * @constructor\n * @extends p5.Filter\n */\n p5.HighPass = function() {\n p5.Filter.call(this, 'highpass');\n };\n p5.HighPass.prototype = Object.create(p5.Filter.prototype);\n\n /**\n * Constructor: new p5.BandPass() Filter.\n * This is the same as creating a p5.Filter and then calling\n * its method setType('bandpass').\n * See p5.Filter for methods.\n *\n * @class p5.BandPass\n * @constructor\n * @extends p5.Filter\n */\n p5.BandPass = function() {\n p5.Filter.call(this, 'bandpass');\n };\n p5.BandPass.prototype = Object.create(p5.Filter.prototype);\n\n return p5.Filter;\n});\n","define([\"Tone/core/Tone\", \"Tone/signal/Add\", \"Tone/signal/Negate\", \"Tone/signal/Signal\", \"Tone/core/Gain\"], function(Tone){\n\n\t\"use strict\";\n\n\t/**\n\t * @class Subtract the signal connected to input[1] from the signal connected \n\t * to input[0]. If an argument is provided in the constructor, the \n\t * signals .value will be subtracted from the incoming signal.\n\t *\n\t * @extends {Tone.Signal}\n\t * @constructor\n\t * @param {number=} value The value to subtract from the incoming signal. If the value\n\t * is omitted, it will subtract the second signal from the first.\n\t * @example\n\t * var sub = new Tone.Subtract(1);\n\t * var sig = new Tone.Signal(4).connect(sub);\n\t * //the output of sub is 3. \n\t * @example\n\t * var sub = new Tone.Subtract();\n\t * var sigA = new Tone.Signal(10);\n\t * var sigB = new Tone.Signal(2.5);\n\t * sigA.connect(sub, 0, 0);\n\t * sigB.connect(sub, 0, 1);\n\t * //output of sub is 7.5\n\t */\n\tTone.Subtract = function(value){\n\n\t\tthis.createInsOuts(2, 0);\n\n\t\t/**\n\t\t * the summing node\n\t\t * @type {GainNode}\n\t\t * @private\n\t\t */\n\t\tthis._sum = this.input[0] = this.output = new Tone.Gain();\n\n\t\t/**\n\t\t * negate the input of the second input before connecting it\n\t\t * to the summing node.\n\t\t * @type {Tone.Negate}\n\t\t * @private\n\t\t */\n\t\tthis._neg = new Tone.Negate();\n\n\t\t/**\n\t\t * the node where the value is set\n\t\t * @private\n\t\t * @type {Tone.Signal}\n\t\t */\n\t\tthis._param = this.input[1] = new Tone.Signal(value);\n\n\t\tthis._param.chain(this._neg, this._sum);\n\t};\n\n\tTone.extend(Tone.Subtract, Tone.Signal);\n\n\t/**\n\t * Clean up.\n\t * @returns {Tone.SignalBase} this\n\t */\n\tTone.Subtract.prototype.dispose = function(){\n\t\tTone.prototype.dispose.call(this);\n\t\tthis._neg.dispose();\n\t\tthis._neg = null;\n\t\tthis._sum.disconnect();\n\t\tthis._sum = null;\n\t\tthis._param.dispose();\n\t\tthis._param = null;\n\t\treturn this;\n\t};\n\n\treturn Tone.Subtract;\n});","'use strict';\n\nglobal.TONE_SILENCE_VERSION_LOGGING = true;\n\ndefine(['startaudiocontext', 'Tone/core/Context', 'Tone/core/Tone'], function (StartAudioContext, Context, Tone) {\n // Create the Audio Context\n const audiocontext = new window.AudioContext();\n\n // Tone and p5.sound share the same audio context\n Tone.context.dispose();\n Tone.setContext(audiocontext);\n\n /**\n *
Returns the Audio Context for this sketch. Useful for users\n * who would like to dig deeper into the Web Audio API\n * .
\n *\n *
Some browsers require users to startAudioContext\n * with a user gesture, such as touchStarted in the example below.
\n *\n * @method getAudioContext\n * @return {Object} AudioContext for this sketch\n * @example\n *
\n * function draw() {\n * background(255);\n * textAlign(CENTER);\n *\n * if (getAudioContext().state !== 'running') {\n * text('click to start audio', width/2, height/2);\n * } else {\n * text('audio is enabled', width/2, height/2);\n * }\n * }\n *\n * function touchStarted() {\n * if (getAudioContext().state !== 'running') {\n * getAudioContext().resume();\n * }\n * var synth = new p5.MonoSynth();\n * synth.play('A4', 0.5, 0, 0.2);\n * }\n *\n *
It is a good practice to give users control over starting audio playback.\n * This practice is enforced by Google Chrome's autoplay policy as of r70\n * (info), iOS Safari, and other browsers.\n *
\n *\n *
\n * userStartAudio() starts the Audio Context on a user gesture. It utilizes\n * the StartAudioContext library by\n * Yotam Mann (MIT Licence, 2016). Read more at https://github.com/tambien/StartAudioContext.\n *
\n *\n *
Starting the audio context on a user gesture can be as simple as userStartAudio().\n * Optional parameters let you decide on a specific element that will start the audio context,\n * and/or call a function once the audio context is started.
\n * @param {Element|Array} [element(s)] This argument can be an Element,\n * Selector String, NodeList, p5.Element,\n * jQuery Element, or an Array of any of those.\n * @param {Function} [callback] Callback to invoke when the AudioContext has started\n * @return {Promise} Returns a Promise which is resolved when\n * the AudioContext state is 'running'\n * @method userStartAudio\n * @for p5\n * @example\n *
\n * function setup() {\n * var myDiv = createDiv('click to start audio');\n * myDiv.position(0, 0);\n *\n * var mySynth = new p5.MonoSynth();\n *\n * // This won't play until the context has started\n * mySynth.play('A6');\n *\n * // Start the audio context on a click/touch event\n * userStartAudio().then(function() {\n * myDiv.remove();\n * });\n * }\n *
\n */\n p5.prototype.userStartAudio = function(elements, callback) {\n var elt = elements;\n if (elements instanceof p5.Element) {\n elt = elements.elt;\n } else if (elements instanceof Array && elements[0] instanceof p5.Element ) {\n elt = elements.map(function(e) { return e.elt});\n }\n return StartAudioContext(audiocontext, elt, callback);\n };\n\n return audiocontext;\n});\n","define([\"Tone/core/Tone\"], function (Tone) {\n\n\t\"use strict\";\n\n\t/**\n\t * @class Tone.Emitter gives classes which extend it\n\t * the ability to listen for and emit events. \n\t * Inspiration and reference from Jerome Etienne's [MicroEvent](https://github.com/jeromeetienne/microevent.js).\n\t * MIT (c) 2011 Jerome Etienne.\n\t * \n\t * @extends {Tone}\n\t */\n\tTone.Emitter = function(){\n\t\t/**\n\t\t * Contains all of the events.\n\t\t * @private\n\t\t * @type {Object}\n\t\t */\n\t\tthis._events = {};\n\t};\n\n\tTone.extend(Tone.Emitter);\n\n\t/**\n\t * Bind a callback to a specific event.\n\t * @param {String} event The name of the event to listen for.\n\t * @param {Function} callback The callback to invoke when the\n\t * event is emitted\n\t * @return {Tone.Emitter} this\n\t */\n\tTone.Emitter.prototype.on = function(event, callback){\n\t\t//split the event\n\t\tvar events = event.split(/\\W+/);\n\t\tfor (var i = 0; i < events.length; i++){\n\t\t\tvar eventName = events[i];\n\t\t\tif (!this._events.hasOwnProperty(eventName)){\n\t\t\t\tthis._events[eventName] = [];\n\t\t\t}\n\t\t\tthis._events[eventName].push(callback);\n\t\t}\n\t\treturn this;\n\t};\n\n\t/**\n\t * Remove the event listener.\n\t * @param {String} event The event to stop listening to.\n\t * @param {Function=} callback The callback which was bound to \n\t * the event with Tone.Emitter.on.\n\t * If no callback is given, all callbacks\n\t * events are removed.\n\t * @return {Tone.Emitter} this\n\t */\n\tTone.Emitter.prototype.off = function(event, callback){\n\t\tvar events = event.split(/\\W+/);\n\t\tfor (var ev = 0; ev < events.length; ev++){\n\t\t\tevent = events[ev];\n\t\t\tif (this._events.hasOwnProperty(event)){\n\t\t\t\tif (Tone.prototype.isUndef(callback)){\n\t\t\t\t\tthis._events[event] = [];\n\t\t\t\t} else {\n\t\t\t\t\tvar eventList = this._events[event];\n\t\t\t\t\tfor (var i = 0; i < eventList.length; i++){\n\t\t\t\t\t\tif (eventList[i] === callback){\n\t\t\t\t\t\t\teventList.splice(i, 1);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\treturn this;\n\t};\n\n\t/**\n\t * Invoke all of the callbacks bound to the event\n\t * with any arguments passed in. \n\t * @param {String} event The name of the event.\n\t * @param {*...} args The arguments to pass to the functions listening.\n\t * @return {Tone.Emitter} this\n\t */\n\tTone.Emitter.prototype.emit = function(event){\n\t\tif (this._events){\n\t\t\tvar args = Array.apply(null, arguments).slice(1);\n\t\t\tif (this._events.hasOwnProperty(event)){\n\t\t\t\tvar eventList = this._events[event];\n\t\t\t\tfor (var i = 0, len = eventList.length; i < len; i++){\n\t\t\t\t\teventList[i].apply(this, args);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\treturn this;\n\t};\n\n\t/**\n\t * Add Emitter functions (on/off/emit) to the object\n\t * @param {Object|Function} object The object or class to extend.\n\t */\n\tTone.Emitter.mixin = function(object){\n\t\tvar functions = [\"on\", \"off\", \"emit\"];\n\t\tobject._events = {};\n\t\tfor (var i = 0; i < functions.length; i++){\n\t\t\tvar func = functions[i];\n\t\t\tvar emitterFunc = Tone.Emitter.prototype[func];\n\t\t\tobject[func] = emitterFunc;\n\t\t}\n\t};\n\n\t/**\n\t * Clean up\n\t * @return {Tone.Emitter} this\n\t */\n\tTone.Emitter.prototype.dispose = function(){\n\t\tTone.prototype.dispose.call(this);\n\t\tthis._events = null;\n\t\treturn this;\n\t};\n\n\treturn Tone.Emitter;\n});","define([\"Tone/core/Tone\"], function(Tone){\n\n\t\"use strict\";\n\n\t/**\n\t * @class Base class for all Signals. Used Internally. \n\t *\n\t * @constructor\n\t * @extends {Tone}\n\t */\n\tTone.SignalBase = function(){};\n\n\tTone.extend(Tone.SignalBase);\n\n\t/**\n\t * When signals connect to other signals or AudioParams, \n\t * they take over the output value of that signal or AudioParam. \n\t * For all other nodes, the behavior is the same as a default connect. \n\t *\n\t * @override\n\t * @param {AudioParam|AudioNode|Tone.Signal|Tone} node \n\t * @param {number} [outputNumber=0] The output number to connect from.\n\t * @param {number} [inputNumber=0] The input number to connect to.\n\t * @returns {Tone.SignalBase} this\n\t */\n\tTone.SignalBase.prototype.connect = function(node, outputNumber, inputNumber){\n\t\t//zero it out so that the signal can have full control\n\t\tif ((Tone.Signal && Tone.Signal === node.constructor) || \n\t\t\t\t(Tone.Param && Tone.Param === node.constructor) || \n\t\t\t\t(Tone.TimelineSignal && Tone.TimelineSignal === node.constructor)){\n\t\t\t//cancel changes\n\t\t\tnode._param.cancelScheduledValues(0);\n\t\t\t//reset the value\n\t\t\tnode._param.value = 0;\n\t\t\t//mark the value as overridden\n\t\t\tnode.overridden = true;\n\t\t} else if (node instanceof AudioParam){\n\t\t\tnode.cancelScheduledValues(0);\n\t\t\tnode.value = 0;\n\t\t} \n\t\tTone.prototype.connect.call(this, node, outputNumber, inputNumber);\n\t\treturn this;\n\t};\n\n\treturn Tone.SignalBase;\n});","define([\"Tone/core/Tone\", \"Tone/type/TimeBase\"], function (Tone) {\n\n\t/**\n\t * @class Tone.Time is a primitive type for encoding Time values. \n\t * Eventually all time values are evaluated to seconds\n\t * using the `eval` method. Tone.Time can be constructed\n\t * with or without the `new` keyword. Tone.Time can be passed\n\t * into the parameter of any method which takes time as an argument. \n\t * @constructor\n\t * @extends {Tone.TimeBase}\n\t * @param {String|Number} val The time value.\n\t * @param {String=} units The units of the value.\n\t * @example\n\t * var t = Tone.Time(\"4n\");//encodes a quarter note\n\t * t.mult(4); // multiply that value by 4\n\t * t.toNotation(); //returns \"1m\"\n\t */\n\tTone.Time = function(val, units){\n\t\tif (this instanceof Tone.Time){\n\n\t\t\t/**\n\t\t\t * If the current clock time should\n\t\t\t * be added to the output\n\t\t\t * @type {Boolean}\n\t\t\t * @private\n\t\t\t */\n\t\t\tthis._plusNow = false;\n\t\t\t\n\t\t\tTone.TimeBase.call(this, val, units);\n\n\t\t} else {\n\t\t\treturn new Tone.Time(val, units);\n\t\t}\n\t};\n\n\tTone.extend(Tone.Time, Tone.TimeBase);\n\n\t//clone the expressions so that \n\t//we can add more without modifying the original\n\tTone.Time.prototype._unaryExpressions = Object.create(Tone.TimeBase.prototype._unaryExpressions);\n\n\t/*\n\t * Adds an additional unary expression\n\t * which quantizes values to the next subdivision\n\t * @type {Object}\n\t * @private\n\t */\n\tTone.Time.prototype._unaryExpressions.quantize = {\n\t\tregexp : /^@/,\n\t\tmethod : function(rh){\n\t\t\treturn Tone.Transport.nextSubdivision(rh());\n\t\t}\n\t};\n\n\t/*\n\t * Adds an additional unary expression\n\t * which adds the current clock time.\n\t * @type {Object}\n\t * @private\n\t */\n\tTone.Time.prototype._unaryExpressions.now = {\n\t\tregexp : /^\\+/,\n\t\tmethod : function(lh){\n\t\t\tthis._plusNow = true;\n\t\t\treturn lh();\n\t\t}\n\t};\n\n\t/**\n\t * Quantize the time by the given subdivision. Optionally add a\n\t * percentage which will move the time value towards the ideal\n\t * quantized value by that percentage. \n\t * @param {Number|Time} val The subdivision to quantize to\n\t * @param {NormalRange} [percent=1] Move the time value\n\t * towards the quantized value by\n\t * a percentage.\n\t * @return {Tone.Time} this\n\t * @example\n\t * Tone.Time(21).quantize(2) //returns 22\n\t * Tone.Time(0.6).quantize(\"4n\", 0.5) //returns 0.55\n\t */\n\tTone.Time.prototype.quantize = function(subdiv, percent){\n\t\tpercent = this.defaultArg(percent, 1);\n\t\tthis._expr = function(expr, subdivision, percent){\n\t\t\texpr = expr();\n\t\t\tsubdivision = subdivision.toSeconds();\n\t\t\tvar multiple = Math.round(expr / subdivision);\n\t\t\tvar ideal = multiple * subdivision;\n\t\t\tvar diff = ideal - expr;\n\t\t\treturn expr + diff * percent;\n\t\t}.bind(this, this._expr, new this.constructor(subdiv), percent);\n\t\treturn this;\n\t};\n\n\t/**\n\t * Adds the clock time to the time expression at the \n\t * moment of evaluation. \n\t * @return {Tone.Time} this\n\t */\n\tTone.Time.prototype.addNow = function(){\n\t\tthis._plusNow = true;\n\t\treturn this;\n\t};\n\n\t/**\n\t * @override\n\t * Override the default value return when no arguments are passed in.\n\t * The default value is 'now'\n\t * @private\n\t */\n\tTone.Time.prototype._defaultExpr = function(){\n\t\tthis._plusNow = true;\n\t\treturn this._noOp;\n\t};\n\n\t/**\n\t * Copies the value of time to this Time\n\t * @param {Tone.Time} time\n\t * @return {Time}\n\t */\n\tTone.Time.prototype.copy = function(time){\n\t\tTone.TimeBase.prototype.copy.call(this, time);\n\t\tthis._plusNow = time._plusNow;\n\t\treturn this;\n\t};\n\n\t//CONVERSIONS//////////////////////////////////////////////////////////////\n\n\t/**\n\t * Convert a Time to Notation. Values will be thresholded to the nearest 128th note. \n\t * @return {Notation} \n\t * @example\n\t * //if the Transport is at 120bpm:\n\t * Tone.Time(2).toNotation();//returns \"1m\"\n\t */\n\tTone.Time.prototype.toNotation = function(){\n\t\tvar time = this.toSeconds();\n\t\tvar testNotations = [\"1m\", \"2n\", \"4n\", \"8n\", \"16n\", \"32n\", \"64n\", \"128n\"];\n\t\tvar retNotation = this._toNotationHelper(time, testNotations);\n\t\t//try the same thing but with tripelets\n\t\tvar testTripletNotations = [\"1m\", \"2n\", \"2t\", \"4n\", \"4t\", \"8n\", \"8t\", \"16n\", \"16t\", \"32n\", \"32t\", \"64n\", \"64t\", \"128n\"];\n\t\tvar retTripletNotation = this._toNotationHelper(time, testTripletNotations);\n\t\t//choose the simpler expression of the two\n\t\tif (retTripletNotation.split(\"+\").length < retNotation.split(\"+\").length){\n\t\t\treturn retTripletNotation;\n\t\t} else {\n\t\t\treturn retNotation;\n\t\t}\n\t};\n\n\t/**\n\t * Helper method for Tone.toNotation\n\t * @param {Number} units \n\t * @param {Array} testNotations\n\t * @return {String}\n\t * @private\n\t */\n\tTone.Time.prototype._toNotationHelper = function(units, testNotations){\n\t\t//the threshold is the last value in the array\n\t\tvar threshold = this._notationToUnits(testNotations[testNotations.length - 1]);\n\t\tvar retNotation = \"\";\n\t\tfor (var i = 0; i < testNotations.length; i++){\n\t\t\tvar notationTime = this._notationToUnits(testNotations[i]);\n\t\t\t//account for floating point errors (i.e. round up if the value is 0.999999)\n\t\t\tvar multiple = units / notationTime;\n\t\t\tvar floatingPointError = 0.000001;\n\t\t\tif (1 - multiple % 1 < floatingPointError){\n\t\t\t\tmultiple += floatingPointError;\n\t\t\t}\n\t\t\tmultiple = Math.floor(multiple);\n\t\t\tif (multiple > 0){\n\t\t\t\tif (multiple === 1){\n\t\t\t\t\tretNotation += testNotations[i];\n\t\t\t\t} else {\n\t\t\t\t\tretNotation += multiple.toString() + \"*\" + testNotations[i];\n\t\t\t\t}\n\t\t\t\tunits -= multiple * notationTime;\n\t\t\t\tif (units < threshold){\n\t\t\t\t\tbreak;\n\t\t\t\t} else {\n\t\t\t\t\tretNotation += \" + \";\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tif (retNotation === \"\"){\n\t\t\tretNotation = \"0\";\n\t\t}\n\t\treturn retNotation;\n\t};\n\n\t/**\n\t * Convert a notation value to the current units\n\t * @param {Notation} notation \n\t * @return {Number} \n\t * @private\n\t */\n\tTone.Time.prototype._notationToUnits = function(notation){\n\t\tvar primaryExprs = this._primaryExpressions;\n\t\tvar notationExprs = [primaryExprs.n, primaryExprs.t, primaryExprs.m];\n\t\tfor (var i = 0; i < notationExprs.length; i++){\n\t\t\tvar expr = notationExprs[i];\n\t\t\tvar match = notation.match(expr.regexp);\n\t\t\tif (match){\n\t\t\t\treturn expr.method.call(this, match[1]);\n\t\t\t}\n\t\t}\n\t};\n\n\t/**\n\t * Return the time encoded as Bars:Beats:Sixteenths.\n\t * @return {BarsBeatsSixteenths}\n\t */\n\tTone.Time.prototype.toBarsBeatsSixteenths = function(){\n\t\tvar quarterTime = this._beatsToUnits(1);\n\t\tvar quarters = this.toSeconds() / quarterTime;\n\t\tvar measures = Math.floor(quarters / this._timeSignature());\n\t\tvar sixteenths = (quarters % 1) * 4;\n\t\tquarters = Math.floor(quarters) % this._timeSignature();\n\t\tsixteenths = sixteenths.toString();\n\t\tif (sixteenths.length > 3){\n\t\t\tsixteenths = parseFloat(sixteenths).toFixed(3);\n\t\t}\n\t\tvar progress = [measures, quarters, sixteenths];\n\t\treturn progress.join(\":\");\n\t};\n\n\t/**\n\t * Return the time in ticks.\n\t * @return {Ticks}\n\t */\n\tTone.Time.prototype.toTicks = function(){\n\t\tvar quarterTime = this._beatsToUnits(1);\n\t\tvar quarters = this.valueOf() / quarterTime;\n\t\treturn Math.floor(quarters * Tone.Transport.PPQ);\n\t};\n\n\t/**\n\t * Return the time in samples\n\t * @return {Samples} \n\t */\n\tTone.Time.prototype.toSamples = function(){\n\t\treturn this.toSeconds() * this.context.sampleRate;\n\t};\n\n\t/**\n\t * Return the time as a frequency value\n\t * @return {Frequency} \n\t * @example\n\t * Tone.Time(2).toFrequency(); //0.5\n\t */\n\tTone.Time.prototype.toFrequency = function(){\n\t\treturn 1/this.toSeconds();\n\t};\n\n\t/**\n\t * Return the time in seconds.\n\t * @return {Seconds} \n\t */\n\tTone.Time.prototype.toSeconds = function(){\n\t\treturn this.valueOf();\n\t};\n\n\t/**\n\t * Return the time in milliseconds.\n\t * @return {Milliseconds} \n\t */\n\tTone.Time.prototype.toMilliseconds = function(){\n\t\treturn this.toSeconds() * 1000;\n\t};\n\n\t/**\n\t * Return the time in seconds.\n\t * @return {Seconds} \n\t */\n\tTone.Time.prototype.valueOf = function(){\n\t\tvar val = this._expr();\n\t\treturn val + (this._plusNow?this.now():0);\n\t};\n\n\treturn Tone.Time;\n});","define([\"Tone/core/Tone\"], function (Tone) {\n\n\t/**\n\t * @class Tone.TimeBase is a flexible encoding of time\n\t * which can be evaluated to and from a string.\n\t * Parsing code modified from https://code.google.com/p/tapdigit/\n\t * Copyright 2011 2012 Ariya Hidayat, New BSD License\n\t * @extends {Tone}\n\t * @param {Time} val The time value as a number or string\n\t * @param {String=} units Unit values\n\t * @example\n\t * Tone.TimeBase(4, \"n\")\n\t * Tone.TimeBase(2, \"t\")\n\t * Tone.TimeBase(\"2t\").add(\"1m\")\n\t * Tone.TimeBase(\"2t + 1m\");\n\t */\n\tTone.TimeBase = function(val, units){\n\n\t\t//allows it to be constructed with or without 'new'\n\t\tif (this instanceof Tone.TimeBase) {\n\n\t\t\t/**\n\t\t\t * Any expressions parsed from the Time\n\t\t\t * @type {Array}\n\t\t\t * @private\n\t\t\t */\n\t\t\tthis._expr = this._noOp;\n\n\t\t\tif (val instanceof Tone.TimeBase){\n\t\t\t\tthis.copy(val);\n\t\t\t} else if (!this.isUndef(units) || this.isNumber(val)){\n\t\t\t\t//default units\n\t\t\t\tunits = this.defaultArg(units, this._defaultUnits);\n\t\t\t\tvar method = this._primaryExpressions[units].method;\n\t\t\t\tthis._expr = method.bind(this, val);\n\t\t\t} else if (this.isString(val)){\n\t\t\t\tthis.set(val);\n\t\t\t} else if (this.isUndef(val)){\n\t\t\t\t//default expression\n\t\t\t\tthis._expr = this._defaultExpr();\n\t\t\t}\n\t\t} else {\n\n\t\t\treturn new Tone.TimeBase(val, units);\n\t\t}\n\t};\n\n\tTone.extend(Tone.TimeBase);\n\n\t/**\n\t * Repalce the current time value with the value\n\t * given by the expression string.\n\t * @param {String} exprString\n\t * @return {Tone.TimeBase} this\n\t */\n\tTone.TimeBase.prototype.set = function(exprString){\n\t\tthis._expr = this._parseExprString(exprString);\n\t\treturn this;\n\t};\n\n\t/**\n\t * Return a clone of the TimeBase object.\n\t * @return {Tone.TimeBase} The new cloned Tone.TimeBase\n\t */\n\tTone.TimeBase.prototype.clone = function(){\n\t\tvar instance = new this.constructor();\n\t\tinstance.copy(this);\n\t\treturn instance;\n\t};\n\n\t/**\n\t * Copies the value of time to this Time\n\t * @param {Tone.TimeBase} time\n\t * @return {TimeBase}\n\t */\n\tTone.TimeBase.prototype.copy = function(time){\n\t\tvar val = time._expr();\n\t\treturn this.set(val);\n\t};\n\n\t///////////////////////////////////////////////////////////////////////////\n\t//\tABSTRACT SYNTAX TREE PARSER\n\t///////////////////////////////////////////////////////////////////////////\n\n\t/**\n\t * All the primary expressions.\n\t * @private\n\t * @type {Object}\n\t */\n\tTone.TimeBase.prototype._primaryExpressions = {\n\t\t\"n\" : {\n\t\t\tregexp : /^(\\d+)n/i,\n\t\t\tmethod : function(value){\n\t\t\t\tvalue = parseInt(value);\n\t\t\t\tif (value === 1){\n\t\t\t\t\treturn this._beatsToUnits(this._timeSignature());\n\t\t\t\t} else {\n\t\t\t\t\treturn this._beatsToUnits(4 / value);\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\t\t\"t\" : {\n\t\t\tregexp : /^(\\d+)t/i,\n\t\t\tmethod : function(value){\n\t\t\t\tvalue = parseInt(value);\n\t\t\t\treturn this._beatsToUnits(8 / (parseInt(value) * 3));\n\t\t\t}\n\t\t},\n\t\t\"m\" : {\n\t\t\tregexp : /^(\\d+)m/i,\n\t\t\tmethod : function(value){\n\t\t\t\treturn this._beatsToUnits(parseInt(value) * this._timeSignature());\n\t\t\t}\n\t\t},\n\t\t\"i\" : {\n\t\t\tregexp : /^(\\d+)i/i,\n\t\t\tmethod : function(value){\n\t\t\t\treturn this._ticksToUnits(parseInt(value));\n\t\t\t}\n\t\t},\n\t\t\"hz\" : {\n\t\t\tregexp : /^(\\d+(?:\\.\\d+)?)hz/i,\n\t\t\tmethod : function(value){\n\t\t\t\treturn this._frequencyToUnits(parseFloat(value));\n\t\t\t}\n\t\t},\n\t\t\"tr\" : {\n\t\t\tregexp : /^(\\d+(?:\\.\\d+)?):(\\d+(?:\\.\\d+)?):?(\\d+(?:\\.\\d+)?)?/,\n\t\t\tmethod : function(m, q, s){\n\t\t\t\tvar total = 0;\n\t\t\t\tif (m && m !== \"0\"){\n\t\t\t\t\ttotal += this._beatsToUnits(this._timeSignature() * parseFloat(m));\n\t\t\t\t}\n\t\t\t\tif (q && q !== \"0\"){\n\t\t\t\t\ttotal += this._beatsToUnits(parseFloat(q));\n\t\t\t\t}\n\t\t\t\tif (s && s !== \"0\"){\n\t\t\t\t\ttotal += this._beatsToUnits(parseFloat(s) / 4);\n\t\t\t\t}\n\t\t\t\treturn total;\n\t\t\t}\n\t\t},\n\t\t\"s\" : {\n\t\t\tregexp : /^(\\d+(?:\\.\\d+)?s)/,\n\t\t\tmethod : function(value){\n\t\t\t\treturn this._secondsToUnits(parseFloat(value));\n\t\t\t}\n\t\t},\n\t\t\"samples\" : {\n\t\t\tregexp : /^(\\d+)samples/,\n\t\t\tmethod : function(value){\n\t\t\t\treturn parseInt(value) / this.context.sampleRate;\n\t\t\t}\n\t\t},\n\t\t\"default\" : {\n\t\t\tregexp : /^(\\d+(?:\\.\\d+)?)/,\n\t\t\tmethod : function(value){\n\t\t\t\treturn this._primaryExpressions[this._defaultUnits].method.call(this, value);\n\t\t\t}\n\t\t}\n\t};\n\n\t/**\n\t * All the binary expressions that TimeBase can accept.\n\t * @private\n\t * @type {Object}\n\t */\n\tTone.TimeBase.prototype._binaryExpressions = {\n\t\t\"+\" : {\n\t\t\tregexp : /^\\+/,\n\t\t\tprecedence : 2,\n\t\t\tmethod : function(lh, rh){\n\t\t\t\treturn lh() + rh();\n\t\t\t}\n\t\t},\n\t\t\"-\" : {\n\t\t\tregexp : /^\\-/,\n\t\t\tprecedence : 2,\n\t\t\tmethod : function(lh, rh){\n\t\t\t\treturn lh() - rh();\n\t\t\t}\n\t\t},\n\t\t\"*\" : {\n\t\t\tregexp : /^\\*/,\n\t\t\tprecedence : 1,\n\t\t\tmethod : function(lh, rh){\n\t\t\t\treturn lh() * rh();\n\t\t\t}\n\t\t},\n\t\t\"/\" : {\n\t\t\tregexp : /^\\//,\n\t\t\tprecedence : 1,\n\t\t\tmethod : function(lh, rh){\n\t\t\t\treturn lh() / rh();\n\t\t\t}\n\t\t}\n\t};\n\n\t/**\n\t * All the unary expressions.\n\t * @private\n\t * @type {Object}\n\t */\n\tTone.TimeBase.prototype._unaryExpressions = {\n\t\t\"neg\" : {\n\t\t\tregexp : /^\\-/,\n\t\t\tmethod : function(lh){\n\t\t\t\treturn -lh();\n\t\t\t}\n\t\t}\n\t};\n\n\t/**\n\t * Syntactic glue which holds expressions together\n\t * @private\n\t * @type {Object}\n\t */\n\tTone.TimeBase.prototype._syntaxGlue = {\n\t\t\"(\" : {\n\t\t\tregexp : /^\\(/\n\t\t},\n\t\t\")\" : {\n\t\t\tregexp : /^\\)/\n\t\t}\n\t};\n\n\t/**\n\t * tokenize the expression based on the Expressions object\n\t * @param {string} expr \n\t * @return {Object} returns two methods on the tokenized list, next and peek\n\t * @private\n\t */\n\tTone.TimeBase.prototype._tokenize = function(expr){\n\t\tvar position = -1;\n\t\tvar tokens = [];\n\n\t\twhile(expr.length > 0){\n\t\t\texpr = expr.trim();\n\t\t\tvar token = getNextToken(expr, this);\n\t\t\ttokens.push(token);\n\t\t\texpr = expr.substr(token.value.length);\n\t\t}\n\n\t\tfunction getNextToken(expr, context){\n\t\t\tvar expressions = [\"_binaryExpressions\", \"_unaryExpressions\", \"_primaryExpressions\", \"_syntaxGlue\"];\n\t\t\tfor (var i = 0; i < expressions.length; i++){\n\t\t\t\tvar group = context[expressions[i]];\n\t\t\t\tfor (var opName in group){\n\t\t\t\t\tvar op = group[opName];\n\t\t\t\t\tvar reg = op.regexp;\n\t\t\t\t\tvar match = expr.match(reg);\n\t\t\t\t\tif (match !== null){\n\t\t\t\t\t\treturn {\n\t\t\t\t\t\t\tmethod : op.method,\n\t\t\t\t\t\t\tprecedence : op.precedence,\n\t\t\t\t\t\t\tregexp : op.regexp,\n\t\t\t\t\t\t\tvalue : match[0],\n\t\t\t\t\t\t};\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\tthrow new SyntaxError(\"Tone.TimeBase: Unexpected token \"+expr);\n\t\t}\n\n\t\treturn {\n\t\t\tnext : function(){\n\t\t\t\treturn tokens[++position];\n\t\t\t},\n\t\t\tpeek : function(){\n\t\t\t\treturn tokens[position + 1];\n\t\t\t}\n\t\t};\n\t};\n\n\t/**\n\t * Given a token, find the value within the groupName\n\t * @param {Object} token\n\t * @param {String} groupName\n\t * @param {Number} precedence\n\t * @private\n\t */\n\tTone.TimeBase.prototype._matchGroup = function(token, group, prec) {\n\t\tvar ret = false;\n\t\tif (!this.isUndef(token)){\n\t\t\tfor (var opName in group){\n\t\t\t\tvar op = group[opName];\n\t\t\t\tif (op.regexp.test(token.value)){\n\t\t\t\t\tif (!this.isUndef(prec)){\n\t\t\t\t\t\tif(op.precedence === prec){\t\n\t\t\t\t\t\t\treturn op;\n\t\t\t\t\t\t}\n\t\t\t\t\t} else {\n\t\t\t\t\t\treturn op;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\treturn ret;\n\t};\n\n\t/**\n\t * Match a binary expression given the token and the precedence\n\t * @param {Lexer} lexer\n\t * @param {Number} precedence\n\t * @private\n\t */\n\tTone.TimeBase.prototype._parseBinary = function(lexer, precedence){\n\t\tif (this.isUndef(precedence)){\n\t\t\tprecedence = 2;\n\t\t}\n\t\tvar expr;\n\t\tif (precedence < 0){\n\t\t\texpr = this._parseUnary(lexer);\n\t\t} else {\n\t\t\texpr = this._parseBinary(lexer, precedence - 1);\n\t\t}\n\t\tvar token = lexer.peek();\n\t\twhile (token && this._matchGroup(token, this._binaryExpressions, precedence)){\n\t\t\ttoken = lexer.next();\n\t\t\texpr = token.method.bind(this, expr, this._parseBinary(lexer, precedence - 1));\n\t\t\ttoken = lexer.peek();\n\t\t}\n\t\treturn expr;\n\t};\n\n\t/**\n\t * Match a unary expression.\n\t * @param {Lexer} lexer\n\t * @private\n\t */\n\tTone.TimeBase.prototype._parseUnary = function(lexer){\n\t\tvar token, expr;\n\t\ttoken = lexer.peek();\n\t\tvar op = this._matchGroup(token, this._unaryExpressions);\n\t\tif (op) {\n\t\t\ttoken = lexer.next();\n\t\t\texpr = this._parseUnary(lexer);\n\t\t\treturn op.method.bind(this, expr);\n\t\t}\n\t\treturn this._parsePrimary(lexer);\n\t};\n\n\t/**\n\t * Match a primary expression (a value).\n\t * @param {Lexer} lexer\n\t * @private\n\t */\n\tTone.TimeBase.prototype._parsePrimary = function(lexer){\n\t\tvar token, expr;\n\t\ttoken = lexer.peek();\n\t\tif (this.isUndef(token)) {\n\t\t\tthrow new SyntaxError(\"Tone.TimeBase: Unexpected end of expression\");\n\t\t}\n\t\tif (this._matchGroup(token, this._primaryExpressions)) {\n\t\t\ttoken = lexer.next();\n\t\t\tvar matching = token.value.match(token.regexp);\n\t\t\treturn token.method.bind(this, matching[1], matching[2], matching[3]);\n\t\t}\n\t\tif (token && token.value === \"(\"){\n\t\t\tlexer.next();\n\t\t\texpr = this._parseBinary(lexer);\n\t\t\ttoken = lexer.next();\n\t\t\tif (!(token && token.value === \")\")) {\n\t\t\t\tthrow new SyntaxError(\"Expected )\");\n\t\t\t}\n\t\t\treturn expr;\n\t\t}\n\t\tthrow new SyntaxError(\"Tone.TimeBase: Cannot process token \" + token.value);\n\t};\n\n\t/**\n\t * Recursively parse the string expression into a syntax tree.\n\t * @param {string} expr \n\t * @return {Function} the bound method to be evaluated later\n\t * @private\n\t */\n\tTone.TimeBase.prototype._parseExprString = function(exprString){\n\t\tif (!this.isString(exprString)){\n\t\t\texprString = exprString.toString();\n\t\t}\n\t\tvar lexer = this._tokenize(exprString);\n\t\tvar tree = this._parseBinary(lexer);\n\t\treturn tree;\n\t};\n\n\t///////////////////////////////////////////////////////////////////////////\n\t//\tDEFAULTS\n\t///////////////////////////////////////////////////////////////////////////\n\n\t/**\n\t * The initial expression value\n\t * @return {Number} The initial value 0\n\t * @private\n\t */\n\tTone.TimeBase.prototype._noOp = function(){\n\t\treturn 0;\n\t};\n\n\t/**\n\t * The default expression value if no arguments are given\n\t * @private\n\t */\n\tTone.TimeBase.prototype._defaultExpr = function(){\n\t\treturn this._noOp;\n\t};\n\n\t/**\n\t * The default units if none are given.\n\t * @private\n\t */\n\tTone.TimeBase.prototype._defaultUnits = \"s\";\n\n\t///////////////////////////////////////////////////////////////////////////\n\t//\tUNIT CONVERSIONS\n\t///////////////////////////////////////////////////////////////////////////\n\n\t/**\n\t * Returns the value of a frequency in the current units\n\t * @param {Frequency} freq\n\t * @return {Number}\n\t * @private\n\t */\n\tTone.TimeBase.prototype._frequencyToUnits = function(freq){\n\t\treturn 1/freq;\n\t};\n\n\t/**\n\t * Return the value of the beats in the current units\n\t * @param {Number} beats\n\t * @return {Number}\n\t * @private\n\t */\n\tTone.TimeBase.prototype._beatsToUnits = function(beats){\n\t\treturn (60 / Tone.Transport.bpm.value) * beats;\n\t};\n\n\t/**\n\t * Returns the value of a second in the current units\n\t * @param {Seconds} seconds\n\t * @return {Number}\n\t * @private\n\t */\n\tTone.TimeBase.prototype._secondsToUnits = function(seconds){\n\t\treturn seconds;\n\t};\n\n\t/**\n\t * Returns the value of a tick in the current time units\n\t * @param {Ticks} ticks\n\t * @return {Number}\n\t * @private\n\t */\n\tTone.TimeBase.prototype._ticksToUnits = function(ticks){\n\t\treturn ticks * (this._beatsToUnits(1) / Tone.Transport.PPQ);\n\t};\n\n\t/**\n\t * Return the time signature.\n\t * @return {Number}\n\t * @private\n\t */\n\tTone.TimeBase.prototype._timeSignature = function(){\n\t\treturn Tone.Transport.timeSignature;\n\t};\n\n\t///////////////////////////////////////////////////////////////////////////\n\t//\tEXPRESSIONS\n\t///////////////////////////////////////////////////////////////////////////\n\n\t/**\n\t * Push an expression onto the expression list\n\t * @param {Time} val\n\t * @param {String} type\n\t * @param {String} units\n\t * @return {Tone.TimeBase} \n\t * @private\n\t */\n\tTone.TimeBase.prototype._pushExpr = function(val, name, units){\n\t\t//create the expression\n\t\tif (!(val instanceof Tone.TimeBase)){\n\t\t\tval = new this.constructor(val, units);\n\t\t}\n\t\tthis._expr = this._binaryExpressions[name].method.bind(this, this._expr, val._expr);\n\t\treturn this;\n\t};\n\n\t/**\n\t * Add to the current value.\n\t * @param {Time} val The value to add\n\t * @param {String=} units Optional units to use with the value.\n\t * @return {Tone.TimeBase} this\n\t * @example\n\t * Tone.TimeBase(\"2m\").add(\"1m\"); //\"3m\"\n\t */\n\tTone.TimeBase.prototype.add = function(val, units){\n\t\treturn this._pushExpr(val, \"+\", units);\n\t};\n\n\t/**\n\t * Subtract the value from the current time.\n\t * @param {Time} val The value to subtract\n\t * @param {String=} units Optional units to use with the value.\n\t * @return {Tone.TimeBase} this\n\t * @example\n\t * Tone.TimeBase(\"2m\").sub(\"1m\"); //\"1m\"\n\t */\n\tTone.TimeBase.prototype.sub = function(val, units){\n\t\treturn this._pushExpr(val, \"-\", units);\n\t};\n\n\t/**\n\t * Multiply the current value by the given time.\n\t * @param {Time} val The value to multiply\n\t * @param {String=} units Optional units to use with the value.\n\t * @return {Tone.TimeBase} this\n\t * @example\n\t * Tone.TimeBase(\"2m\").mult(\"2\"); //\"4m\"\n\t */\n\tTone.TimeBase.prototype.mult = function(val, units){\n\t\treturn this._pushExpr(val, \"*\", units);\n\t};\n\n\t/**\n\t * Divide the current value by the given time.\n\t * @param {Time} val The value to divide by\n\t * @param {String=} units Optional units to use with the value.\n\t * @return {Tone.TimeBase} this\n\t * @example\n\t * Tone.TimeBase(\"2m\").div(2); //\"1m\"\n\t */\n\tTone.TimeBase.prototype.div = function(val, units){\n\t\treturn this._pushExpr(val, \"/\", units);\n\t};\n\n\t/**\n\t * Evaluate the time value. Returns the time\n\t * in seconds.\n\t * @return {Seconds} \n\t */\n\tTone.TimeBase.prototype.valueOf = function(){\n\t\treturn this._expr();\n\t};\n\n\t/**\n\t * Clean up\n\t * @return {Tone.TimeBase} this\n\t */\n\tTone.TimeBase.prototype.dispose = function(){\n\t\tthis._expr = null;\n\t};\n\n\treturn Tone.TimeBase;\n});","define([\"Tone/core/Tone\", \"Tone/type/Type\"], function(Tone){\n\n\t\"use strict\";\n\n\t/**\n\t * @class Tone.Param wraps the native Web Audio's AudioParam to provide\n\t * additional unit conversion functionality. It also\n\t * serves as a base-class for classes which have a single,\n\t * automatable parameter. \n\t * @extends {Tone}\n\t * @param {AudioParam} param The parameter to wrap.\n\t * @param {Tone.Type} units The units of the audio param.\n\t * @param {Boolean} convert If the param should be converted.\n\t */\n\tTone.Param = function(){\n\n\t\tvar options = this.optionsObject(arguments, [\"param\", \"units\", \"convert\"], Tone.Param.defaults);\n\n\t\t/**\n\t\t * The native parameter to control\n\t\t * @type {AudioParam}\n\t\t * @private\n\t\t */\n\t\tthis._param = this.input = options.param;\n\n\t\t/**\n\t\t * The units of the parameter\n\t\t * @type {Tone.Type}\n\t\t */\n\t\tthis.units = options.units;\n\n\t\t/**\n\t\t * If the value should be converted or not\n\t\t * @type {Boolean}\n\t\t */\n\t\tthis.convert = options.convert;\n\n\t\t/**\n\t\t * True if the signal value is being overridden by \n\t\t * a connected signal.\n\t\t * @readOnly\n\t\t * @type {boolean}\n\t\t * @private\n\t\t */\n\t\tthis.overridden = false;\n\n\t\t/**\n\t\t * If there is an LFO, this is where it is held.\n\t\t * @type {Tone.LFO}\n\t\t * @private\n\t\t */\n\t\tthis._lfo = null;\n\n\t\tif (this.isObject(options.lfo)){\n\t\t\tthis.value = options.lfo;\n\t\t} else if (!this.isUndef(options.value)){\n\t\t\tthis.value = options.value;\n\t\t}\n\t};\n\n\tTone.extend(Tone.Param);\n\t\n\t/**\n\t * Defaults\n\t * @type {Object}\n\t * @const\n\t */\n\tTone.Param.defaults = {\n\t\t\"units\" : Tone.Type.Default,\n\t\t\"convert\" : true,\n\t\t\"param\" : undefined\n\t};\n\n\t/**\n\t * The current value of the parameter. \n\t * @memberOf Tone.Param#\n\t * @type {Number}\n\t * @name value\n\t */\n\tObject.defineProperty(Tone.Param.prototype, \"value\", {\n\t\tget : function(){\n\t\t\treturn this._toUnits(this._param.value);\n\t\t},\n\t\tset : function(value){\n\t\t\tif (this.isObject(value)){\n\t\t\t\t//throw an error if the LFO needs to be included\n\t\t\t\tif (this.isUndef(Tone.LFO)){\n\t\t\t\t\tthrow new Error(\"Include 'Tone.LFO' to use an LFO as a Param value.\");\n\t\t\t\t}\n\t\t\t\t//remove the old one\n\t\t\t\tif (this._lfo){\n\t\t\t\t\tthis._lfo.dispose();\n\t\t\t\t}\n\t\t\t\tthis._lfo = new Tone.LFO(value).start();\n\t\t\t\tthis._lfo.connect(this.input);\n\t\t\t} else {\n\t\t\t\tvar convertedVal = this._fromUnits(value);\n\t\t\t\tthis._param.cancelScheduledValues(0);\n\t\t\t\tthis._param.value = convertedVal;\n\t\t\t}\n\t\t}\n\t});\n\n\t/**\n\t * Convert the given value from the type specified by Tone.Param.units\n\t * into the destination value (such as Gain or Frequency).\n\t * @private\n\t * @param {*} val the value to convert\n\t * @return {number} the number which the value should be set to\n\t */\n\tTone.Param.prototype._fromUnits = function(val){\n\t\tif (this.convert || this.isUndef(this.convert)){\n\t\t\tswitch(this.units){\n\t\t\t\tcase Tone.Type.Time: \n\t\t\t\t\treturn this.toSeconds(val);\n\t\t\t\tcase Tone.Type.Frequency: \n\t\t\t\t\treturn this.toFrequency(val);\n\t\t\t\tcase Tone.Type.Decibels: \n\t\t\t\t\treturn this.dbToGain(val);\n\t\t\t\tcase Tone.Type.NormalRange: \n\t\t\t\t\treturn Math.min(Math.max(val, 0), 1);\n\t\t\t\tcase Tone.Type.AudioRange: \n\t\t\t\t\treturn Math.min(Math.max(val, -1), 1);\n\t\t\t\tcase Tone.Type.Positive: \n\t\t\t\t\treturn Math.max(val, 0);\n\t\t\t\tdefault:\n\t\t\t\t\treturn val;\n\t\t\t}\n\t\t} else {\n\t\t\treturn val;\n\t\t}\n\t};\n\n\t/**\n\t * Convert the parameters value into the units specified by Tone.Param.units.\n\t * @private\n\t * @param {number} val the value to convert\n\t * @return {number}\n\t */\n\tTone.Param.prototype._toUnits = function(val){\n\t\tif (this.convert || this.isUndef(this.convert)){\n\t\t\tswitch(this.units){\n\t\t\t\tcase Tone.Type.Decibels: \n\t\t\t\t\treturn this.gainToDb(val);\n\t\t\t\tdefault:\n\t\t\t\t\treturn val;\n\t\t\t}\n\t\t} else {\n\t\t\treturn val;\n\t\t}\n\t};\n\n\t/**\n\t * the minimum output value\n\t * @type {Number}\n\t * @private\n\t */\n\tTone.Param.prototype._minOutput = 0.00001;\n\n\t/**\n\t * Schedules a parameter value change at the given time.\n\t * @param {*}\tvalue The value to set the signal.\n\t * @param {Time} time The time when the change should occur.\n\t * @returns {Tone.Param} this\n\t * @example\n\t * //set the frequency to \"G4\" in exactly 1 second from now. \n\t * freq.setValueAtTime(\"G4\", \"+1\");\n\t */\n\tTone.Param.prototype.setValueAtTime = function(value, time){\n\t\tvalue = this._fromUnits(value);\n\t\ttime = this.toSeconds(time);\n\t\tif (time <= this.now() + this.blockTime){\n\t\t\tthis._param.value = value;\n\t\t} else {\n\t\t\tthis._param.setValueAtTime(value, time);\n\t\t}\n\t\treturn this;\n\t};\n\n\t/**\n\t * Creates a schedule point with the current value at the current time.\n\t * This is useful for creating an automation anchor point in order to \n\t * schedule changes from the current value. \n\t *\n\t * @param {number=} now (Optionally) pass the now value in. \n\t * @returns {Tone.Param} this\n\t */\n\tTone.Param.prototype.setRampPoint = function(now){\n\t\tnow = this.defaultArg(now, this.now());\n\t\tvar currentVal = this._param.value;\n\t\t// exponentialRampToValueAt cannot ever ramp from or to 0\n\t\t// More info: https://bugzilla.mozilla.org/show_bug.cgi?id=1125600#c2\n\t\tif (currentVal === 0){\n\t\t\tcurrentVal = this._minOutput;\n\t\t}\n\t\tthis._param.setValueAtTime(currentVal, now);\n\t\treturn this;\n\t};\n\n\t/**\n\t * Schedules a linear continuous change in parameter value from the \n\t * previous scheduled parameter value to the given value.\n\t * \n\t * @param {number} value \n\t * @param {Time} endTime \n\t * @returns {Tone.Param} this\n\t */\n\tTone.Param.prototype.linearRampToValueAtTime = function(value, endTime){\n\t\tvalue = this._fromUnits(value);\n\t\tthis._param.linearRampToValueAtTime(value, this.toSeconds(endTime));\n\t\treturn this;\n\t};\n\n\t/**\n\t * Schedules an exponential continuous change in parameter value from \n\t * the previous scheduled parameter value to the given value.\n\t * \n\t * @param {number} value \n\t * @param {Time} endTime \n\t * @returns {Tone.Param} this\n\t */\n\tTone.Param.prototype.exponentialRampToValueAtTime = function(value, endTime){\n\t\tvalue = this._fromUnits(value);\n\t\tvalue = Math.max(this._minOutput, value);\n\t\tthis._param.exponentialRampToValueAtTime(value, this.toSeconds(endTime));\n\t\treturn this;\n\t};\n\n\t/**\n\t * Schedules an exponential continuous change in parameter value from \n\t * the current time and current value to the given value over the \n\t * duration of the rampTime.\n\t * \n\t * @param {number} value The value to ramp to.\n\t * @param {Time} rampTime the time that it takes the \n\t * value to ramp from it's current value\n\t * @param {Time}\t[startTime=now] \tWhen the ramp should start. \n\t * @returns {Tone.Param} this\n\t * @example\n\t * //exponentially ramp to the value 2 over 4 seconds. \n\t * signal.exponentialRampToValue(2, 4);\n\t */\n\tTone.Param.prototype.exponentialRampToValue = function(value, rampTime, startTime){\n\t\tstartTime = this.toSeconds(startTime);\n\t\tthis.setRampPoint(startTime);\n\t\tthis.exponentialRampToValueAtTime(value, startTime + this.toSeconds(rampTime));\n\t\treturn this;\n\t};\n\n\t/**\n\t * Schedules an linear continuous change in parameter value from \n\t * the current time and current value to the given value over the \n\t * duration of the rampTime.\n\t * \n\t * @param {number} value The value to ramp to.\n\t * @param {Time} rampTime the time that it takes the \n\t * value to ramp from it's current value\n\t * @param {Time}\t[startTime=now] \tWhen the ramp should start. \n\t * @returns {Tone.Param} this\n\t * @example\n\t * //linearly ramp to the value 4 over 3 seconds. \n\t * signal.linearRampToValue(4, 3);\n\t */\n\tTone.Param.prototype.linearRampToValue = function(value, rampTime, startTime){\n\t\tstartTime = this.toSeconds(startTime);\n\t\tthis.setRampPoint(startTime);\n\t\tthis.linearRampToValueAtTime(value, startTime + this.toSeconds(rampTime));\n\t\treturn this;\n\t};\n\n\t/**\n\t * Start exponentially approaching the target value at the given time with\n\t * a rate having the given time constant.\n\t * @param {number} value \n\t * @param {Time} startTime \n\t * @param {number} timeConstant \n\t * @returns {Tone.Param} this \n\t */\n\tTone.Param.prototype.setTargetAtTime = function(value, startTime, timeConstant){\n\t\tvalue = this._fromUnits(value);\n\t\t// The value will never be able to approach without timeConstant > 0.\n\t\t// http://www.w3.org/TR/webaudio/#dfn-setTargetAtTime, where the equation\n\t\t// is described. 0 results in a division by 0.\n\t\tvalue = Math.max(this._minOutput, value);\n\t\ttimeConstant = Math.max(this._minOutput, timeConstant);\n\t\tthis._param.setTargetAtTime(value, this.toSeconds(startTime), timeConstant);\n\t\treturn this;\n\t};\n\n\t/**\n\t * Sets an array of arbitrary parameter values starting at the given time\n\t * for the given duration.\n\t * \t\n\t * @param {Array} values \n\t * @param {Time} startTime \n\t * @param {Time} duration \n\t * @returns {Tone.Param} this\n\t */\n\tTone.Param.prototype.setValueCurveAtTime = function(values, startTime, duration){\n\t\tfor (var i = 0; i < values.length; i++){\n\t\t\tvalues[i] = this._fromUnits(values[i]);\n\t\t}\n\t\tthis._param.setValueCurveAtTime(values, this.toSeconds(startTime), this.toSeconds(duration));\n\t\treturn this;\n\t};\n\n\t/**\n\t * Cancels all scheduled parameter changes with times greater than or \n\t * equal to startTime.\n\t * \n\t * @param {Time} startTime\n\t * @returns {Tone.Param} this\n\t */\n\tTone.Param.prototype.cancelScheduledValues = function(startTime){\n\t\tthis._param.cancelScheduledValues(this.toSeconds(startTime));\n\t\treturn this;\n\t};\n\n\t/**\n\t * Ramps to the given value over the duration of the rampTime. \n\t * Automatically selects the best ramp type (exponential or linear)\n\t * depending on the `units` of the signal\n\t * \n\t * @param {number} value \n\t * @param {Time} rampTime \tThe time that it takes the \n\t * value to ramp from it's current value\n\t * @param {Time}\t[startTime=now] \tWhen the ramp should start. \n\t * @returns {Tone.Param} this\n\t * @example\n\t * //ramp to the value either linearly or exponentially \n\t * //depending on the \"units\" value of the signal\n\t * signal.rampTo(0, 10);\n\t * @example\n\t * //schedule it to ramp starting at a specific time\n\t * signal.rampTo(0, 10, 5)\n\t */\n\tTone.Param.prototype.rampTo = function(value, rampTime, startTime){\n\t\trampTime = this.defaultArg(rampTime, 0);\n\t\tif (this.units === Tone.Type.Frequency || this.units === Tone.Type.BPM || this.units === Tone.Type.Decibels){\n\t\t\tthis.exponentialRampToValue(value, rampTime, startTime);\n\t\t} else {\n\t\t\tthis.linearRampToValue(value, rampTime, startTime);\n\t\t}\n\t\treturn this;\n\t};\n\n\t/**\n\t * The LFO created by the signal instance. If none\n\t * was created, this is null.\n\t * @type {Tone.LFO}\n\t * @readOnly\n\t * @memberOf Tone.Param#\n\t * @name lfo\n\t */\n\tObject.defineProperty(Tone.Param.prototype, \"lfo\", {\n\t\tget : function(){\n\t\t\treturn this._lfo;\n\t\t}\n\t});\n\n\t/**\n\t * Clean up\n\t * @returns {Tone.Param} this\n\t */\n\tTone.Param.prototype.dispose = function(){\n\t\tTone.prototype.dispose.call(this);\n\t\tthis._param = null;\n\t\tif (this._lfo){\n\t\t\tthis._lfo.dispose();\n\t\t\tthis._lfo = null;\n\t\t}\n\t\treturn this;\n\t};\n\n\treturn Tone.Param;\n});","'use strict';\n\ndefine(function (require) {\n var p5sound = require('master');\n\n var Add = require('Tone/signal/Add');\n var Mult = require('Tone/signal/Multiply');\n var Scale = require('Tone/signal/Scale');\n\n /**\n *
Creates a signal that oscillates between -1.0 and 1.0.\n * By default, the oscillation takes the form of a sinusoidal\n * shape ('sine'). Additional types include 'triangle',\n * 'sawtooth' and 'square'. The frequency defaults to\n * 440 oscillations per second (440Hz, equal to the pitch of an\n * 'A' note).
\n *\n * @class p5.Oscillator\n * @constructor\n * @param {Number} [freq] frequency defaults to 440Hz\n * @param {String} [type] type of oscillator. Options:\n * 'sine' (default), 'triangle',\n * 'sawtooth', 'square'\n * @example\n *
\n * var osc;\n * var playing = false;\n *\n * function setup() {\n * backgroundColor = color(255,0,255);\n * textAlign(CENTER);\n *\n * osc = new p5.Oscillator();\n * osc.setType('sine');\n * osc.freq(240);\n * osc.amp(0);\n * osc.start();\n * }\n *\n * function draw() {\n * background(backgroundColor)\n * text('click to play', width/2, height/2);\n * }\n *\n * function mouseClicked() {\n * if (mouseX > 0 && mouseX < width && mouseY < height && mouseY > 0) {\n * if (!playing) {\n * // ramp amplitude to 0.5 over 0.05 seconds\n * osc.amp(0.5, 0.05);\n * playing = true;\n * backgroundColor = color(0,255,255);\n * } else {\n * // ramp amplitude to 0 over 0.5 seconds\n * osc.amp(0, 0.5);\n * playing = false;\n * backgroundColor = color(255,0,255);\n * }\n * }\n * }\n *
\n */\n p5.Oscillator = function(freq, type) {\n if (typeof freq === 'string') {\n var f = type;\n type = freq;\n freq = f;\n } if (typeof type === 'number') {\n var f = type;\n type = freq;\n freq = f;\n }\n this.started = false;\n\n // components\n this.phaseAmount = undefined;\n this.oscillator = p5sound.audiocontext.createOscillator();\n this.f = freq || 440.0; // frequency\n this.oscillator.type = type || 'sine';\n this.oscillator.frequency.setValueAtTime(this.f, p5sound.audiocontext.currentTime);\n\n // connections\n this.output = p5sound.audiocontext.createGain();\n\n this._freqMods = []; // modulators connected to this oscillator's frequency\n\n // set default output gain to 0.5\n this.output.gain.value = 0.5;\n this.output.gain.setValueAtTime(0.5, p5sound.audiocontext.currentTime);\n\n this.oscillator.connect(this.output);\n // stereo panning\n this.panPosition = 0.0;\n this.connection = p5sound.input; // connect to p5sound by default\n this.panner = new p5.Panner(this.output, this.connection, 1);\n\n //array of math operation signal chaining\n this.mathOps = [this.output];\n\n // add to the soundArray so we can dispose of the osc later\n p5sound.soundArray.push(this);\n };\n\n /**\n * Start an oscillator. Accepts an optional parameter to\n * determine how long (in seconds from now) until the\n * oscillator starts.\n *\n * @method start\n * @for p5.Oscillator\n * @param {Number} [time] startTime in seconds from now.\n * @param {Number} [frequency] frequency in Hz.\n */\n p5.Oscillator.prototype.start = function(time, f) {\n if (this.started) {\n var now = p5sound.audiocontext.currentTime;\n this.stop(now);\n }\n if (!this.started) {\n var freq = f || this.f;\n var type = this.oscillator.type;\n\n // set old osc free to be garbage collected (memory)\n if (this.oscillator) {\n this.oscillator.disconnect();\n delete this.oscillator;\n }\n\n // var detune = this.oscillator.frequency.value;\n this.oscillator = p5sound.audiocontext.createOscillator();\n this.oscillator.frequency.value = Math.abs(freq);\n this.oscillator.type = type;\n // this.oscillator.detune.value = detune;\n this.oscillator.connect(this.output);\n time = time || 0;\n this.oscillator.start(time + p5sound.audiocontext.currentTime);\n this.freqNode = this.oscillator.frequency;\n\n // if other oscillators are already connected to this osc's freq\n for (var i in this._freqMods) {\n if (typeof this._freqMods[i].connect !== 'undefined') {\n this._freqMods[i].connect(this.oscillator.frequency);\n }\n }\n\n this.started = true;\n }\n };\n\n /**\n * Stop an oscillator. Accepts an optional parameter\n * to determine how long (in seconds from now) until the\n * oscillator stops.\n *\n * @method stop\n * @for p5.Oscillator\n * @param {Number} secondsFromNow Time, in seconds from now.\n */\n p5.Oscillator.prototype.stop = function(time) {\n if (this.started) {\n var t = time || 0;\n var now = p5sound.audiocontext.currentTime;\n this.oscillator.stop(t + now);\n this.started = false;\n }\n };\n\n /**\n * Set the amplitude between 0 and 1.0. Or, pass in an object\n * such as an oscillator to modulate amplitude with an audio signal.\n *\n * @method amp\n * @for p5.Oscillator\n * @param {Number|Object} vol between 0 and 1.0\n * or a modulating signal/oscillator\n * @param {Number} [rampTime] create a fade that lasts rampTime\n * @param {Number} [timeFromNow] schedule this event to happen\n * seconds from now\n * @return {AudioParam} gain If no value is provided,\n * returns the Web Audio API\n * AudioParam that controls\n * this oscillator's\n * gain/amplitude/volume)\n */\n p5.Oscillator.prototype.amp = function(vol, rampTime, tFromNow) {\n var self = this;\n if (typeof vol === 'number') {\n var rampTime = rampTime || 0;\n var tFromNow = tFromNow || 0;\n var now = p5sound.audiocontext.currentTime;\n this.output.gain.linearRampToValueAtTime(vol, now + tFromNow + rampTime);\n }\n\n else if (vol) {\n vol.connect(self.output.gain);\n } else {\n // return the Gain Node\n return this.output.gain;\n }\n };\n\n // these are now the same thing\n p5.Oscillator.prototype.fade = p5.Oscillator.prototype.amp;\n\n p5.Oscillator.prototype.getAmp = function() {\n return this.output.gain.value;\n };\n\n /**\n * Set frequency of an oscillator to a value. Or, pass in an object\n * such as an oscillator to modulate the frequency with an audio signal.\n *\n * @method freq\n * @for p5.Oscillator\n * @param {Number|Object} Frequency Frequency in Hz\n * or modulating signal/oscillator\n * @param {Number} [rampTime] Ramp time (in seconds)\n * @param {Number} [timeFromNow] Schedule this event to happen\n * at x seconds from now\n * @return {AudioParam} Frequency If no value is provided,\n * returns the Web Audio API\n * AudioParam that controls\n * this oscillator's frequency\n * @example\n *
\n * var osc = new p5.Oscillator(300);\n * osc.start();\n * osc.freq(40, 10);\n *
\n */\n p5.Oscillator.prototype.freq = function(val, rampTime, tFromNow) {\n if (typeof val === 'number' && !isNaN(val)) {\n this.f = val;\n var now = p5sound.audiocontext.currentTime;\n var rampTime = rampTime || 0;\n var tFromNow = tFromNow || 0;\n var t = now + tFromNow + rampTime;\n // var currentFreq = this.oscillator.frequency.value;\n // this.oscillator.frequency.cancelScheduledValues(now);\n\n if (rampTime === 0) {\n this.oscillator.frequency.setValueAtTime(val, tFromNow + now);\n } else {\n if (val > 0 ) {\n this.oscillator.frequency.exponentialRampToValueAtTime(val, tFromNow + rampTime + now);\n } else {\n this.oscillator.frequency.linearRampToValueAtTime(val, tFromNow + rampTime + now);\n }\n }\n\n // reset phase if oscillator has a phase\n if (this.phaseAmount) {\n this.phase(this.phaseAmount);\n }\n\n } else if (val) {\n if (val.output) {\n val = val.output;\n }\n val.connect(this.oscillator.frequency);\n\n // keep track of what is modulating this param\n // so it can be re-connected if\n this._freqMods.push( val );\n } else {\n // return the Frequency Node\n return this.oscillator.frequency;\n }\n };\n\n p5.Oscillator.prototype.getFreq = function() {\n return this.oscillator.frequency.value;\n };\n\n /**\n * Set type to 'sine', 'triangle', 'sawtooth' or 'square'.\n *\n * @method setType\n * @for p5.Oscillator\n * @param {String} type 'sine', 'triangle', 'sawtooth' or 'square'.\n */\n p5.Oscillator.prototype.setType = function(type) {\n this.oscillator.type = type;\n };\n\n p5.Oscillator.prototype.getType = function() {\n return this.oscillator.type;\n };\n\n /**\n * Connect to a p5.sound / Web Audio object.\n *\n * @method connect\n * @for p5.Oscillator\n * @param {Object} unit A p5.sound or Web Audio object\n */\n p5.Oscillator.prototype.connect = function(unit) {\n if (!unit) {\n this.panner.connect(p5sound.input);\n }\n else if (unit.hasOwnProperty('input')) {\n this.panner.connect(unit.input);\n this.connection = unit.input;\n }\n else {\n this.panner.connect(unit);\n this.connection = unit;\n }\n };\n\n /**\n * Disconnect all outputs\n *\n * @method disconnect\n * @for p5.Oscillator\n */\n p5.Oscillator.prototype.disconnect = function() {\n if (this.output) {\n this.output.disconnect();\n }\n if (this.panner) {\n this.panner.disconnect();\n if (this.output) {\n this.output.connect(this.panner);\n }\n }\n this.oscMods = [];\n };\n\n /**\n * Pan between Left (-1) and Right (1)\n *\n * @method pan\n * @for p5.Oscillator\n * @param {Number} panning Number between -1 and 1\n * @param {Number} timeFromNow schedule this event to happen\n * seconds from now\n */\n p5.Oscillator.prototype.pan = function(pval, tFromNow) {\n this.panPosition = pval;\n this.panner.pan(pval, tFromNow);\n };\n\n p5.Oscillator.prototype.getPan = function() {\n return this.panPosition;\n };\n\n // get rid of the oscillator\n p5.Oscillator.prototype.dispose = function() {\n // remove reference from soundArray\n var index = p5sound.soundArray.indexOf(this);\n p5sound.soundArray.splice(index, 1);\n\n if (this.oscillator) {\n var now = p5sound.audiocontext.currentTime;\n this.stop(now);\n this.disconnect();\n this.panner = null;\n this.oscillator = null;\n }\n // if it is a Pulse\n if (this.osc2) {\n this.osc2.dispose();\n }\n };\n\n /**\n * Set the phase of an oscillator between 0.0 and 1.0.\n * In this implementation, phase is a delay time\n * based on the oscillator's current frequency.\n *\n * @method phase\n * @for p5.Oscillator\n * @param {Number} phase float between 0.0 and 1.0\n */\n p5.Oscillator.prototype.phase = function(p) {\n var delayAmt = p5.prototype.map(p, 0, 1.0, 0, 1/this.f);\n var now = p5sound.audiocontext.currentTime;\n\n this.phaseAmount = p;\n\n if (!this.dNode) {\n // create a delay node\n this.dNode = p5sound.audiocontext.createDelay();\n // put the delay node in between output and panner\n this.oscillator.disconnect();\n this.oscillator.connect(this.dNode);\n this.dNode.connect(this.output);\n }\n\n // set delay time to match phase:\n this.dNode.delayTime.setValueAtTime(delayAmt, now);\n };\n\n // ========================== //\n // SIGNAL MATH FOR MODULATION //\n // ========================== //\n\n // return sigChain(this, scale, thisChain, nextChain, Scale);\n var sigChain = function(o, mathObj, thisChain, nextChain, type) {\n var chainSource = o.oscillator;\n // if this type of math already exists in the chain, replace it\n for (var i in o.mathOps) {\n if (o.mathOps[i] instanceof type) {\n chainSource.disconnect();\n o.mathOps[i].dispose();\n thisChain = i;\n // assume nextChain is output gain node unless...\n if (thisChain < o.mathOps.length - 2) {\n nextChain = o.mathOps[i+1];\n }\n }\n }\n if (thisChain === o.mathOps.length - 1) {\n o.mathOps.push(nextChain);\n }\n // assume source is the oscillator unless i > 0\n if (i > 0) {\n chainSource = o.mathOps[i-1];\n }\n chainSource.disconnect();\n chainSource.connect(mathObj);\n mathObj.connect(nextChain);\n o.mathOps[thisChain] = mathObj;\n return o;\n };\n\n /**\n * Add a value to the p5.Oscillator's output amplitude,\n * and return the oscillator. Calling this method again\n * will override the initial add() with a new value.\n *\n * @method add\n * @for p5.Oscillator\n * @param {Number} number Constant number to add\n * @return {p5.Oscillator} Oscillator Returns this oscillator\n * with scaled output\n *\n */\n p5.Oscillator.prototype.add = function(num) {\n var add = new Add(num);\n var thisChain = this.mathOps.length-1;\n var nextChain = this.output;\n return sigChain(this, add, thisChain, nextChain, Add);\n };\n\n /**\n * Multiply the p5.Oscillator's output amplitude\n * by a fixed value (i.e. turn it up!). Calling this method\n * again will override the initial mult() with a new value.\n *\n * @method mult\n * @for p5.Oscillator\n * @param {Number} number Constant number to multiply\n * @return {p5.Oscillator} Oscillator Returns this oscillator\n * with multiplied output\n */\n p5.Oscillator.prototype.mult = function(num) {\n var mult = new Mult(num);\n var thisChain = this.mathOps.length-1;\n var nextChain = this.output;\n return sigChain(this, mult, thisChain, nextChain, Mult);\n };\n\n /**\n * Scale this oscillator's amplitude values to a given\n * range, and return the oscillator. Calling this method\n * again will override the initial scale() with new values.\n *\n * @method scale\n * @for p5.Oscillator\n * @param {Number} inMin input range minumum\n * @param {Number} inMax input range maximum\n * @param {Number} outMin input range minumum\n * @param {Number} outMax input range maximum\n * @return {p5.Oscillator} Oscillator Returns this oscillator\n * with scaled output\n */\n p5.Oscillator.prototype.scale = function(inMin, inMax, outMin, outMax) {\n var mapOutMin, mapOutMax;\n if (arguments.length === 4) {\n mapOutMin = p5.prototype.map(outMin, inMin, inMax, 0, 1) - 0.5;\n mapOutMax = p5.prototype.map(outMax, inMin, inMax, 0, 1) - 0.5;\n }\n else {\n mapOutMin = arguments[0];\n mapOutMax = arguments[1];\n }\n var scale = new Scale(mapOutMin, mapOutMax);\n var thisChain = this.mathOps.length-1;\n var nextChain = this.output;\n return sigChain(this, scale, thisChain, nextChain, Scale);\n\n // this.output.disconnect();\n // this.output.connect(scale)\n };\n\n // ============================== //\n // SinOsc, TriOsc, SqrOsc, SawOsc //\n // ============================== //\n\n /**\n * Constructor: new p5.SinOsc().\n * This creates a Sine Wave Oscillator and is\n * equivalent to new p5.Oscillator('sine')\n * or creating a p5.Oscillator and then calling\n * its method setType('sine').\n * See p5.Oscillator for methods.\n *\n * @class p5.SinOsc\n * @constructor\n * @extends p5.Oscillator\n * @param {Number} [freq] Set the frequency\n */\n p5.SinOsc = function(freq) {\n p5.Oscillator.call(this, freq, 'sine');\n };\n\n p5.SinOsc.prototype = Object.create(p5.Oscillator.prototype);\n\n /**\n * Constructor: new p5.TriOsc().\n * This creates a Triangle Wave Oscillator and is\n * equivalent to new p5.Oscillator('triangle')\n * or creating a p5.Oscillator and then calling\n * its method setType('triangle').\n * See p5.Oscillator for methods.\n *\n * @class p5.TriOsc\n * @constructor\n * @extends p5.Oscillator\n * @param {Number} [freq] Set the frequency\n */\n p5.TriOsc = function(freq) {\n p5.Oscillator.call(this, freq, 'triangle');\n };\n\n p5.TriOsc.prototype = Object.create(p5.Oscillator.prototype);\n\n /**\n * Constructor: new p5.SawOsc().\n * This creates a SawTooth Wave Oscillator and is\n * equivalent to new p5.Oscillator('sawtooth')\n * or creating a p5.Oscillator and then calling\n * its method setType('sawtooth').\n * See p5.Oscillator for methods.\n *\n * @class p5.SawOsc\n * @constructor\n * @extends p5.Oscillator\n * @param {Number} [freq] Set the frequency\n */\n p5.SawOsc = function(freq) {\n p5.Oscillator.call(this, freq, 'sawtooth');\n };\n\n p5.SawOsc.prototype = Object.create(p5.Oscillator.prototype);\n\n /**\n * Constructor: new p5.SqrOsc().\n * This creates a Square Wave Oscillator and is\n * equivalent to new p5.Oscillator('square')\n * or creating a p5.Oscillator and then calling\n * its method setType('square').\n * See p5.Oscillator for methods.\n *\n * @class p5.SqrOsc\n * @constructor\n * @extends p5.Oscillator\n * @param {Number} [freq] Set the frequency\n */\n p5.SqrOsc = function(freq) {\n p5.Oscillator.call(this, freq, 'square');\n };\n\n p5.SqrOsc.prototype = Object.create(p5.Oscillator.prototype);\n\n});\n","define([\"Tone/core/Tone\", \"Tone/type/Type\"], function (Tone) {\n\n\t\"use strict\";\n\n\t/**\n\t * @class A Timeline class for scheduling and maintaining state\n\t * along a timeline. All events must have a \"time\" property. \n\t * Internally, events are stored in time order for fast \n\t * retrieval.\n\t * @extends {Tone}\n\t * @param {Positive} [memory=Infinity] The number of previous events that are retained.\n\t */\n\tTone.Timeline = function(){\n\n\t\tvar options = this.optionsObject(arguments, [\"memory\"], Tone.Timeline.defaults);\n\n\t\t/**\n\t\t * The array of scheduled timeline events\n\t\t * @type {Array}\n\t\t * @private\n\t\t */\n\t\tthis._timeline = [];\n\n\t\t/**\n\t\t * An array of items to remove from the list. \n\t\t * @type {Array}\n\t\t * @private\n\t\t */\n\t\tthis._toRemove = [];\n\n\t\t/**\n\t\t * Flag if the tieline is mid iteration\n\t\t * @private\n\t\t * @type {Boolean}\n\t\t */\n\t\tthis._iterating = false;\n\n\t\t/**\n\t\t * The memory of the timeline, i.e.\n\t\t * how many events in the past it will retain\n\t\t * @type {Positive}\n\t\t */\n\t\tthis.memory = options.memory;\n\t};\n\n\tTone.extend(Tone.Timeline);\n\n\t/**\n\t * the default parameters\n\t * @static\n\t * @const\n\t */\n\tTone.Timeline.defaults = {\n\t\t\"memory\" : Infinity\n\t};\n\n\t/**\n\t * The number of items in the timeline.\n\t * @type {Number}\n\t * @memberOf Tone.Timeline#\n\t * @name length\n\t * @readOnly\n\t */\n\tObject.defineProperty(Tone.Timeline.prototype, \"length\", {\n\t\tget : function(){\n\t\t\treturn this._timeline.length;\n\t\t}\n\t});\n\n\t/**\n\t * Insert an event object onto the timeline. Events must have a \"time\" attribute.\n\t * @param {Object} event The event object to insert into the \n\t * timeline. \n\t * @returns {Tone.Timeline} this\n\t */\n\tTone.Timeline.prototype.add = function(event){\n\t\t//the event needs to have a time attribute\n\t\tif (this.isUndef(event.time)){\n\t\t\tthrow new Error(\"Tone.Timeline: events must have a time attribute\");\n\t\t}\n\t\tif (this._timeline.length){\n\t\t\tvar index = this._search(event.time);\n\t\t\tthis._timeline.splice(index + 1, 0, event);\n\t\t} else {\n\t\t\tthis._timeline.push(event);\t\t\t\n\t\t}\n\t\t//if the length is more than the memory, remove the previous ones\n\t\tif (this.length > this.memory){\n\t\t\tvar diff = this.length - this.memory;\n\t\t\tthis._timeline.splice(0, diff);\n\t\t}\n\t\treturn this;\n\t};\n\n\t/**\n\t * Remove an event from the timeline.\n\t * @param {Object} event The event object to remove from the list.\n\t * @returns {Tone.Timeline} this\n\t */\n\tTone.Timeline.prototype.remove = function(event){\n\t\tif (this._iterating){\n\t\t\tthis._toRemove.push(event);\n\t\t} else {\n\t\t\tvar index = this._timeline.indexOf(event);\n\t\t\tif (index !== -1){\n\t\t\t\tthis._timeline.splice(index, 1);\n\t\t\t}\n\t\t}\n\t\treturn this;\n\t};\n\n\t/**\n\t * Get the nearest event whose time is less than or equal to the given time.\n\t * @param {Number} time The time to query.\n\t * @returns {Object} The event object set after that time.\n\t */\n\tTone.Timeline.prototype.get = function(time){\n\t\tvar index = this._search(time);\n\t\tif (index !== -1){\n\t\t\treturn this._timeline[index];\n\t\t} else {\n\t\t\treturn null;\n\t\t}\n\t};\n\n\t/**\n\t * Return the first event in the timeline without removing it\n\t * @returns {Object} The first event object\n\t */\n\tTone.Timeline.prototype.peek = function(){\n\t\treturn this._timeline[0];\n\t};\n\n\t/**\n\t * Return the first event in the timeline and remove it\n\t * @returns {Object} The first event object\n\t */\n\tTone.Timeline.prototype.shift = function(){\n\t\treturn this._timeline.shift();\n\t};\n\n\t/**\n\t * Get the event which is scheduled after the given time.\n\t * @param {Number} time The time to query.\n\t * @returns {Object} The event object after the given time\n\t */\n\tTone.Timeline.prototype.getAfter = function(time){\n\t\tvar index = this._search(time);\n\t\tif (index + 1 < this._timeline.length){\n\t\t\treturn this._timeline[index + 1];\n\t\t} else {\n\t\t\treturn null;\n\t\t}\n\t};\n\n\t/**\n\t * Get the event before the event at the given time.\n\t * @param {Number} time The time to query.\n\t * @returns {Object} The event object before the given time\n\t */\n\tTone.Timeline.prototype.getBefore = function(time){\n\t\tvar len = this._timeline.length;\n\t\t//if it's after the last item, return the last item\n\t\tif (len > 0 && this._timeline[len - 1].time < time){\n\t\t\treturn this._timeline[len - 1];\n\t\t}\n\t\tvar index = this._search(time);\n\t\tif (index - 1 >= 0){\n\t\t\treturn this._timeline[index - 1];\n\t\t} else {\n\t\t\treturn null;\n\t\t}\n\t};\n\n\t/**\n\t * Cancel events after the given time\n\t * @param {Number} time The time to query.\n\t * @returns {Tone.Timeline} this\n\t */\n\tTone.Timeline.prototype.cancel = function(after){\n\t\tif (this._timeline.length > 1){\n\t\t\tvar index = this._search(after);\n\t\t\tif (index >= 0){\n\t\t\t\tif (this._timeline[index].time === after){\n\t\t\t\t\t//get the first item with that time\n\t\t\t\t\tfor (var i = index; i >= 0; i--){\n\t\t\t\t\t\tif (this._timeline[i].time === after){\n\t\t\t\t\t\t\tindex = i;\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tthis._timeline = this._timeline.slice(0, index);\n\t\t\t\t} else {\n\t\t\t\t\tthis._timeline = this._timeline.slice(0, index + 1);\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tthis._timeline = [];\n\t\t\t}\n\t\t} else if (this._timeline.length === 1){\n\t\t\t//the first item's time\n\t\t\tif (this._timeline[0].time >= after){\n\t\t\t\tthis._timeline = [];\n\t\t\t}\n\t\t}\n\t\treturn this;\n\t};\n\n\t/**\n\t * Cancel events before or equal to the given time.\n\t * @param {Number} time The time to cancel before.\n\t * @returns {Tone.Timeline} this\n\t */\n\tTone.Timeline.prototype.cancelBefore = function(time){\n\t\tif (this._timeline.length){\n\t\t\tvar index = this._search(time);\n\t\t\tif (index >= 0){\n\t\t\t\tthis._timeline = this._timeline.slice(index + 1);\n\t\t\t}\n\t\t}\n\t\treturn this;\n\t};\n\n\t/**\n\t * Does a binary serach on the timeline array and returns the \n\t * nearest event index whose time is after or equal to the given time.\n\t * If a time is searched before the first index in the timeline, -1 is returned.\n\t * If the time is after the end, the index of the last item is returned.\n\t * @param {Number} time \n\t * @return {Number} the index in the timeline array \n\t * @private\n\t */\n\tTone.Timeline.prototype._search = function(time){\n\t\tvar beginning = 0;\n\t\tvar len = this._timeline.length;\n\t\tvar end = len;\n\t\tif (len > 0 && this._timeline[len - 1].time <= time){\n\t\t\treturn len - 1;\n\t\t}\n\t\twhile (beginning < end){\n\t\t\t// calculate the midpoint for roughly equal partition\n\t\t\tvar midPoint = Math.floor(beginning + (end - beginning) / 2);\n\t\t\tvar event = this._timeline[midPoint];\n\t\t\tvar nextEvent = this._timeline[midPoint + 1];\n\t\t\tif (event.time === time){\n\t\t\t\t//choose the last one that has the same time\n\t\t\t\tfor (var i = midPoint; i < this._timeline.length; i++){\n\t\t\t\t\tvar testEvent = this._timeline[i];\n\t\t\t\t\tif (testEvent.time === time){\n\t\t\t\t\t\tmidPoint = i;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\treturn midPoint;\n\t\t\t} else if (event.time < time && nextEvent.time > time){\n\t\t\t\treturn midPoint;\n\t\t\t} else if (event.time > time){\n\t\t\t\t//search lower\n\t\t\t\tend = midPoint;\n\t\t\t} else if (event.time < time){\n\t\t\t\t//search upper\n\t\t\t\tbeginning = midPoint + 1;\n\t\t\t} \n\t\t}\n\t\treturn -1;\n\t};\n\n\t/**\n\t * Internal iterator. Applies extra safety checks for \n\t * removing items from the array. \n\t * @param {Function} callback \n\t * @param {Number=} lowerBound \n\t * @param {Number=} upperBound \n\t * @private\n\t */\n\tTone.Timeline.prototype._iterate = function(callback, lowerBound, upperBound){\n\t\tthis._iterating = true;\n\t\tlowerBound = this.defaultArg(lowerBound, 0);\n\t\tupperBound = this.defaultArg(upperBound, this._timeline.length - 1);\n\t\tfor (var i = lowerBound; i <= upperBound; i++){\n\t\t\tcallback(this._timeline[i]);\n\t\t}\n\t\tthis._iterating = false;\n\t\tif (this._toRemove.length > 0){\n\t\t\tfor (var j = 0; j < this._toRemove.length; j++){\n\t\t\t\tvar index = this._timeline.indexOf(this._toRemove[j]);\n\t\t\t\tif (index !== -1){\n\t\t\t\t\tthis._timeline.splice(index, 1);\n\t\t\t\t}\n\t\t\t}\n\t\t\tthis._toRemove = [];\n\t\t}\n\t};\n\n\t/**\n\t * Iterate over everything in the array\n\t * @param {Function} callback The callback to invoke with every item\n\t * @returns {Tone.Timeline} this\n\t */\n\tTone.Timeline.prototype.forEach = function(callback){\n\t\tthis._iterate(callback);\n\t\treturn this;\n\t};\n\n\t/**\n\t * Iterate over everything in the array at or before the given time.\n\t * @param {Number} time The time to check if items are before\n\t * @param {Function} callback The callback to invoke with every item\n\t * @returns {Tone.Timeline} this\n\t */\n\tTone.Timeline.prototype.forEachBefore = function(time, callback){\n\t\t//iterate over the items in reverse so that removing an item doesn't break things\n\t\tvar upperBound = this._search(time);\n\t\tif (upperBound !== -1){\n\t\t\tthis._iterate(callback, 0, upperBound);\n\t\t}\n\t\treturn this;\n\t};\n\n\t/**\n\t * Iterate over everything in the array after the given time.\n\t * @param {Number} time The time to check if items are before\n\t * @param {Function} callback The callback to invoke with every item\n\t * @returns {Tone.Timeline} this\n\t */\n\tTone.Timeline.prototype.forEachAfter = function(time, callback){\n\t\t//iterate over the items in reverse so that removing an item doesn't break things\n\t\tvar lowerBound = this._search(time);\n\t\tthis._iterate(callback, lowerBound + 1);\n\t\treturn this;\n\t};\n\n\t/**\n\t * Iterate over everything in the array at or after the given time. Similar to \n\t * forEachAfter, but includes the item(s) at the given time.\n\t * @param {Number} time The time to check if items are before\n\t * @param {Function} callback The callback to invoke with every item\n\t * @returns {Tone.Timeline} this\n\t */\n\tTone.Timeline.prototype.forEachFrom = function(time, callback){\n\t\t//iterate over the items in reverse so that removing an item doesn't break things\n\t\tvar lowerBound = this._search(time);\n\t\t//work backwards until the event time is less than time\n\t\twhile (lowerBound >= 0 && this._timeline[lowerBound].time >= time){\n\t\t\tlowerBound--;\n\t\t}\n\t\tthis._iterate(callback, lowerBound + 1);\n\t\treturn this;\n\t};\n\n\t/**\n\t * Iterate over everything in the array at the given time\n\t * @param {Number} time The time to check if items are before\n\t * @param {Function} callback The callback to invoke with every item\n\t * @returns {Tone.Timeline} this\n\t */\n\tTone.Timeline.prototype.forEachAtTime = function(time, callback){\n\t\t//iterate over the items in reverse so that removing an item doesn't break things\n\t\tvar upperBound = this._search(time);\n\t\tif (upperBound !== -1){\n\t\t\tthis._iterate(function(event){\n\t\t\t\tif (event.time === time){\n\t\t\t\t\tcallback(event);\n\t\t\t\t} \n\t\t\t}, 0, upperBound);\n\t\t}\n\t\treturn this;\n\t};\n\n\t/**\n\t * Clean up.\n\t * @return {Tone.Timeline} this\n\t */\n\tTone.Timeline.prototype.dispose = function(){\n\t\tTone.prototype.dispose.call(this);\n\t\tthis._timeline = null;\n\t\tthis._toRemove = null;\n\t};\n\n\treturn Tone.Timeline;\n});","define([\"Tone/core/Tone\", \"Tone/signal/Multiply\", \"Tone/signal/Signal\"], function(Tone){\n\n\t\"use strict\";\n\n\t/**\n\t * @class Negate the incoming signal. i.e. an input signal of 10 will output -10\n\t *\n\t * @constructor\n\t * @extends {Tone.SignalBase}\n\t * @example\n\t * var neg = new Tone.Negate();\n\t * var sig = new Tone.Signal(-2).connect(neg);\n\t * //output of neg is positive 2. \n\t */\n\tTone.Negate = function(){\n\t\t/**\n\t\t * negation is done by multiplying by -1\n\t\t * @type {Tone.Multiply}\n\t\t * @private\n\t\t */\n\t\tthis._multiply = this.input = this.output = new Tone.Multiply(-1);\n\t};\n\n\tTone.extend(Tone.Negate, Tone.SignalBase);\n\n\t/**\n\t * clean up\n\t * @returns {Tone.Negate} this\n\t */\n\tTone.Negate.prototype.dispose = function(){\n\t\tTone.prototype.dispose.call(this);\n\t\tthis._multiply.dispose();\n\t\tthis._multiply = null;\n\t\treturn this;\n\t}; \n\n\treturn Tone.Negate;\n});","define([\"Tone/core/Tone\", \"Tone/signal/Signal\", \"Tone/signal/Multiply\", \"Tone/signal/WaveShaper\"], \nfunction(Tone){\n\n\t\"use strict\";\n\n\t/**\n\t * @class GreaterThanZero outputs 1 when the input is strictly greater than zero\n\t * \n\t * @constructor\n\t * @extends {Tone.SignalBase}\n\t * @example\n\t * var gt0 = new Tone.GreaterThanZero();\n\t * var sig = new Tone.Signal(0.01).connect(gt0);\n\t * //the output of gt0 is 1. \n\t * sig.value = 0;\n\t * //the output of gt0 is 0. \n\t */\n\tTone.GreaterThanZero = function(){\n\t\t\n\t\t/**\n\t\t * @type {Tone.WaveShaper}\n\t\t * @private\n\t\t */\n\t\tthis._thresh = this.output = new Tone.WaveShaper(function(val){\n\t\t\tif (val <= 0){\n\t\t\t\treturn 0;\n\t\t\t} else {\n\t\t\t\treturn 1;\n\t\t\t}\n\t\t}, 127);\n\n\t\t/**\n\t\t * scale the first thresholded signal by a large value.\n\t\t * this will help with values which are very close to 0\n\t\t * @type {Tone.Multiply}\n\t\t * @private\n\t\t */\n\t\tthis._scale = this.input = new Tone.Multiply(10000);\n\n\t\t//connections\n\t\tthis._scale.connect(this._thresh);\n\t};\n\n\tTone.extend(Tone.GreaterThanZero, Tone.SignalBase);\n\n\t/**\n\t * dispose method\n\t * @returns {Tone.GreaterThanZero} this\n\t */\n\tTone.GreaterThanZero.prototype.dispose = function(){\n\t\tTone.prototype.dispose.call(this);\n\t\tthis._scale.dispose();\n\t\tthis._scale = null;\n\t\tthis._thresh.dispose();\n\t\tthis._thresh = null;\n\t\treturn this;\n\t};\n\n\treturn Tone.GreaterThanZero;\n});","define([\"Tone/core/Tone\", \"Tone/signal/TimelineSignal\", \"Tone/core/TimelineState\", \n\t\"Tone/core/Emitter\", \"Tone/core/Context\"], function (Tone) {\n\n\t\"use strict\";\n\n\t/**\n\t * @class A sample accurate clock which provides a callback at the given rate. \n\t * While the callback is not sample-accurate (it is still susceptible to\n\t * loose JS timing), the time passed in as the argument to the callback\n\t * is precise. For most applications, it is better to use Tone.Transport\n\t * instead of the Clock by itself since you can synchronize multiple callbacks.\n\t *\n\t * \t@constructor\n\t * @extends {Tone.Emitter}\n\t * \t@param {function} callback The callback to be invoked with the time of the audio event\n\t * \t@param {Frequency} frequency The rate of the callback\n\t * \t@example\n\t * //the callback will be invoked approximately once a second\n\t * //and will print the time exactly once a second apart.\n\t * var clock = new Tone.Clock(function(time){\n\t * \tconsole.log(time);\n\t * }, 1);\n\t */\n\tTone.Clock = function(){\n\n\t\tTone.Emitter.call(this);\n\n\t\tvar options = this.optionsObject(arguments, [\"callback\", \"frequency\"], Tone.Clock.defaults);\n\n\t\t/**\n\t\t * The callback function to invoke at the scheduled tick.\n\t\t * @type {Function}\n\t\t */\n\t\tthis.callback = options.callback;\n\n\t\t/**\n\t\t * The next time the callback is scheduled.\n\t\t * @type {Number}\n\t\t * @private\n\t\t */\n\t\tthis._nextTick = 0;\n\n\t\t/**\n\t\t * The last state of the clock.\n\t\t * @type {State}\n\t\t * @private\n\t\t */\n\t\tthis._lastState = Tone.State.Stopped;\n\n\t\t/**\n\t\t * The rate the callback function should be invoked. \n\t\t * @type {BPM}\n\t\t * @signal\n\t\t */\n\t\tthis.frequency = new Tone.TimelineSignal(options.frequency, Tone.Type.Frequency);\n\t\tthis._readOnly(\"frequency\");\n\n\t\t/**\n\t\t * The number of times the callback was invoked. Starts counting at 0\n\t\t * and increments after the callback was invoked. \n\t\t * @type {Ticks}\n\t\t * @readOnly\n\t\t */\n\t\tthis.ticks = 0;\n\n\t\t/**\n\t\t * The state timeline\n\t\t * @type {Tone.TimelineState}\n\t\t * @private\n\t\t */\n\t\tthis._state = new Tone.TimelineState(Tone.State.Stopped);\n\n\t\t/**\n\t\t * The loop function bound to its context. \n\t\t * This is necessary to remove the event in the end.\n\t\t * @type {Function}\n\t\t * @private\n\t\t */\n\t\tthis._boundLoop = this._loop.bind(this);\n\n\t\t//bind a callback to the worker thread\n \tthis.context.on(\"tick\", this._boundLoop);\n\t};\n\n\tTone.extend(Tone.Clock, Tone.Emitter);\n\n\t/**\n\t * The defaults\n\t * @const\n\t * @type {Object}\n\t */\n\tTone.Clock.defaults = {\n\t\t\"callback\" : Tone.noOp,\n\t\t\"frequency\" : 1,\n\t\t\"lookAhead\" : \"auto\",\n\t};\n\n\t/**\n\t * Returns the playback state of the source, either \"started\", \"stopped\" or \"paused\".\n\t * @type {Tone.State}\n\t * @readOnly\n\t * @memberOf Tone.Clock#\n\t * @name state\n\t */\n\tObject.defineProperty(Tone.Clock.prototype, \"state\", {\n\t\tget : function(){\n\t\t\treturn this._state.getValueAtTime(this.now());\n\t\t}\n\t});\n\n\t/**\n\t * Start the clock at the given time. Optionally pass in an offset\n\t * of where to start the tick counter from.\n\t * @param {Time} time The time the clock should start\n\t * @param {Ticks=} offset Where the tick counter starts counting from.\n\t * @return {Tone.Clock} this\n\t */\n\tTone.Clock.prototype.start = function(time, offset){\n\t\ttime = this.toSeconds(time);\n\t\tif (this._state.getValueAtTime(time) !== Tone.State.Started){\n\t\t\tthis._state.add({\n\t\t\t\t\"state\" : Tone.State.Started, \n\t\t\t\t\"time\" : time,\n\t\t\t\t\"offset\" : offset\n\t\t\t});\n\t\t}\n\t\treturn this;\t\n\t};\n\n\t/**\n\t * Stop the clock. Stopping the clock resets the tick counter to 0.\n\t * @param {Time} [time=now] The time when the clock should stop.\n\t * @returns {Tone.Clock} this\n\t * @example\n\t * clock.stop();\n\t */\n\tTone.Clock.prototype.stop = function(time){\n\t\ttime = this.toSeconds(time);\n\t\tthis._state.cancel(time);\n\t\tthis._state.setStateAtTime(Tone.State.Stopped, time);\n\t\treturn this;\t\n\t};\n\n\n\t/**\n\t * Pause the clock. Pausing does not reset the tick counter.\n\t * @param {Time} [time=now] The time when the clock should stop.\n\t * @returns {Tone.Clock} this\n\t */\n\tTone.Clock.prototype.pause = function(time){\n\t\ttime = this.toSeconds(time);\n\t\tif (this._state.getValueAtTime(time) === Tone.State.Started){\n\t\t\tthis._state.setStateAtTime(Tone.State.Paused, time);\n\t\t}\n\t\treturn this;\t\n\t};\n\n\t/**\n\t * The scheduling loop.\n\t * @param {Number} time The current page time starting from 0\n\t * when the page was loaded.\n\t * @private\n\t */\n\tTone.Clock.prototype._loop = function(){\n\t\t//get the frequency value to compute the value of the next loop\n\t\tvar now = this.now();\n\t\t//if it's started\n\t\tvar lookAhead = this.context.lookAhead;\n\t\tvar updateInterval = this.context.updateInterval;\n\t\tvar lagCompensation = this.context.lag * 2;\n\t\tvar loopInterval = now + lookAhead + updateInterval + lagCompensation;\n\t\twhile (loopInterval > this._nextTick && this._state){\n\t\t\tvar currentState = this._state.getValueAtTime(this._nextTick);\n\t\t\tif (currentState !== this._lastState){\n\t\t\t\tthis._lastState = currentState;\n\t\t\t\tvar event = this._state.get(this._nextTick);\n\t\t\t\t// emit an event\n\t\t\t\tif (currentState === Tone.State.Started){\n\t\t\t\t\t//correct the time\n\t\t\t\t\tthis._nextTick = event.time;\n\t\t\t\t\tif (!this.isUndef(event.offset)){\n\t\t\t\t\t\tthis.ticks = event.offset;\n\t\t\t\t\t}\n\t\t\t\t\tthis.emit(\"start\", event.time, this.ticks);\n\t\t\t\t} else if (currentState === Tone.State.Stopped){\n\t\t\t\t\tthis.ticks = 0;\n\n\t\t\t\t\tthis.emit(\"stop\", event.time);\n\t\t\t\t} else if (currentState === Tone.State.Paused){\n\t\t\t\t\tthis.emit(\"pause\", event.time);\n\t\t\t\t}\n\t\t\t}\n\t\t\tvar tickTime = this._nextTick;\n\t\t\tif (this.frequency){\n\t\t\t\tthis._nextTick += 1 / this.frequency.getValueAtTime(this._nextTick);\n\t\t\t\tif (currentState === Tone.State.Started){\n\t\t\t\t\tthis.callback(tickTime);\n\t\t\t\t\tthis.ticks++;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t};\n\n\t/**\n\t * Returns the scheduled state at the given time.\n\t * @param {Time} time The time to query.\n\t * @return {String} The name of the state input in setStateAtTime.\n\t * @example\n\t * clock.start(\"+0.1\");\n\t * clock.getStateAtTime(\"+0.1\"); //returns \"started\"\n\t */\n\tTone.Clock.prototype.getStateAtTime = function(time){\n\t\ttime = this.toSeconds(time);\n\t\treturn this._state.getValueAtTime(time);\n\t};\n\n\t/**\n\t * Clean up\n\t * @returns {Tone.Clock} this\n\t */\n\tTone.Clock.prototype.dispose = function(){\n\t\tTone.Emitter.prototype.dispose.call(this);\n\t\tthis.context.off(\"tick\", this._boundLoop);\n\t\tthis._writable(\"frequency\");\n\t\tthis.frequency.dispose();\n\t\tthis.frequency = null;\n\t\tthis._boundLoop = null;\n\t\tthis._nextTick = Infinity;\n\t\tthis.callback = null;\n\t\tthis._state.dispose();\n\t\tthis._state = null;\n\t};\n\n\treturn Tone.Clock;\n});","'use strict';\ndefine(function (require) {\n\n var p5sound = require('master');\n var AudioVoice = require('audioVoice');\n var noteToFreq = require('helpers').noteToFreq;\n\n var DEFAULT_SUSTAIN = 0.15;\n\n /**\n * A MonoSynth is used as a single voice for sound synthesis.\n * This is a class to be used in conjunction with the PolySynth\n * class. Custom synthetisers should be built inheriting from\n * this class.\n *\n * @class p5.MonoSynth\n * @constructor\n * @example\n *
\n * var monoSynth;\n *\n * function setup() {\n * var cnv = createCanvas(100, 100);\n * cnv.mousePressed(playSynth);\n *\n * monoSynth = new p5.MonoSynth();\n *\n * textAlign(CENTER);\n * text('click to play', width/2, height/2);\n * }\n *\n * function playSynth() {\n * // time from now (in seconds)\n * var time = 0;\n * // note duration (in seconds)\n * var dur = 0.25;\n * // velocity (volume, from 0 to 1)\n * var v = 0.2;\n *\n * monoSynth.play(\"G3\", v, time, dur);\n * monoSynth.play(\"C4\", v, time += dur, dur);\n *\n * background(random(255), random(255), 255);\n * text('click to play', width/2, height/2);\n * }\n *
\n **/\n\n p5.MonoSynth = function () {\n AudioVoice.call(this);\n\n this.oscillator = new p5.Oscillator();\n\n this.env = new p5.Envelope();\n this.env.setRange(1, 0);\n this.env.setExp(true);\n\n //set params\n this.setADSR(0.02, 0.25, 0.05, 0.35);\n\n // oscillator --> env --> this.output (gain) --> p5.soundOut\n this.oscillator.disconnect();\n this.oscillator.connect(this.output);\n\n this.env.disconnect();\n this.env.setInput(this.output.gain);\n\n // reset oscillator gain to 1.0\n this.oscillator.output.gain.value = 1.0;\n\n this.oscillator.start();\n this.connect();\n\n p5sound.soundArray.push(this);\n };\n\n p5.MonoSynth.prototype = Object.create(p5.AudioVoice.prototype);\n\n /**\n * Play tells the MonoSynth to start playing a note. This method schedules\n * the calling of .triggerAttack and .triggerRelease.\n *\n * @method play\n * @for p5.MonoSynth\n * @param {String | Number} note the note you want to play, specified as a\n * frequency in Hertz (Number) or as a midi\n * value in Note/Octave format (\"C4\", \"Eb3\"...etc\")\n * See \n * Tone. Defaults to 440 hz.\n * @param {Number} [velocity] velocity of the note to play (ranging from 0 to 1)\n * @param {Number} [secondsFromNow] time from now (in seconds) at which to play\n * @param {Number} [sustainTime] time to sustain before releasing the envelope\n * @example\n *
\n * var monoSynth;\n *\n * function setup() {\n * var cnv = createCanvas(100, 100);\n * cnv.mousePressed(playSynth);\n *\n * monoSynth = new p5.MonoSynth();\n *\n * textAlign(CENTER);\n * text('click to play', width/2, height/2);\n * }\n *\n * function playSynth() {\n * // time from now (in seconds)\n * var time = 0;\n * // note duration (in seconds)\n * var dur = 1/6;\n * // note velocity (volume, from 0 to 1)\n * var v = random();\n *\n * monoSynth.play(\"Fb3\", v, 0, dur);\n * monoSynth.play(\"Gb3\", v, time += dur, dur);\n *\n * background(random(255), random(255), 255);\n * text('click to play', width/2, height/2);\n * }\n *
\n *\n */\n p5.MonoSynth.prototype.play = function (note, velocity, secondsFromNow, susTime) {\n this.triggerAttack(note, velocity, ~~secondsFromNow);\n this.triggerRelease(~~secondsFromNow + (susTime || DEFAULT_SUSTAIN));\n };\n\n /**\n * Trigger the Attack, and Decay portion of the Envelope.\n * Similar to holding down a key on a piano, but it will\n * hold the sustain level until you let go.\n *\n * @param {String | Number} note the note you want to play, specified as a\n * frequency in Hertz (Number) or as a midi\n * value in Note/Octave format (\"C4\", \"Eb3\"...etc\")\n * See \n * Tone. Defaults to 440 hz\n * @param {Number} [velocity] velocity of the note to play (ranging from 0 to 1)\n * @param {Number} [secondsFromNow] time from now (in seconds) at which to play\n * @method triggerAttack\n * @for p5.MonoSynth\n * @example\n *
\n * var monoSynth = new p5.MonoSynth();\n *\n * function mousePressed() {\n * monoSynth.triggerAttack(\"E3\");\n * }\n *\n * function mouseReleased() {\n * monoSynth.triggerRelease();\n * }\n *
\n */\n p5.MonoSynth.prototype.triggerAttack = function (note, velocity, secondsFromNow) {\n var secondsFromNow = ~~secondsFromNow;\n var freq = noteToFreq(note);\n var vel = velocity || 0.1;\n this.oscillator.freq(freq, 0, secondsFromNow);\n this.env.ramp(this.output.gain, secondsFromNow, vel);\n };\n\n /**\n * Trigger the release of the Envelope. This is similar to releasing\n * the key on a piano and letting the sound fade according to the\n * release level and release time.\n *\n * @param {Number} secondsFromNow time to trigger the release\n * @method triggerRelease\n * @for p5.MonoSynth\n * @example\n *
\n * var monoSynth = new p5.MonoSynth();\n *\n * function mousePressed() {\n * monoSynth.triggerAttack(\"E3\");\n * }\n *\n * function mouseReleased() {\n * monoSynth.triggerRelease();\n * }\n *
\n */\n p5.MonoSynth.prototype.triggerRelease = function (secondsFromNow) {\n var secondsFromNow = secondsFromNow || 0;\n this.env.ramp(this.output.gain, secondsFromNow, 0);\n };\n\n /**\n * Set values like a traditional\n * \n * ADSR envelope\n * .\n *\n * @method setADSR\n * @for p5.MonoSynth\n * @param {Number} attackTime Time (in seconds before envelope\n * reaches Attack Level\n * @param {Number} [decayTime] Time (in seconds) before envelope\n * reaches Decay/Sustain Level\n * @param {Number} [susRatio] Ratio between attackLevel and releaseLevel, on a scale from 0 to 1,\n * where 1.0 = attackLevel, 0.0 = releaseLevel.\n * The susRatio determines the decayLevel and the level at which the\n * sustain portion of the envelope will sustain.\n * For example, if attackLevel is 0.4, releaseLevel is 0,\n * and susAmt is 0.5, the decayLevel would be 0.2. If attackLevel is\n * increased to 1.0 (using setRange),\n * then decayLevel would increase proportionally, to become 0.5.\n * @param {Number} [releaseTime] Time in seconds from now (defaults to 0)\n */\n p5.MonoSynth.prototype.setADSR = function (attack,decay,sustain,release) {\n this.env.setADSR(attack, decay, sustain, release);\n };\n\n\n /**\n * Getters and Setters\n * @property {Number} attack\n * @for p5.MonoSynth\n */\n /**\n * @property {Number} decay\n * @for p5.MonoSynth\n */\n /**\n * @property {Number} sustain\n * @for p5.MonoSynth\n */\n /**\n * @property {Number} release\n * @for p5.MonoSynth\n */\n Object.defineProperties(p5.MonoSynth.prototype, {\n 'attack': {\n get : function() {\n return this.env.aTime;\n },\n set : function(attack) {\n this.env.setADSR(attack, this.env.dTime,\n this.env.sPercent, this.env.rTime);\n }\n },\n 'decay': {\n get : function() {\n return this.env.dTime;\n },\n set : function(decay) {\n this.env.setADSR(this.env.aTime, decay,\n this.env.sPercent, this.env.rTime);\n }\n },\n 'sustain': {\n get : function() {\n return this.env.sPercent;\n },\n set : function(sustain) {\n this.env.setADSR(this.env.aTime, this.env.dTime,\n sustain, this.env.rTime);\n }\n },\n 'release': {\n get : function() {\n return this.env.rTime;\n },\n set : function(release) {\n this.env.setADSR(this.env.aTime, this.env.dTime,\n this.env.sPercent, release);\n }\n },\n });\n\n\n /**\n * MonoSynth amp\n * @method amp\n * @for p5.MonoSynth\n * @param {Number} vol desired volume\n * @param {Number} [rampTime] Time to reach new volume\n * @return {Number} new volume value\n */\n p5.MonoSynth.prototype.amp = function(vol, rampTime) {\n var t = rampTime || 0;\n if (typeof vol !== 'undefined') {\n this.oscillator.amp(vol, t);\n }\n return this.oscillator.amp().value;\n };\n\n /**\n * Connect to a p5.sound / Web Audio object.\n *\n * @method connect\n * @for p5.MonoSynth\n * @param {Object} unit A p5.sound or Web Audio object\n */\n\n p5.MonoSynth.prototype.connect = function(unit) {\n var u = unit || p5sound.input;\n this.output.connect(u.input ? u.input : u);\n };\n\n /**\n * Disconnect all outputs\n *\n * @method disconnect\n * @for p5.MonoSynth\n */\n p5.MonoSynth.prototype.disconnect = function() {\n if (this.output) {\n this.output.disconnect();\n }\n };\n\n\n /**\n * Get rid of the MonoSynth and free up its resources / memory.\n *\n * @method dispose\n * @for p5.MonoSynth\n */\n p5.MonoSynth.prototype.dispose = function() {\n AudioVoice.prototype.dispose.apply(this);\n\n if (this.env) {\n this.env.dispose();\n }\n if (this.oscillator) {\n this.oscillator.dispose();\n }\n };\n\n});\n","'use strict';\ndefine(function() {\n var p5sound = require('master');\n\n /**\n * Base class for monophonic synthesizers. Any extensions of this class\n * should follow the API and implement the methods below in order to\n * remain compatible with p5.PolySynth();\n *\n * @class p5.AudioVoice\n * @constructor\n */\n p5.AudioVoice = function () {\n\t this.ac = p5sound.audiocontext;\n\t this.output = this.ac.createGain();\n\t this.connect();\n\t p5sound.soundArray.push(this);\n };\n\n p5.AudioVoice.prototype.play = function (note, velocity, secondsFromNow, sustime) {\n };\n\n p5.AudioVoice.prototype.triggerAttack = function (note, velocity, secondsFromNow) {\n };\n\n p5.AudioVoice.prototype.triggerRelease = function (secondsFromNow) {\n };\n\n p5.AudioVoice.prototype.amp = function(vol, rampTime) {\n };\n\n /**\n * Connect to p5 objects or Web Audio Nodes\n * @method connect\n * @for p5.AudioVoice\n * @param {Object} unit\n */\n p5.AudioVoice.prototype.connect = function(unit) {\n var u = unit || p5sound.input;\n this.output.connect(u.input ? u.input : u);\n };\n\n /**\n * Disconnect from soundOut\n * @method disconnect\n * @for p5.AudioVoice\n */\n p5.AudioVoice.prototype.disconnect = function() {\n this.output.disconnect();\n };\n\n p5.AudioVoice.prototype.dispose = function() {\n if (this.output) {\n this.output.disconnect();\n delete this.output;\n }\n };\n\n return p5.AudioVoice;\n});\n","'use strict';\ndefine(function (require) {\n\n var p5sound = require('master');\n var TimelineSignal = require('Tone/signal/TimelineSignal');\n var noteToFreq = require('helpers').noteToFreq;\n\n /**\n * An AudioVoice is used as a single voice for sound synthesis.\n * The PolySynth class holds an array of AudioVoice, and deals\n * with voices allocations, with setting notes to be played, and\n * parameters to be set.\n *\n * @class p5.PolySynth\n * @constructor\n *\n * @param {Number} [synthVoice] A monophonic synth voice inheriting\n * the AudioVoice class. Defaults to p5.MonoSynth\n * @param {Number} [maxVoices] Number of voices, defaults to 8;\n * @example\n *
\n * var polySynth;\n *\n * function setup() {\n * var cnv = createCanvas(100, 100);\n * cnv.mousePressed(playSynth);\n *\n * polySynth = new p5.PolySynth();\n *\n * textAlign(CENTER);\n * text('click to play', width/2, height/2);\n * }\n *\n * function playSynth() {\n * // note duration (in seconds)\n * var dur = 1.5;\n *\n * // time from now (in seconds)\n * var time = 0;\n *\n * // velocity (volume, from 0 to 1)\n * var vel = 0.1;\n *\n * // notes can overlap with each other\n * polySynth.play(\"G2\", vel, 0, dur);\n * polySynth.play(\"C3\", vel, time += 1/3, dur);\n * polySynth.play(\"G3\", vel, time += 1/3, dur);\n *\n * background(random(255), random(255), 255);\n * text('click to play', width/2, height/2);\n * }\n *
\n **/\n p5.PolySynth = function(audioVoice, maxVoices) {\n //audiovoices will contain maxVoices many monophonic synths\n this.audiovoices = [];\n\n /**\n * An object that holds information about which notes have been played and\n * which notes are currently being played. New notes are added as keys\n * on the fly. While a note has been attacked, but not released, the value of the\n * key is the audiovoice which is generating that note. When notes are released,\n * the value of the key becomes undefined.\n * @property notes\n */\n this.notes = {};\n\n //indices of the most recently used, and least recently used audiovoice\n this._newest = 0;\n this._oldest = 0;\n\n /**\n * A PolySynth must have at least 1 voice, defaults to 8\n * @property polyvalue\n */\n this.maxVoices = maxVoices || 8;\n\n /**\n * Monosynth that generates the sound for each note that is triggered. The\n * p5.PolySynth defaults to using the p5.MonoSynth as its voice.\n * @property AudioVoice\n */\n this.AudioVoice = audioVoice === undefined ? p5.MonoSynth : audioVoice;\n\n /**\n * This value must only change as a note is attacked or released. Due to delay\n * and sustain times, Tone.TimelineSignal is required to schedule the change in value.\n\t * @private\n * @property {Tone.TimelineSignal} _voicesInUse\n */\n this._voicesInUse = new TimelineSignal(0);\n\n this.output = p5sound.audiocontext.createGain();\n this.connect();\n\n //Construct the appropriate number of audiovoices\n this._allocateVoices();\n p5sound.soundArray.push(this);\n };\n\n /**\n * Construct the appropriate number of audiovoices\n * @private\n * @for p5.PolySynth\n * @method _allocateVoices\n */\n p5.PolySynth.prototype._allocateVoices = function() {\n for(var i = 0; i< this.maxVoices; i++) {\n this.audiovoices.push(new this.AudioVoice());\n this.audiovoices[i].disconnect();\n this.audiovoices[i].connect(this.output);\n }\n };\n\n /**\n * Play a note by triggering noteAttack and noteRelease with sustain time\n *\n * @method play\n * @for p5.PolySynth\n * @param {Number} [note] midi note to play (ranging from 0 to 127 - 60 being a middle C)\n * @param {Number} [velocity] velocity of the note to play (ranging from 0 to 1)\n * @param {Number} [secondsFromNow] time from now (in seconds) at which to play\n * @param {Number} [sustainTime] time to sustain before releasing the envelope\n * @example\n *
\n * var polySynth;\n *\n * function setup() {\n * var cnv = createCanvas(100, 100);\n * cnv.mousePressed(playSynth);\n *\n * polySynth = new p5.PolySynth();\n *\n * textAlign(CENTER);\n * text('click to play', width/2, height/2);\n * }\n *\n * function playSynth() {\n * // note duration (in seconds)\n * var dur = 0.1;\n *\n * // time from now (in seconds)\n * var time = 0;\n *\n * // velocity (volume, from 0 to 1)\n * var vel = 0.1;\n *\n * polySynth.play(\"G2\", vel, 0, dur);\n * polySynth.play(\"C3\", vel, 0, dur);\n * polySynth.play(\"G3\", vel, 0, dur);\n *\n * background(random(255), random(255), 255);\n * text('click to play', width/2, height/2);\n * }\n *
\n */\n p5.PolySynth.prototype.play = function (note,velocity, secondsFromNow, susTime) {\n var susTime = susTime || 1;\n this.noteAttack(note, velocity, secondsFromNow);\n this.noteRelease(note, secondsFromNow + susTime);\n };\n\n\n /**\n * noteADSR sets the envelope for a specific note that has just been triggered.\n * Using this method modifies the envelope of whichever audiovoice is being used\n * to play the desired note. The envelope should be reset before noteRelease is called\n * in order to prevent the modified envelope from being used on other notes.\n *\n * @method noteADSR\n * @for p5.PolySynth\n * @param {Number} [note] Midi note on which ADSR should be set.\n * @param {Number} [attackTime] Time (in seconds before envelope\n * reaches Attack Level\n * @param {Number} [decayTime] Time (in seconds) before envelope\n * reaches Decay/Sustain Level\n * @param {Number} [susRatio] Ratio between attackLevel and releaseLevel, on a scale from 0 to 1,\n * where 1.0 = attackLevel, 0.0 = releaseLevel.\n * The susRatio determines the decayLevel and the level at which the\n * sustain portion of the envelope will sustain.\n * For example, if attackLevel is 0.4, releaseLevel is 0,\n * and susAmt is 0.5, the decayLevel would be 0.2. If attackLevel is\n * increased to 1.0 (using setRange),\n * then decayLevel would increase proportionally, to become 0.5.\n * @param {Number} [releaseTime] Time in seconds from now (defaults to 0)\n **/\n\n p5.PolySynth.prototype.noteADSR = function (note,a,d,s,r,timeFromNow) {\n var now = p5sound.audiocontext.currentTime;\n var timeFromNow = timeFromNow || 0;\n var t = now + timeFromNow\n this.audiovoices[ this.notes[note].getValueAtTime(t) ].setADSR(a,d,s,r);\n };\n\n\n /**\n * Set the PolySynths global envelope. This method modifies the envelopes of each\n * monosynth so that all notes are played with this envelope.\n *\n * @method setADSR\n * @for p5.PolySynth\n * @param {Number} [attackTime] Time (in seconds before envelope\n * reaches Attack Level\n * @param {Number} [decayTime] Time (in seconds) before envelope\n * reaches Decay/Sustain Level\n * @param {Number} [susRatio] Ratio between attackLevel and releaseLevel, on a scale from 0 to 1,\n * where 1.0 = attackLevel, 0.0 = releaseLevel.\n * The susRatio determines the decayLevel and the level at which the\n * sustain portion of the envelope will sustain.\n * For example, if attackLevel is 0.4, releaseLevel is 0,\n * and susAmt is 0.5, the decayLevel would be 0.2. If attackLevel is\n * increased to 1.0 (using setRange),\n * then decayLevel would increase proportionally, to become 0.5.\n * @param {Number} [releaseTime] Time in seconds from now (defaults to 0)\n **/\n p5.PolySynth.prototype.setADSR = function(a,d,s,r) {\n this.audiovoices.forEach(function(voice) {\n voice.setADSR(a,d,s,r);\n });\n };\n\n /**\n * Trigger the Attack, and Decay portion of a MonoSynth.\n * Similar to holding down a key on a piano, but it will\n * hold the sustain level until you let go.\n *\n * @method noteAttack\n * @for p5.PolySynth\n * @param {Number} [note] midi note on which attack should be triggered.\n * @param {Number} [velocity] velocity of the note to play (ranging from 0 to 1)/\n * @param {Number} [secondsFromNow] time from now (in seconds)\n * @example\n *
\n * var polySynth = new p5.PolySynth();\n * var pitches = [\"G\", \"D\", \"G\", \"C\"];\n * var octaves = [2, 3, 4];\n *\n * function mousePressed() {\n * // play a chord: multiple notes at the same time\n * for (var i = 0; i < 4; i++) {\n * var note = random(pitches) + random(octaves);\n * polySynth.noteAttack(note, 0.1);\n * }\n * }\n *\n * function mouseReleased() {\n * // release all voices\n * polySynth.noteRelease();\n * }\n *
\n */\n p5.PolySynth.prototype.noteAttack = function (_note, _velocity, secondsFromNow) {\n //this value goes to the audiovoices which handle their own scheduling\n var secondsFromNow = ~~secondsFromNow;\n\n //this value is used by this._voicesInUse\n var acTime = p5sound.audiocontext.currentTime + secondsFromNow;\n\n //Convert note to frequency if necessary. This is because entries into this.notes\n //should be based on frequency for the sake of consistency.\n var note = noteToFreq(_note);\n var velocity = _velocity || 0.1;\n\n var currentVoice;\n\n //Release the note if it is already playing\n if (this.notes[note] && this.notes[note].getValueAtTime(acTime) !== null) {\n this.noteRelease(note, 0);\n }\n\n //Check to see how many voices are in use at the time the note will start\n if (this._voicesInUse.getValueAtTime(acTime) < this.maxVoices) {\n currentVoice = Math.max(~~this._voicesInUse.getValueAtTime(acTime), 0);\n }\n //If we are exceeding the polyvalue, bump off the oldest notes and replace\n //with a new note\n else {\n currentVoice = this._oldest;\n\n var oldestNote = p5.prototype.freqToMidi(this.audiovoices[this._oldest].oscillator.freq().value);\n this.noteRelease(oldestNote);\n this._oldest = ( this._oldest + 1 ) % (this.maxVoices - 1);\n }\n\n //Overrite the entry in the notes object. A note (frequency value)\n //corresponds to the index of the audiovoice that is playing it\n this.notes[note] = new TimelineSignal();\n this.notes[note].setValueAtTime(currentVoice, acTime);\n\n //Find the scheduled change in this._voicesInUse that will be previous to this new note\n //Add 1 and schedule this value at time 't', when this note will start playing\n var previousVal = this._voicesInUse._searchBefore(acTime) === null ? 0 : this._voicesInUse._searchBefore(acTime).value;\n this._voicesInUse.setValueAtTime(previousVal + 1, acTime);\n\n //Then update all scheduled values that follow to increase by 1\n this._updateAfter(acTime, 1);\n\n this._newest = currentVoice;\n //The audiovoice handles the actual scheduling of the note\n if (typeof velocity === 'number') {\n var maxRange = 1 / this._voicesInUse.getValueAtTime(acTime) * 2;\n velocity = velocity > maxRange ? maxRange : velocity;\n }\n this.audiovoices[currentVoice].triggerAttack(note, velocity, secondsFromNow);\n };\n\n /**\n * Private method to ensure accurate values of this._voicesInUse\n * Any time a new value is scheduled, it is necessary to increment all subsequent\n * scheduledValues after attack, and decrement all subsequent\n * scheduledValues after release\n *\n * @private\n * @for p5.PolySynth\n * @param {[type]} time [description]\n * @param {[type]} value [description]\n * @return {[type]} [description]\n */\n p5.PolySynth.prototype._updateAfter = function(time, value) {\n if(this._voicesInUse._searchAfter(time) === null) {\n return;\n } else{\n this._voicesInUse._searchAfter(time).value += value;\n var nextTime = this._voicesInUse._searchAfter(time).time;\n this._updateAfter(nextTime, value);\n }\n };\n\n\n /**\n * Trigger the Release of an AudioVoice note. This is similar to releasing\n * the key on a piano and letting the sound fade according to the\n * release level and release time.\n *\n * @method noteRelease\n * @for p5.PolySynth\n * @param {Number} [note] midi note on which attack should be triggered.\n * If no value is provided, all notes will be released.\n * @param {Number} [secondsFromNow] time to trigger the release\n * @example\n *
\n * var pitches = [\"G\", \"D\", \"G\", \"C\"];\n * var octaves = [2, 3, 4];\n * var polySynth = new p5.PolySynth();\n *\n * function mousePressed() {\n * // play a chord: multiple notes at the same time\n * for (var i = 0; i < 4; i++) {\n * var note = random(pitches) + random(octaves);\n * polySynth.noteAttack(note, 0.1);\n * }\n * }\n *\n * function mouseReleased() {\n * // release all voices\n * polySynth.noteRelease();\n * }\n *
\n *\n */\n p5.PolySynth.prototype.noteRelease = function (_note,secondsFromNow) {\n var now = p5sound.audiocontext.currentTime;\n var tFromNow = secondsFromNow || 0;\n var t = now + tFromNow;\n\n // if a note value is not provided, release all voices\n if (!_note) {\n this.audiovoices.forEach(function(voice) {\n voice.triggerRelease(tFromNow)\n });\n this._voicesInUse.setValueAtTime(0, t);\n for (var n in this.notes) {\n this.notes[n].dispose();\n delete this.notes[n];\n }\n return;\n }\n\n //Make sure note is in frequency inorder to query the this.notes object\n var note = noteToFreq(_note);\n\n if (!this.notes[note] || this.notes[note].getValueAtTime(t) === null) {\n console.warn('Cannot release a note that is not already playing');\n } else {\n //Find the scheduled change in this._voicesInUse that will be previous to this new note\n //subtract 1 and schedule this value at time 't', when this note will stop playing\n var previousVal = Math.max(~~this._voicesInUse.getValueAtTime(t).value, 1);\n this._voicesInUse.setValueAtTime(previousVal - 1, t);\n //Then update all scheduled values that follow to decrease by 1 but never go below 0\n if (previousVal > 0) {\n this._updateAfter(t, -1);\n }\n\n this.audiovoices[ this.notes[note].getValueAtTime(t) ].triggerRelease(tFromNow);\n this.notes[note].dispose();\n delete this.notes[note];\n\n this._newest = this._newest === 0 ? 0 : (this._newest - 1) % (this.maxVoices - 1);\n }\n\n };\n\n /**\n * Connect to a p5.sound / Web Audio object.\n *\n * @method connect\n * @for p5.PolySynth\n * @param {Object} unit A p5.sound or Web Audio object\n */\n p5.PolySynth.prototype.connect = function (unit) {\n var u = unit || p5sound.input;\n this.output.connect(u.input ? u.input : u);\n };\n\n /**\n * Disconnect all outputs\n *\n * @method disconnect\n * @for p5.PolySynth\n */\n p5.PolySynth.prototype.disconnect = function() {\n if (this.output) {\n this.output.disconnect();\n }\n };\n\n /**\n * Get rid of the MonoSynth and free up its resources / memory.\n *\n * @method dispose\n * @for p5.PolySynth\n */\n p5.PolySynth.prototype.dispose = function() {\n this.audiovoices.forEach(function(voice) {\n voice.dispose();\n });\n\n if (this.output) {\n this.output.disconnect();\n delete this.output;\n }\n };\n\n});\n","'use strict';\n\ndefine(function (require) {\n\n require('audioworklet-polyfill');\n require('shims');\n require('audiocontext');\n var p5SOUND = require('master');\n require('helpers');\n require('errorHandler');\n require('audioWorklet');\n require('panner');\n require('soundfile');\n require('amplitude');\n require('fft');\n require('signal');\n require('oscillator');\n require('envelope');\n require('pulse');\n require('noise');\n require('audioin');\n require('filter');\n require('eq');\n require('panner3d');\n require('listener3d');\n require('delay');\n require('reverb');\n require('metro');\n require('looper');\n require('soundLoop');\n require('compressor');\n require('soundRecorder');\n require('peakDetect');\n require('gain');\n require('monosynth');\n require('polysynth');\n require('distortion');\n require('audioVoice');\n require('monosynth');\n require('polysynth');\n\n return p5SOUND;\n\n});\n","!function(){var e,t=[];function r(e){var r=this,n={},i=-1;this.parameters.forEach(function(e,o){var s=t[++i]||(t[i]=new Float32Array(r.bufferSize));s.fill(e.value),n[o]=s}),this.processor.realm.exec(\"self.sampleRate=sampleRate=\"+this.context.sampleRate+\";self.currentTime=currentTime=\"+this.context.currentTime);var s=o(e.inputBuffer),a=o(e.outputBuffer);this.instance.process([s],[a],n)}function o(e){for(var t=[],r=0;r= this.sampleLimit) {\\n this.stop();\\n return true;\\n }\\n\\n var input = inputs[0];\\n var output = outputs[0];\\n\\n for (var channel = 0; channel < output.length; ++channel) {\\n var inputChannel = input[channel];\\n\\n if (channel === 0) {\\n this.leftBuffers.push(inputChannel);\\n\\n if (this.numInputChannels === 1) {\\n this.rightBuffers.push(inputChannel);\\n }\\n } else if (channel === 1 && this.numInputChannels > 1) {\\n this.rightBuffers.push(inputChannel);\\n }\\n }\\n\\n this.recordedSamples += output[0].length;\\n return true;\\n }\\n }, {\\n key: \\\"record\\\",\\n value: function record(duration) {\\n if (duration) {\\n this.sampleLimit = Math.round(duration * sampleRate);\\n }\\n\\n this.recording = true;\\n }\\n }, {\\n key: \\\"stop\\\",\\n value: function stop() {\\n this.recording = false;\\n var buffers = this.getBuffers();\\n var leftBuffer = buffers[0].buffer;\\n var rightBuffer = buffers[1].buffer;\\n this.port.postMessage({\\n name: 'buffers',\\n leftBuffer: leftBuffer,\\n rightBuffer: rightBuffer\\n }, [leftBuffer, rightBuffer]);\\n this.clear();\\n }\\n }, {\\n key: \\\"getBuffers\\\",\\n value: function getBuffers() {\\n var buffers = [];\\n buffers.push(this.mergeBuffers(this.leftBuffers));\\n buffers.push(this.mergeBuffers(this.rightBuffers));\\n return buffers;\\n }\\n }, {\\n key: \\\"mergeBuffers\\\",\\n value: function mergeBuffers(channelBuffer) {\\n var result = new Float32Array(this.recordedSamples);\\n var offset = 0;\\n var lng = channelBuffer.length;\\n\\n for (var i = 0; i < lng; i++) {\\n var buffer = channelBuffer[i];\\n result.set(buffer, offset);\\n offset += buffer.length;\\n }\\n\\n return result;\\n }\\n }, {\\n key: \\\"clear\\\",\\n value: function clear() {\\n this.leftBuffers = [];\\n this.rightBuffers = [];\\n this.recordedSamples = 0;\\n this.sampleLimit = null;\\n }\\n }]);\\n\\n return RecorderProcessor;\\n}(_wrapNativeSuper(AudioWorkletProcessor));\\n\\nregisterProcessor(processorNames.recorderProcessor, RecorderProcessor);\"","export default \"function _typeof(obj) { if (typeof Symbol === \\\"function\\\" && typeof Symbol.iterator === \\\"symbol\\\") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === \\\"function\\\" && obj.constructor === Symbol && obj !== Symbol.prototype ? \\\"symbol\\\" : typeof obj; }; } return _typeof(obj); }\\n\\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\\\"Cannot call a class as a function\\\"); } }\\n\\nfunction _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if (\\\"value\\\" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }\\n\\nfunction _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }\\n\\nfunction _possibleConstructorReturn(self, call) { if (call && (_typeof(call) === \\\"object\\\" || typeof call === \\\"function\\\")) { return call; } return _assertThisInitialized(self); }\\n\\nfunction _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError(\\\"this hasn't been initialised - super() hasn't been called\\\"); } return self; }\\n\\nfunction _inherits(subClass, superClass) { if (typeof superClass !== \\\"function\\\" && superClass !== null) { throw new TypeError(\\\"Super expression must either be null or a function\\\"); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, writable: true, configurable: true } }); if (superClass) _setPrototypeOf(subClass, superClass); }\\n\\nfunction _wrapNativeSuper(Class) { var _cache = typeof Map === \\\"function\\\" ? new Map() : undefined; _wrapNativeSuper = function _wrapNativeSuper(Class) { if (Class === null || !_isNativeFunction(Class)) return Class; if (typeof Class !== \\\"function\\\") { throw new TypeError(\\\"Super expression must either be null or a function\\\"); } if (typeof _cache !== \\\"undefined\\\") { if (_cache.has(Class)) return _cache.get(Class); _cache.set(Class, Wrapper); } function Wrapper() { return _construct(Class, arguments, _getPrototypeOf(this).constructor); } Wrapper.prototype = Object.create(Class.prototype, { constructor: { value: Wrapper, enumerable: false, writable: true, configurable: true } }); return _setPrototypeOf(Wrapper, Class); }; return _wrapNativeSuper(Class); }\\n\\nfunction isNativeReflectConstruct() { if (typeof Reflect === \\\"undefined\\\" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === \\\"function\\\") return true; try { Date.prototype.toString.call(Reflect.construct(Date, [], function () {})); return true; } catch (e) { return false; } }\\n\\nfunction _construct(Parent, args, Class) { if (isNativeReflectConstruct()) { _construct = Reflect.construct; } else { _construct = function _construct(Parent, args, Class) { var a = [null]; a.push.apply(a, args); var Constructor = Function.bind.apply(Parent, a); var instance = new Constructor(); if (Class) _setPrototypeOf(instance, Class.prototype); return instance; }; } return _construct.apply(null, arguments); }\\n\\nfunction _isNativeFunction(fn) { return Function.toString.call(fn).indexOf(\\\"[native code]\\\") !== -1; }\\n\\nfunction _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); }\\n\\nfunction _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); }; return _getPrototypeOf(o); }\\n\\n// import processor name via preval.require so that it's available as a value at compile time\\nvar processorNames = {\\n \\\"recorderProcessor\\\": \\\"recorder-processor\\\",\\n \\\"soundFileProcessor\\\": \\\"sound-file-processor\\\",\\n \\\"amplitudeProcessor\\\": \\\"amplitude-processor\\\"\\n};\\n\\nvar SoundFileProcessor =\\n/*#__PURE__*/\\nfunction (_AudioWorkletProcesso) {\\n _inherits(SoundFileProcessor, _AudioWorkletProcesso);\\n\\n function SoundFileProcessor() {\\n var _this;\\n\\n _classCallCheck(this, SoundFileProcessor);\\n\\n _this = _possibleConstructorReturn(this, _getPrototypeOf(SoundFileProcessor).call(this));\\n _this.paused = false;\\n\\n _this.port.onmessage = function (event) {\\n var data = event.data;\\n\\n if (data.name === 'play') {\\n _this.paused = false;\\n } else if (data.name === 'pause') {\\n _this.paused = true;\\n }\\n };\\n\\n return _this;\\n }\\n\\n _createClass(SoundFileProcessor, [{\\n key: \\\"process\\\",\\n value: function process(inputs) {\\n var input = inputs[0];\\n var inputChannel = input[0];\\n var position = inputChannel[inputChannel.length - 1];\\n\\n if (!this.paused) {\\n this.port.postMessage({\\n name: 'position',\\n position: position\\n });\\n }\\n\\n return true;\\n }\\n }]);\\n\\n return SoundFileProcessor;\\n}(_wrapNativeSuper(AudioWorkletProcessor));\\n\\nregisterProcessor(processorNames.soundFileProcessor, SoundFileProcessor);\"","export default \"function _typeof(obj) { if (typeof Symbol === \\\"function\\\" && typeof Symbol.iterator === \\\"symbol\\\") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === \\\"function\\\" && obj.constructor === Symbol && obj !== Symbol.prototype ? \\\"symbol\\\" : typeof obj; }; } return _typeof(obj); }\\n\\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\\\"Cannot call a class as a function\\\"); } }\\n\\nfunction _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if (\\\"value\\\" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }\\n\\nfunction _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }\\n\\nfunction _possibleConstructorReturn(self, call) { if (call && (_typeof(call) === \\\"object\\\" || typeof call === \\\"function\\\")) { return call; } return _assertThisInitialized(self); }\\n\\nfunction _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError(\\\"this hasn't been initialised - super() hasn't been called\\\"); } return self; }\\n\\nfunction _inherits(subClass, superClass) { if (typeof superClass !== \\\"function\\\" && superClass !== null) { throw new TypeError(\\\"Super expression must either be null or a function\\\"); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, writable: true, configurable: true } }); if (superClass) _setPrototypeOf(subClass, superClass); }\\n\\nfunction _wrapNativeSuper(Class) { var _cache = typeof Map === \\\"function\\\" ? new Map() : undefined; _wrapNativeSuper = function _wrapNativeSuper(Class) { if (Class === null || !_isNativeFunction(Class)) return Class; if (typeof Class !== \\\"function\\\") { throw new TypeError(\\\"Super expression must either be null or a function\\\"); } if (typeof _cache !== \\\"undefined\\\") { if (_cache.has(Class)) return _cache.get(Class); _cache.set(Class, Wrapper); } function Wrapper() { return _construct(Class, arguments, _getPrototypeOf(this).constructor); } Wrapper.prototype = Object.create(Class.prototype, { constructor: { value: Wrapper, enumerable: false, writable: true, configurable: true } }); return _setPrototypeOf(Wrapper, Class); }; return _wrapNativeSuper(Class); }\\n\\nfunction isNativeReflectConstruct() { if (typeof Reflect === \\\"undefined\\\" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === \\\"function\\\") return true; try { Date.prototype.toString.call(Reflect.construct(Date, [], function () {})); return true; } catch (e) { return false; } }\\n\\nfunction _construct(Parent, args, Class) { if (isNativeReflectConstruct()) { _construct = Reflect.construct; } else { _construct = function _construct(Parent, args, Class) { var a = [null]; a.push.apply(a, args); var Constructor = Function.bind.apply(Parent, a); var instance = new Constructor(); if (Class) _setPrototypeOf(instance, Class.prototype); return instance; }; } return _construct.apply(null, arguments); }\\n\\nfunction _isNativeFunction(fn) { return Function.toString.call(fn).indexOf(\\\"[native code]\\\") !== -1; }\\n\\nfunction _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); }\\n\\nfunction _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); }; return _getPrototypeOf(o); }\\n\\n// import processor name via preval.require so that it's available as a value at compile time\\nvar processorNames = {\\n \\\"recorderProcessor\\\": \\\"recorder-processor\\\",\\n \\\"soundFileProcessor\\\": \\\"sound-file-processor\\\",\\n \\\"amplitudeProcessor\\\": \\\"amplitude-processor\\\"\\n};\\n\\nvar AmplitudeProcessor =\\n/*#__PURE__*/\\nfunction (_AudioWorkletProcesso) {\\n _inherits(AmplitudeProcessor, _AudioWorkletProcesso);\\n\\n function AmplitudeProcessor(options) {\\n var _this;\\n\\n _classCallCheck(this, AmplitudeProcessor);\\n\\n _this = _possibleConstructorReturn(this, _getPrototypeOf(AmplitudeProcessor).call(this));\\n var processorOptions = options.processorOptions || {};\\n _this.smoothing = processorOptions.smoothing || 0;\\n _this.normalize = processorOptions.normalize || false;\\n _this.stereoVol = [0, 0];\\n _this.stereoVolNorm = [0, 0];\\n _this.volMax = 0.001;\\n\\n _this.port.onmessage = function (event) {\\n var data = event.data;\\n\\n if (data.name === 'toggleNormalize') {\\n _this.normalize = data.normalize;\\n } else if (data.name === 'smoothing') {\\n _this.smoothing = Math.max(0, Math.min(1, data.smoothing));\\n }\\n };\\n\\n return _this;\\n } // TO DO make this stereo / dependent on # of audio channels\\n\\n\\n _createClass(AmplitudeProcessor, [{\\n key: \\\"process\\\",\\n value: function process(inputs, outputs) {\\n var input = inputs[0];\\n var output = outputs[0];\\n var smoothing = this.smoothing;\\n\\n for (var channel = 0; channel < input.length; ++channel) {\\n var inputBuffer = input[channel];\\n var bufLength = inputBuffer.length;\\n var sum = 0;\\n\\n for (var i = 0; i < bufLength; i++) {\\n var x = inputBuffer[i];\\n\\n if (this.normalize) {\\n sum += Math.max(Math.min(x / this.volMax, 1), -1) * Math.max(Math.min(x / this.volMax, 1), -1);\\n } else {\\n sum += x * x;\\n }\\n } // ... then take the square root of the sum.\\n\\n\\n var rms = Math.sqrt(sum / bufLength);\\n this.stereoVol[channel] = Math.max(rms, this.stereoVol[channel] * smoothing);\\n this.volMax = Math.max(this.stereoVol[channel], this.volMax);\\n } // calculate stero normalized volume and add volume from all channels together\\n\\n\\n var volSum = 0;\\n\\n for (var index = 0; index < this.stereoVol.length; index++) {\\n this.stereoVolNorm[index] = Math.max(Math.min(this.stereoVol[index] / this.volMax, 1), 0);\\n volSum += this.stereoVol[index];\\n } // volume is average of channels\\n\\n\\n var volume = volSum / this.stereoVol.length; // normalized value\\n\\n var volNorm = Math.max(Math.min(volume / this.volMax, 1), 0);\\n this.port.postMessage({\\n name: 'amplitude',\\n volume: volume,\\n volNorm: volNorm,\\n stereoVol: this.stereoVol,\\n stereoVolNorm: this.stereoVolNorm\\n }); // pass input through to output\\n\\n for (var _channel = 0; _channel < output.length; ++_channel) {\\n output[_channel].set(input[_channel]);\\n }\\n\\n return true;\\n }\\n }]);\\n\\n return AmplitudeProcessor;\\n}(_wrapNativeSuper(AudioWorkletProcessor));\\n\\nregisterProcessor(processorNames.amplitudeProcessor, AmplitudeProcessor);\"","'use strict';\n\ndefine(function (require) {\n\n var p5sound = require('master');\n var ac = p5sound.audiocontext;\n\n // Stereo panner\n // if there is a stereo panner node use it\n if(typeof ac.createStereoPanner !== 'undefined') {\n p5.Panner = function (input, output) {\n this.stereoPanner = this.input = ac.createStereoPanner();\n input.connect(this.stereoPanner);\n this.stereoPanner.connect(output);\n };\n\n p5.Panner.prototype.pan = function(val, tFromNow) {\n var time = tFromNow || 0;\n var t = ac.currentTime + time;\n\n this.stereoPanner.pan.linearRampToValueAtTime(val, t);\n };\n\n //not implemented because stereopanner\n //node does not require this and will automatically\n //convert single channel or multichannel to stereo.\n //tested with single and stereo, not with (>2) multichannel\n p5.Panner.prototype.inputChannels = function() {};\n\n p5.Panner.prototype.connect = function(obj) {\n this.stereoPanner.connect(obj);\n };\n\n p5.Panner.prototype.disconnect = function() {\n if (this.stereoPanner) {\n this.stereoPanner.disconnect();\n }\n };\n\n } else {\n // if there is no createStereoPanner object\n // such as in safari 7.1.7 at the time of writing this\n // use this method to create the effect\n p5.Panner = function(input, output, numInputChannels) {\n this.input = ac.createGain();\n input.connect(this.input);\n\n this.left = ac.createGain();\n this.right = ac.createGain();\n this.left.channelInterpretation = 'discrete';\n this.right.channelInterpretation = 'discrete';\n\n // if input is stereo\n if (numInputChannels > 1) {\n this.splitter = ac.createChannelSplitter(2);\n this.input.connect(this.splitter);\n\n this.splitter.connect(this.left, 1);\n this.splitter.connect(this.right, 0);\n }\n else {\n this.input.connect(this.left);\n this.input.connect(this.right);\n }\n\n this.output = ac.createChannelMerger(2);\n this.left.connect(this.output, 0, 1);\n this.right.connect(this.output, 0, 0);\n this.output.connect(output);\n };\n\n // -1 is left, +1 is right\n p5.Panner.prototype.pan = function(val, tFromNow) {\n var time = tFromNow || 0;\n var t = ac.currentTime + time;\n var v = (val + 1) / 2;\n var rightVal = Math.cos(v*Math.PI/2);\n var leftVal = Math.sin(v * Math.PI/2);\n this.left.gain.linearRampToValueAtTime(leftVal, t);\n this.right.gain.linearRampToValueAtTime(rightVal, t);\n };\n\n p5.Panner.prototype.inputChannels = function(numChannels) {\n if (numChannels === 1) {\n this.input.disconnect();\n this.input.connect(this.left);\n this.input.connect(this.right);\n } else if (numChannels === 2) {\n if (typeof(this.splitter === 'undefined')) {\n this.splitter = ac.createChannelSplitter(2);\n }\n this.input.disconnect();\n this.input.connect(this.splitter);\n this.splitter.connect(this.left, 1);\n this.splitter.connect(this.right, 0);\n }\n };\n\n p5.Panner.prototype.connect = function(obj) {\n this.output.connect(obj);\n };\n\n p5.Panner.prototype.disconnect = function() {\n if (this.output) {\n this.output.disconnect();\n }\n };\n }\n});\n","'use strict';\n\ndefine(function (require) {\n\n var CustomError = require('errorHandler');\n var p5sound = require('master');\n var ac = p5sound.audiocontext;\n var midiToFreq = require('helpers').midiToFreq;\n var convertToWav = require('helpers').convertToWav;\n var processorNames = require('./audioWorklet/processorNames');\n\n /**\n *
SoundFile object with a path to a file.
\n *\n *
The p5.SoundFile may not be available immediately because\n * it loads the file information asynchronously.
\n *\n *
To do something with the sound as soon as it loads\n * pass the name of a function as the second parameter.
\n *\n *
Only one file path is required. However, audio file formats\n * (i.e. mp3, ogg, wav and m4a/aac) are not supported by all\n * web browsers. If you want to ensure compatability, instead of a single\n * file path, you may include an Array of filepaths, and the browser will\n * choose a format that works.
\n *\n * @class p5.SoundFile\n * @constructor\n * @param {String|Array} path path to a sound file (String). Optionally,\n * you may include multiple file formats in\n * an array. Alternately, accepts an object\n * from the HTML5 File API, or a p5.File.\n * @param {Function} [successCallback] Name of a function to call once file loads\n * @param {Function} [errorCallback] Name of a function to call if file fails to\n * load. This function will receive an error or\n * XMLHttpRequest object with information\n * about what went wrong.\n * @param {Function} [whileLoadingCallback] Name of a function to call while file\n * is loading. That function will\n * receive progress of the request to\n * load the sound file\n * (between 0 and 1) as its first\n * parameter. This progress\n * does not account for the additional\n * time needed to decode the audio data.\n *\n * @example\n *
\n */\n p5.SoundFile = function(paths, onload, onerror, whileLoading) {\n if (typeof paths !== 'undefined') {\n if (typeof paths === 'string' || typeof paths[0] === 'string') {\n var path = p5.prototype._checkFileFormats(paths);\n this.url = path;\n }\n else if(typeof paths === 'object') {\n if (!(window.File && window.FileReader && window.FileList && window.Blob)) {\n // The File API isn't supported in this browser\n throw 'Unable to load file because the File API is not supported';\n }\n }\n\n // if type is a p5.File...get the actual file\n if (paths.file) {\n paths = paths.file;\n }\n\n this.file = paths;\n }\n\n // private _onended callback, set by the method: onended(callback)\n this._onended = function() {};\n\n this._looping = false;\n this._playing = false;\n this._paused = false;\n this._pauseTime = 0;\n\n // cues for scheduling events with addCue() removeCue()\n this._cues = [];\n this._cueIDCounter = 0;\n\n // position of the most recently played sample\n this._lastPos = 0;\n this._counterNode = null;\n this._workletNode = null;\n\n // array of sources so that they can all be stopped!\n this.bufferSourceNodes = [];\n\n // current source\n this.bufferSourceNode = null;\n\n this.buffer = null;\n this.playbackRate = 1;\n\n this.input = p5sound.audiocontext.createGain();\n this.output = p5sound.audiocontext.createGain();\n\n this.reversed = false;\n\n // start and end of playback / loop\n this.startTime = 0;\n this.endTime = null;\n this.pauseTime = 0;\n\n // \"restart\" would stop playback before retriggering\n this.mode = 'sustain';\n\n // time that playback was started, in millis\n this.startMillis = null;\n\n // stereo panning\n this.panPosition = 0.0;\n this.panner = new p5.Panner(this.output, p5sound.input, 2);\n\n // it is possible to instantiate a soundfile with no path\n if (this.url || this.file) {\n this.load(onload, onerror);\n }\n\n // add this p5.SoundFile to the soundArray\n p5sound.soundArray.push(this);\n\n if (typeof whileLoading === 'function') {\n this._whileLoading = whileLoading;\n } else {\n this._whileLoading = function() {};\n }\n\n this._clearOnEnd = _clearOnEnd.bind(this);\n };\n\n // register preload handling of loadSound\n p5.prototype.registerPreloadMethod('loadSound', p5.prototype);\n\n /**\n * loadSound() returns a new p5.SoundFile from a specified\n * path. If called during preload(), the p5.SoundFile will be ready\n * to play in time for setup() and draw(). If called outside of\n * preload, the p5.SoundFile will not be ready immediately, so\n * loadSound accepts a callback as the second parameter. Using a\n * \n * local server is recommended when loading external files.\n *\n * @method loadSound\n * @for p5\n * @param {String|Array} path Path to the sound file, or an array with\n * paths to soundfiles in multiple formats\n * i.e. ['sound.ogg', 'sound.mp3'].\n * Alternately, accepts an object: either\n * from the HTML5 File API, or a p5.File.\n * @param {Function} [successCallback] Name of a function to call once file loads\n * @param {Function} [errorCallback] Name of a function to call if there is\n * an error loading the file.\n * @param {Function} [whileLoading] Name of a function to call while file is loading.\n * This function will receive the percentage loaded\n * so far, from 0.0 to 1.0.\n * @return {SoundFile} Returns a p5.SoundFile\n * @example\n *
\n */\n p5.prototype.loadSound = function(path, callback, onerror, whileLoading) {\n // if loading locally without a server\n if (window.location.origin.indexOf('file://') > -1 && window.cordova === 'undefined' ) {\n window.alert('This sketch may require a server to load external files. Please see http://bit.ly/1qcInwS');\n }\n\n var self = this;\n var s = new p5.SoundFile(path, function() {\n if(typeof callback === 'function') {\n callback.apply(self, arguments);\n }\n\n if (typeof self._decrementPreload === 'function') {\n self._decrementPreload();\n }\n }, onerror, whileLoading);\n\n return s;\n };\n\n /**\n * This is a helper function that the p5.SoundFile calls to load\n * itself. Accepts a callback (the name of another function)\n * as an optional parameter.\n *\n * @private\n * @for p5.SoundFile\n * @param {Function} [successCallback] Name of a function to call once file loads\n * @param {Function} [errorCallback] Name of a function to call if there is an error\n */\n p5.SoundFile.prototype.load = function(callback, errorCallback) {\n var self = this;\n var errorTrace = new Error().stack;\n\n if (this.url !== undefined && this.url !== '') {\n var request = new XMLHttpRequest();\n request.addEventListener('progress', function(evt) {\n self._updateProgress(evt);\n }, false);\n request.open('GET', this.url, true);\n request.responseType = 'arraybuffer';\n\n request.onload = function() {\n if (request.status === 200) {\n // on sucess loading file:\n if (!self.panner) return;\n ac.decodeAudioData(request.response,\n // success decoding buffer:\n function(buff) {\n if (!self.panner) return;\n self.buffer = buff;\n self.panner.inputChannels(buff.numberOfChannels);\n if (callback) {\n callback(self);\n }\n },\n // error decoding buffer. \"e\" is undefined in Chrome 11/22/2015\n function() {\n if (!self.panner) return;\n var err = new CustomError('decodeAudioData', errorTrace, self.url);\n var msg = 'AudioContext error at decodeAudioData for ' + self.url;\n if (errorCallback) {\n err.msg = msg;\n errorCallback(err);\n } else {\n console.error(msg +'\\n The error stack trace includes: \\n' + err.stack);\n }\n }\n );\n }\n // if request status != 200, it failed\n else {\n if (!self.panner) return;\n var err = new CustomError('loadSound', errorTrace, self.url);\n var msg = 'Unable to load ' + self.url + '. The request status was: ' +\n request.status + ' (' + request.statusText + ')';\n\n if (errorCallback) {\n err.message = msg;\n errorCallback(err);\n } else {\n console.error(msg +'\\n The error stack trace includes: \\n' + err.stack);\n }\n }\n };\n\n // if there is another error, aside from 404...\n request.onerror = function() {\n var err = new CustomError('loadSound', errorTrace, self.url);\n var msg = 'There was no response from the server at ' + self.url + '. Check the url and internet connectivity.';\n\n if (errorCallback) {\n err.message = msg;\n errorCallback(err);\n } else {\n console.error(msg +'\\n The error stack trace includes: \\n' + err.stack);\n }\n };\n\n request.send();\n }\n else if (this.file !== undefined) {\n var reader = new FileReader();\n reader.onload = function() {\n if (!self.panner) return;\n ac.decodeAudioData(reader.result, function(buff) {\n if (!self.panner) return;\n self.buffer = buff;\n self.panner.inputChannels(buff.numberOfChannels);\n if (callback) {\n callback(self);\n }\n });\n };\n reader.onerror = function(e) {\n if (!self.panner) return;\n if (onerror) {\n onerror(e);\n }\n };\n reader.readAsArrayBuffer(this.file);\n }\n };\n\n // TO DO: use this method to create a loading bar that shows progress during file upload/decode.\n p5.SoundFile.prototype._updateProgress = function(evt) {\n if (evt.lengthComputable) {\n var percentComplete = evt.loaded / evt.total * 0.99;\n this._whileLoading(percentComplete, evt);\n // ...\n } else {\n // Unable to compute progress information since the total size is unknown\n this._whileLoading('size unknown');\n }\n };\n\n /**\n * Returns true if the sound file finished loading successfully.\n *\n * @method isLoaded\n * @for p5.SoundFile\n * @return {Boolean}\n */\n p5.SoundFile.prototype.isLoaded = function() {\n if (this.buffer) {\n return true;\n } else {\n return false;\n }\n };\n\n /**\n * Play the p5.SoundFile\n *\n * @method play\n * @for p5.SoundFile\n * @param {Number} [startTime] (optional) schedule playback to start (in seconds from now).\n * @param {Number} [rate] (optional) playback rate\n * @param {Number} [amp] (optional) amplitude (volume)\n * of playback\n * @param {Number} [cueStart] (optional) cue start time in seconds\n * @param {Number} [duration] (optional) duration of playback in seconds\n */\n p5.SoundFile.prototype.play = function(startTime, rate, amp, _cueStart, duration) {\n if (!this.output) {\n console.warn('SoundFile.play() called after dispose');\n return;\n }\n\n var now = p5sound.audiocontext.currentTime;\n var cueStart, cueEnd;\n var time = startTime || 0;\n if (time < 0) {\n time = 0;\n }\n\n time = time + now;\n\n if (typeof rate !== 'undefined') {\n this.rate(rate);\n }\n\n if (typeof amp !== 'undefined') {\n this.setVolume(amp);\n }\n\n // TO DO: if already playing, create array of buffers for easy stop()\n if (this.buffer) {\n\n // reset the pause time (if it was paused)\n this._pauseTime = 0;\n\n // handle restart playmode\n if (this.mode === 'restart' && this.buffer && this.bufferSourceNode) {\n this.bufferSourceNode.stop(time);\n this._counterNode.stop(time);\n }\n\n //dont create another instance if already playing\n if (this.mode === 'untildone' && this.isPlaying()) {\n return;\n }\n // make a new source and counter. They are automatically assigned playbackRate and buffer\n this.bufferSourceNode = this._initSourceNode();\n\n // garbage collect counterNode and create a new one\n delete this._counterNode;\n this._counterNode = this._initCounterNode();\n\n if (_cueStart) {\n if (_cueStart >=0 && _cueStart < this.buffer.duration) {\n // this.startTime = cueStart;\n cueStart = _cueStart;\n } else { throw 'start time out of range'; }\n } else {\n cueStart = 0;\n }\n\n if (duration) {\n // if duration is greater than buffer.duration, just play entire file anyway rather than throw an error\n duration = duration <= this.buffer.duration - cueStart ? duration : this.buffer.duration;\n }\n\n // if it was paused, play at the pause position\n if (this._paused) {\n this.bufferSourceNode.start(time, this.pauseTime, duration);\n this._counterNode.start(time, this.pauseTime, duration);\n } else {\n this.bufferSourceNode.start(time, cueStart, duration);\n this._counterNode.start(time, cueStart, duration);\n }\n\n this._playing = true;\n this._paused = false;\n\n // add source to sources array, which is used in stopAll()\n this.bufferSourceNodes.push(this.bufferSourceNode);\n this.bufferSourceNode._arrayIndex = this.bufferSourceNodes.length - 1;\n\n this.bufferSourceNode.addEventListener('ended', this._clearOnEnd);\n }\n // If soundFile hasn't loaded the buffer yet, throw an error\n else {\n throw 'not ready to play file, buffer has yet to load. Try preload()';\n }\n\n // if looping, will restart at original time\n this.bufferSourceNode.loop = this._looping;\n this._counterNode.loop = this._looping;\n\n if (this._looping === true) {\n cueEnd = duration ? duration : cueStart - 0.000000000000001;\n this.bufferSourceNode.loopStart = cueStart;\n this.bufferSourceNode.loopEnd = cueEnd;\n this._counterNode.loopStart = cueStart;\n this._counterNode.loopEnd = cueEnd;\n }\n\n this._workletNode.port.postMessage({ name: 'play' });\n };\n\n\n /**\n * p5.SoundFile has two play modes: restart and\n * sustain. Play Mode determines what happens to a\n * p5.SoundFile if it is triggered while in the middle of playback.\n * In sustain mode, playback will continue simultaneous to the\n * new playback. In restart mode, play() will stop playback\n * and start over. With untilDone, a sound will play only if it's\n * not already playing. Sustain is the default mode.\n *\n * @method playMode\n * @for p5.SoundFile\n * @param {String} str 'restart' or 'sustain' or 'untilDone'\n * @example\n *
\n * var mySound;\n * function preload(){\n * mySound = loadSound('assets/Damscray_DancingTiger.mp3');\n * }\n * function mouseClicked() {\n * mySound.playMode('sustain');\n * mySound.play();\n * }\n * function keyPressed() {\n * mySound.playMode('restart');\n * mySound.play();\n * }\n *\n *
\n */\n p5.SoundFile.prototype.playMode = function(str) {\n var s = str.toLowerCase();\n\n // if restart, stop all other sounds from playing\n if (s === 'restart' && this.buffer && this.bufferSourceNode) {\n for (var i = 0; i < this.bufferSourceNodes.length - 1; i++) {\n var now = p5sound.audiocontext.currentTime;\n this.bufferSourceNodes[i].stop(now);\n }\n }\n\n // set play mode to effect future playback\n if (s === 'restart' || s === 'sustain' || s === 'untildone') {\n this.mode = s;\n } else {\n throw 'Invalid play mode. Must be either \"restart\" or \"sustain\"';\n }\n };\n\n /**\n * Pauses a file that is currently playing. If the file is not\n * playing, then nothing will happen.\n *\n * After pausing, .play() will resume from the paused\n * position.\n * If p5.SoundFile had been set to loop before it was paused,\n * it will continue to loop after it is unpaused with .play().\n *\n * @method pause\n * @for p5.SoundFile\n * @param {Number} [startTime] (optional) schedule event to occur\n * seconds from now\n * @example\n *
\n */\n p5.SoundFile.prototype.pause = function(startTime) {\n var now = p5sound.audiocontext.currentTime;\n var time = startTime || 0;\n var pTime = time + now;\n\n if (this.isPlaying() && this.buffer && this.bufferSourceNode) {\n this._workletNode.port.postMessage({ name: 'pause' });\n\n this.pauseTime = this.currentTime();\n this.bufferSourceNode.stop(pTime);\n this._counterNode.stop(pTime);\n this._paused = true;\n this._playing = false;\n\n this._pauseTime = this.currentTime();\n // TO DO: make sure play() still starts from orig start position\n } else {\n this._pauseTime = 0;\n }\n };\n\n /**\n * Loop the p5.SoundFile. Accepts optional parameters to set the\n * playback rate, playback volume, loopStart, loopEnd.\n *\n * @method loop\n * @for p5.SoundFile\n * @param {Number} [startTime] (optional) schedule event to occur\n * seconds from now\n * @param {Number} [rate] (optional) playback rate\n * @param {Number} [amp] (optional) playback volume\n * @param {Number} [cueLoopStart] (optional) startTime in seconds\n * @param {Number} [duration] (optional) loop duration in seconds\n */\n p5.SoundFile.prototype.loop = function(startTime, rate, amp, loopStart, duration) {\n this._looping = true;\n this.play(startTime, rate, amp, loopStart, duration);\n };\n\n /**\n * Set a p5.SoundFile's looping flag to true or false. If the sound\n * is currently playing, this change will take effect when it\n * reaches the end of the current playback.\n *\n * @method setLoop\n * @for p5.SoundFile\n * @param {Boolean} Boolean set looping to true or false\n */\n p5.SoundFile.prototype.setLoop = function(bool) {\n if (bool === true) {\n this._looping = true;\n }\n else if (bool === false) {\n this._looping = false;\n }\n else {\n throw 'Error: setLoop accepts either true or false';\n }\n if (this.bufferSourceNode) {\n this.bufferSourceNode.loop = this._looping;\n this._counterNode.loop = this._looping;\n }\n };\n\n /**\n * Returns 'true' if a p5.SoundFile is currently looping and playing, 'false' if not.\n *\n * @method isLooping\n * @for p5.SoundFile\n * @return {Boolean}\n */\n p5.SoundFile.prototype.isLooping = function() {\n if (!this.bufferSourceNode) {\n return false;\n }\n if (this._looping === true && this.isPlaying() === true) {\n return true;\n }\n return false;\n };\n\n /**\n * Returns true if a p5.SoundFile is playing, false if not (i.e.\n * paused or stopped).\n *\n * @method isPlaying\n * @for p5.SoundFile\n * @return {Boolean}\n */\n p5.SoundFile.prototype.isPlaying = function() {\n return this._playing;\n };\n\n /**\n * Returns true if a p5.SoundFile is paused, false if not (i.e.\n * playing or stopped).\n *\n * @method isPaused\n * @for p5.SoundFile\n * @return {Boolean}\n */\n p5.SoundFile.prototype.isPaused = function() {\n return this._paused;\n };\n\n /**\n * Stop soundfile playback.\n *\n * @method stop\n * @for p5.SoundFile\n * @param {Number} [startTime] (optional) schedule event to occur\n * in seconds from now\n */\n p5.SoundFile.prototype.stop = function(timeFromNow) {\n var time = timeFromNow || 0;\n\n if (this.mode === 'sustain' || this.mode === 'untildone') {\n this.stopAll(time);\n this._playing = false;\n this.pauseTime = 0;\n this._paused = false;\n }\n else if (this.buffer && this.bufferSourceNode) {\n var now = p5sound.audiocontext.currentTime;\n var t = time || 0;\n this.pauseTime = 0;\n this.bufferSourceNode.stop(now + t);\n this._counterNode.stop(now + t);\n this._playing = false;\n this._paused = false;\n }\n };\n\n /**\n * Stop playback on all of this soundfile's sources.\n * @private\n */\n p5.SoundFile.prototype.stopAll = function(_time) {\n var now = p5sound.audiocontext.currentTime;\n var time = _time || 0;\n if (this.buffer && this.bufferSourceNode) {\n for (var i in this.bufferSourceNodes) {\n const bufferSourceNode = this.bufferSourceNodes[i];\n if (!!bufferSourceNode) {\n try {\n bufferSourceNode.stop(now + time);\n } catch(e) {\n // this was throwing errors only on Safari\n }\n }\n }\n this._counterNode.stop(now + time);\n this._onended(this);\n }\n };\n\n /**\n * Multiply the output volume (amplitude) of a sound file\n * between 0.0 (silence) and 1.0 (full volume).\n * 1.0 is the maximum amplitude of a digital sound, so multiplying\n * by greater than 1.0 may cause digital distortion. To\n * fade, provide a rampTime parameter. For more\n * complex fades, see the Envelope class.\n *\n * Alternately, you can pass in a signal source such as an\n * oscillator to modulate the amplitude with an audio signal.\n *\n * @method setVolume\n * @for p5.SoundFile\n * @param {Number|Object} volume Volume (amplitude) between 0.0\n * and 1.0 or modulating signal/oscillator\n * @param {Number} [rampTime] Fade for t seconds\n * @param {Number} [timeFromNow] Schedule this event to happen at\n * t seconds in the future\n */\n p5.SoundFile.prototype.setVolume = function(vol, _rampTime, _tFromNow) {\n if (typeof vol === 'number') {\n var rampTime = _rampTime || 0;\n var tFromNow = _tFromNow || 0;\n var now = p5sound.audiocontext.currentTime;\n var currentVol = this.output.gain.value;\n this.output.gain.cancelScheduledValues(now + tFromNow);\n this.output.gain.linearRampToValueAtTime(currentVol, now + tFromNow);\n this.output.gain.linearRampToValueAtTime(vol, now + tFromNow + rampTime);\n }\n else if (vol) {\n vol.connect(this.output.gain);\n } else {\n // return the Gain Node\n return this.output.gain;\n }\n };\n\n // same as setVolume, to match Processing Sound\n p5.SoundFile.prototype.amp = p5.SoundFile.prototype.setVolume;\n\n // these are the same thing\n p5.SoundFile.prototype.fade = p5.SoundFile.prototype.setVolume;\n\n p5.SoundFile.prototype.getVolume = function() {\n return this.output.gain.value;\n };\n\n /**\n * Set the stereo panning of a p5.sound object to\n * a floating point number between -1.0 (left) and 1.0 (right).\n * Default is 0.0 (center).\n *\n * @method pan\n * @for p5.SoundFile\n * @param {Number} [panValue] Set the stereo panner\n * @param {Number} [timeFromNow] schedule this event to happen\n * seconds from now\n * @example\n *
\n *\n * var ball = {};\n * var soundFile;\n *\n * function preload() {\n * soundFormats('ogg', 'mp3');\n * soundFile = loadSound('assets/beatbox.mp3');\n * }\n *\n * function draw() {\n * background(0);\n * ball.x = constrain(mouseX, 0, width);\n * ellipse(ball.x, height/2, 20, 20)\n * }\n *\n * function mousePressed(){\n * // map the ball's x location to a panning degree\n * // between -1.0 (left) and 1.0 (right)\n * var panning = map(ball.x, 0., width,-1.0, 1.0);\n * soundFile.pan(panning);\n * soundFile.play();\n * }\n *
\n */\n p5.SoundFile.prototype.pan = function(pval, tFromNow) {\n this.panPosition = pval;\n this.panner.pan(pval, tFromNow);\n };\n\n /**\n * Returns the current stereo pan position (-1.0 to 1.0)\n *\n * @method getPan\n * @for p5.SoundFile\n * @return {Number} Returns the stereo pan setting of the Oscillator\n * as a number between -1.0 (left) and 1.0 (right).\n * 0.0 is center and default.\n */\n p5.SoundFile.prototype.getPan = function() {\n return this.panPosition;\n };\n\n /**\n * Set the playback rate of a sound file. Will change the speed and the pitch.\n * Values less than zero will reverse the audio buffer.\n *\n * @method rate\n * @for p5.SoundFile\n * @param {Number} [playbackRate] Set the playback rate. 1.0 is normal,\n * .5 is half-speed, 2.0 is twice as fast.\n * Values less than zero play backwards.\n * @example\n *
\n * var song;\n *\n * function preload() {\n * song = loadSound('assets/Damscray_DancingTiger.mp3');\n * }\n *\n * function setup() {\n * song.loop();\n * }\n *\n * function draw() {\n * background(200);\n *\n * // Set the rate to a range between 0.1 and 4\n * // Changing the rate also alters the pitch\n * var speed = map(mouseY, 0.1, height, 0, 2);\n * speed = constrain(speed, 0.01, 4);\n * song.rate(speed);\n *\n * // Draw a circle to show what is going on\n * stroke(0);\n * fill(51, 100);\n * ellipse(mouseX, 100, 48, 48);\n * }\n *\n * \n *
\n *\n */\n p5.SoundFile.prototype.rate = function(playbackRate) {\n var reverse = false;\n if (typeof playbackRate === 'undefined') {\n return this.playbackRate;\n }\n\n this.playbackRate = playbackRate;\n\n if (playbackRate === 0) {\n playbackRate = 0.0000000000001;\n }\n\n else if (playbackRate < 0 && !this.reversed) {\n playbackRate = Math.abs(playbackRate);\n reverse = true;\n }\n\n else if (playbackRate > 0 && this.reversed) {\n reverse = true;\n }\n\n if (this.bufferSourceNode) {\n var now = p5sound.audiocontext.currentTime;\n this.bufferSourceNode.playbackRate.cancelScheduledValues(now);\n this.bufferSourceNode.playbackRate.linearRampToValueAtTime(Math.abs(playbackRate), now);\n this._counterNode.playbackRate.cancelScheduledValues(now);\n this._counterNode.playbackRate.linearRampToValueAtTime(Math.abs(playbackRate), now);\n }\n\n if (reverse) {\n this.reverseBuffer();\n }\n return this.playbackRate;\n };\n\n // TO DO: document this\n p5.SoundFile.prototype.setPitch = function(num) {\n var newPlaybackRate = midiToFreq(num) / midiToFreq(60);\n this.rate(newPlaybackRate);\n };\n\n p5.SoundFile.prototype.getPlaybackRate = function() {\n return this.playbackRate;\n };\n\n /**\n * Returns the duration of a sound file in seconds.\n *\n * @method duration\n * @for p5.SoundFile\n * @return {Number} The duration of the soundFile in seconds.\n */\n p5.SoundFile.prototype.duration = function() {\n // Return Duration\n if (this.buffer) {\n return this.buffer.duration;\n } else {\n return 0;\n }\n };\n\n /**\n * Return the current position of the p5.SoundFile playhead, in seconds.\n * Time is relative to the normal buffer direction, so if `reverseBuffer`\n * has been called, currentTime will count backwards.\n *\n * @method currentTime\n * @for p5.SoundFile\n * @return {Number} currentTime of the soundFile in seconds.\n */\n p5.SoundFile.prototype.currentTime = function() {\n return this.reversed\n ? Math.abs(this._lastPos - this.buffer.length) / ac.sampleRate\n : this._lastPos / ac.sampleRate;\n };\n\n /**\n * Move the playhead of the song to a position, in seconds. Start timing\n * and playback duration. If none are given, will reset the file to play\n * entire duration from start to finish.\n *\n * @method jump\n * @for p5.SoundFile\n * @param {Number} cueTime cueTime of the soundFile in seconds.\n * @param {Number} duration duration in seconds.\n */\n p5.SoundFile.prototype.jump = function(cueTime, duration) {\n if (cueTime < 0 || cueTime > this.buffer.duration) {\n throw 'jump time out of range';\n }\n if (duration > this.buffer.duration - cueTime) {\n throw 'end time out of range';\n }\n\n var cTime = cueTime || 0;\n var dur = duration || undefined;\n if (this.isPlaying()) {\n this.stop(0);\n }\n this.play(0, this.playbackRate, this.output.gain.value, cTime, dur);\n };\n\n /**\n * Return the number of channels in a sound file.\n * For example, Mono = 1, Stereo = 2.\n *\n * @method channels\n * @for p5.SoundFile\n * @return {Number} [channels]\n */\n p5.SoundFile.prototype.channels = function() {\n return this.buffer.numberOfChannels;\n };\n\n /**\n * Return the sample rate of the sound file.\n *\n * @method sampleRate\n * @for p5.SoundFile\n * @return {Number} [sampleRate]\n */\n p5.SoundFile.prototype.sampleRate = function() {\n return this.buffer.sampleRate;\n };\n\n /**\n * Return the number of samples in a sound file.\n * Equal to sampleRate * duration.\n *\n * @method frames\n * @for p5.SoundFile\n * @return {Number} [sampleCount]\n */\n p5.SoundFile.prototype.frames = function() {\n return this.buffer.length;\n };\n\n /**\n * Returns an array of amplitude peaks in a p5.SoundFile that can be\n * used to draw a static waveform. Scans through the p5.SoundFile's\n * audio buffer to find the greatest amplitudes. Accepts one\n * parameter, 'length', which determines size of the array.\n * Larger arrays result in more precise waveform visualizations.\n *\n * Inspired by Wavesurfer.js.\n *\n * @method getPeaks\n * @for p5.SoundFile\n * @params {Number} [length] length is the size of the returned array.\n * Larger length results in more precision.\n * Defaults to 5*width of the browser window.\n * @returns {Float32Array} Array of peaks.\n */\n p5.SoundFile.prototype.getPeaks = function(length) {\n\n if (this.buffer) {\n // set length to window's width if no length is provided\n if (!length) {\n length = window.width*5;\n }\n if (this.buffer) {\n var buffer = this.buffer;\n var sampleSize = buffer.length / length;\n var sampleStep = ~~(sampleSize / 10) || 1;\n var channels = buffer.numberOfChannels;\n var peaks = new Float32Array(Math.round(length));\n\n for (var c = 0; c < channels; c++) {\n var chan = buffer.getChannelData(c);\n for (var i = 0; i < length; i++) {\n var start = ~~(i*sampleSize);\n var end = ~~(start + sampleSize);\n var max = 0;\n for (var j = start; j < end; j+= sampleStep) {\n var value = chan[j];\n if (value > max) {\n max = value;\n // faster than Math.abs\n } else if (-value > max) {\n max = value;\n }\n }\n if (c === 0 || Math.abs(max) > peaks[i]) {\n peaks[i] = max;\n }\n }\n }\n\n return peaks;\n }\n }\n\n else {\n throw 'Cannot load peaks yet, buffer is not loaded';\n }\n };\n\n /**\n * Reverses the p5.SoundFile's buffer source.\n * Playback must be handled separately (see example).\n *\n * @method reverseBuffer\n * @for p5.SoundFile\n * @example\n *
\n * var drum;\n *\n * function preload() {\n * drum = loadSound('assets/drum.mp3');\n * }\n *\n * function setup() {\n * drum.reverseBuffer();\n * drum.play();\n * }\n *\n * \n *
\n */\n p5.SoundFile.prototype.reverseBuffer = function() {\n if (this.buffer) {\n var currentPos = this._lastPos / ac.sampleRate;\n var curVol = this.getVolume();\n this.setVolume(0, 0.001);\n\n const numChannels = this.buffer.numberOfChannels;\n for (var i = 0; i < numChannels; i++) {\n this.buffer.getChannelData(i).reverse();\n }\n // set reversed flag\n this.reversed = !this.reversed;\n\n if (currentPos) {\n this.jump(this.duration() - currentPos);\n }\n this.setVolume(curVol, 0.001);\n } else {\n throw 'SoundFile is not done loading';\n }\n };\n\n /**\n * Schedule an event to be called when the soundfile\n * reaches the end of a buffer. If the soundfile is\n * playing through once, this will be called when it\n * ends. If it is looping, it will be called when\n * stop is called.\n *\n * @method onended\n * @for p5.SoundFile\n * @param {Function} callback function to call when the\n * soundfile has ended.\n */\n p5.SoundFile.prototype.onended = function(callback) {\n this._onended = callback;\n return this;\n };\n\n p5.SoundFile.prototype.add = function() {\n // TO DO\n };\n\n p5.SoundFile.prototype.dispose = function() {\n var now = p5sound.audiocontext.currentTime;\n\n // remove reference to soundfile\n var index = p5sound.soundArray.indexOf(this);\n p5sound.soundArray.splice(index, 1);\n\n this.stop(now);\n if (this.buffer && this.bufferSourceNode) {\n for (var i = 0; i < this.bufferSourceNodes.length - 1; i++) {\n if (this.bufferSourceNodes[i] !== null) {\n this.bufferSourceNodes[i].disconnect();\n try {\n this.bufferSourceNodes[i].stop(now);\n } catch(e) {\n console.warning('no buffer source node to dispose');\n }\n this.bufferSourceNodes[i] = null;\n }\n }\n if ( this.isPlaying() ) {\n try {\n this._counterNode.stop(now);\n } catch(e) {\n console.log(e);\n }\n this._counterNode = null;\n }\n }\n if (this.output) {\n this.output.disconnect();\n this.output = null;\n }\n if (this.panner) {\n this.panner.disconnect();\n this.panner = null;\n }\n };\n\n /**\n * Connects the output of a p5sound object to input of another\n * p5.sound object. For example, you may connect a p5.SoundFile to an\n * FFT or an Effect. If no parameter is given, it will connect to\n * the master output. Most p5sound objects connect to the master\n * output when they are created.\n *\n * @method connect\n * @for p5.SoundFile\n * @param {Object} [object] Audio object that accepts an input\n */\n p5.SoundFile.prototype.connect = function(unit) {\n if (!unit) {\n this.panner.connect(p5sound.input);\n }\n else {\n if (unit.hasOwnProperty('input')) {\n this.panner.connect(unit.input);\n } else {\n this.panner.connect(unit);\n }\n }\n };\n\n /**\n * Disconnects the output of this p5sound object.\n *\n * @method disconnect\n * @for p5.SoundFile\n */\n p5.SoundFile.prototype.disconnect = function() {\n if (this.panner) {\n this.panner.disconnect();\n }\n };\n\n /**\n */\n p5.SoundFile.prototype.getLevel = function() {\n console.warn('p5.SoundFile.getLevel has been removed from the library. Use p5.Amplitude instead');\n };\n\n /**\n * Reset the source for this SoundFile to a\n * new path (URL).\n *\n * @method setPath\n * @for p5.SoundFile\n * @param {String} path path to audio file\n * @param {Function} callback Callback\n */\n p5.SoundFile.prototype.setPath = function(p, callback) {\n var path = p5.prototype._checkFileFormats(p);\n this.url = path;\n this.load(callback);\n };\n\n /**\n * Replace the current Audio Buffer with a new Buffer.\n *\n * @method setBuffer\n * @for p5.SoundFile\n * @param {Array} buf Array of Float32 Array(s). 2 Float32 Arrays\n * will create a stereo source. 1 will create\n * a mono source.\n */\n p5.SoundFile.prototype.setBuffer = function(buf) {\n var numChannels = buf.length;\n var size = buf[0].length;\n var newBuffer = ac.createBuffer(numChannels, size, ac.sampleRate);\n\n if (!(buf[0] instanceof Float32Array)) {\n buf[0] = new Float32Array(buf[0]);\n }\n\n for (var channelNum = 0; channelNum < numChannels; channelNum++) {\n var channel = newBuffer.getChannelData( channelNum );\n channel.set(buf[channelNum]);\n }\n\n this.buffer = newBuffer;\n\n // set numbers of channels on input to the panner\n this.panner.inputChannels(numChannels);\n };\n\n //////////////////////////////////////////////////\n // script processor node with an empty buffer to help\n // keep a sample-accurate position in playback buffer.\n // Inspired by Chinmay Pendharkar's technique for Sonoport --> http://bit.ly/1HwdCsV\n // Copyright [2015] [Sonoport (Asia) Pte. Ltd.],\n // Licensed under the Apache License http://apache.org/licenses/LICENSE-2.0\n ////////////////////////////////////////////////////////////////////////////////////\n\n var _createCounterBuffer = function(buffer) {\n const len = buffer.length;\n const audioBuf = ac.createBuffer( 1, buffer.length, ac.sampleRate );\n const arrayBuffer = audioBuf.getChannelData(0);\n for (var index = 0; index < len; index++) {\n arrayBuffer[index] = index;\n }\n return audioBuf;\n };\n\n // initialize counterNode, set its initial buffer and playbackRate\n p5.SoundFile.prototype._initCounterNode = function() {\n var self = this;\n var now = ac.currentTime;\n var cNode = ac.createBufferSource();\n\n // dispose of worklet node if it already exists\n if (self._workletNode) {\n self._workletNode.disconnect();\n delete self._workletNode;\n }\n self._workletNode = new AudioWorkletNode(ac, processorNames.soundFileProcessor);\n self._workletNode.port.onmessage = function(event) {\n if (event.data.name === 'position') {\n this._lastPos = event.data.position;\n\n // do any callbacks that have been scheduled\n this._onTimeUpdate(self._lastPos);\n }\n }.bind(self);\n\n // create counter buffer of the same length as self.buffer\n cNode.buffer = _createCounterBuffer( self.buffer );\n\n cNode.playbackRate.setValueAtTime(self.playbackRate, now);\n\n cNode.connect(self._workletNode);\n self._workletNode.connect(p5.soundOut._silentNode);\n\n return cNode;\n };\n\n // initialize sourceNode, set its initial buffer and playbackRate\n p5.SoundFile.prototype._initSourceNode = function() {\n var bufferSourceNode = ac.createBufferSource();\n bufferSourceNode.buffer = this.buffer;\n bufferSourceNode.playbackRate.value = this.playbackRate;\n bufferSourceNode.connect(this.output);\n return bufferSourceNode;\n };\n\n /**\n * processPeaks returns an array of timestamps where it thinks there is a beat.\n *\n * This is an asynchronous function that processes the soundfile in an offline audio context,\n * and sends the results to your callback function.\n *\n * The process involves running the soundfile through a lowpass filter, and finding all of the\n * peaks above the initial threshold. If the total number of peaks are below the minimum number of peaks,\n * it decreases the threshold and re-runs the analysis until either minPeaks or minThreshold are reached.\n *\n * @method processPeaks\n * @for p5.SoundFile\n * @param {Function} callback a function to call once this data is returned\n * @param {Number} [initThreshold] initial threshold defaults to 0.9\n * @param {Number} [minThreshold] minimum threshold defaults to 0.22\n * @param {Number} [minPeaks] minimum number of peaks defaults to 200\n * @return {Array} Array of timestamped peaks\n */\n p5.SoundFile.prototype.processPeaks = function(callback, _initThreshold, _minThreshold, _minPeaks) {\n var bufLen = this.buffer.length;\n var sampleRate = this.buffer.sampleRate;\n var buffer = this.buffer;\n var allPeaks = [];\n\n var initialThreshold = _initThreshold || 0.9,\n threshold = initialThreshold,\n minThreshold = _minThreshold || 0.22,\n minPeaks = _minPeaks || 200;\n\n // Create offline context\n var offlineContext = new window.OfflineAudioContext(1, bufLen, sampleRate);\n\n // create buffer source\n var source = offlineContext.createBufferSource();\n source.buffer = buffer;\n\n // Create filter. TO DO: allow custom setting of filter\n var filter = offlineContext.createBiquadFilter();\n filter.type = 'lowpass';\n source.connect(filter);\n filter.connect(offlineContext.destination);\n\n // start playing at time:0\n source.start(0);\n offlineContext.startRendering(); // Render the song\n\n // act on the result\n offlineContext.oncomplete = function(e) {\n if (!self.panner) return;\n var filteredBuffer = e.renderedBuffer;\n var bufferData = filteredBuffer.getChannelData(0);\n\n\n // step 1:\n // create Peak instances, add them to array, with strength and sampleIndex\n do {\n allPeaks = getPeaksAtThreshold(bufferData, threshold);\n threshold -= 0.005;\n } while (Object.keys(allPeaks).length < minPeaks && threshold >= minThreshold);\n\n\n // step 2:\n // find intervals for each peak in the sampleIndex, add tempos array\n var intervalCounts = countIntervalsBetweenNearbyPeaks(allPeaks);\n\n // step 3: find top tempos\n var groups = groupNeighborsByTempo(intervalCounts, filteredBuffer.sampleRate);\n\n // sort top intervals\n var topTempos = groups.sort(function(intA, intB) {\n return intB.count - intA.count;\n\n }).splice(0,5);\n\n // set this SoundFile's tempo to the top tempo ??\n this.tempo = topTempos[0].tempo;\n\n // step 4:\n // new array of peaks at top tempo within a bpmVariance\n var bpmVariance = 5;\n var tempoPeaks = getPeaksAtTopTempo(allPeaks, topTempos[0].tempo, filteredBuffer.sampleRate, bpmVariance);\n\n callback(tempoPeaks);\n };\n };\n\n // process peaks\n var Peak = function(amp, i) {\n this.sampleIndex = i;\n this.amplitude = amp;\n this.tempos = [];\n this.intervals = [];\n };\n\n // 1. for processPeaks() Function to identify peaks above a threshold\n // returns an array of peak indexes as frames (samples) of the original soundfile\n function getPeaksAtThreshold(data, threshold) {\n var peaksObj = {};\n var length = data.length;\n\n for (var i = 0; i < length; i++) {\n if (data[i] > threshold) {\n var amp = data[i];\n var peak = new Peak(amp, i);\n peaksObj[i] = peak;\n // Skip forward ~ 1/8s to get past this peak.\n i += 6000;\n }\n i++;\n }\n return peaksObj;\n }\n\n // 2. for processPeaks()\n function countIntervalsBetweenNearbyPeaks(peaksObj) {\n var intervalCounts = [];\n var peaksArray = Object.keys(peaksObj).sort();\n\n for (var index = 0; index < peaksArray.length; index++) {\n\n // find intervals in comparison to nearby peaks\n for (var i = 0; i < 10; i++) {\n var startPeak = peaksObj[peaksArray[index]];\n var endPeak = peaksObj[peaksArray[index + i]];\n\n if (startPeak && endPeak) {\n var startPos = startPeak.sampleIndex;\n var endPos = endPeak.sampleIndex;\n var interval = endPos - startPos;\n\n // add a sample interval to the startPeak in the allPeaks array\n if (interval > 0) {\n startPeak.intervals.push(interval);\n }\n\n // tally the intervals and return interval counts\n var foundInterval = intervalCounts.some(function(intervalCount) {\n if (intervalCount.interval === interval) {\n intervalCount.count++;\n return intervalCount;\n }\n });\n\n // store with JSON like formatting\n if (!foundInterval) {\n intervalCounts.push({\n interval: interval,\n count: 1,\n });\n }\n }\n }\n }\n\n return intervalCounts;\n }\n\n\n // 3. for processPeaks --> find tempo\n function groupNeighborsByTempo(intervalCounts, sampleRate) {\n var tempoCounts = [];\n\n intervalCounts.forEach(function(intervalCount) {\n\n try {\n // Convert an interval to tempo\n var theoreticalTempo = Math.abs( 60 / (intervalCount.interval / sampleRate ) );\n\n theoreticalTempo = mapTempo(theoreticalTempo);\n\n var foundTempo = tempoCounts.some(function(tempoCount) {\n if (tempoCount.tempo === theoreticalTempo)\n return tempoCount.count += intervalCount.count;\n });\n if (!foundTempo) {\n if (isNaN(theoreticalTempo)) {\n return;\n }\n tempoCounts.push({\n tempo: Math.round(theoreticalTempo),\n count: intervalCount.count\n });\n }\n } catch(e) {\n throw e;\n }\n\n });\n\n return tempoCounts;\n }\n\n // 4. for processPeaks - get peaks at top tempo\n function getPeaksAtTopTempo(peaksObj, tempo, sampleRate, bpmVariance) {\n var peaksAtTopTempo = [];\n var peaksArray = Object.keys(peaksObj).sort();\n\n // TO DO: filter out peaks that have the tempo and return\n for (var i = 0; i < peaksArray.length; i++) {\n var key = peaksArray[i];\n var peak = peaksObj[key];\n\n for (var j = 0; j < peak.intervals.length; j++) {\n var intervalBPM = Math.round(Math.abs( 60 / (peak.intervals[j] / sampleRate) ) );\n\n intervalBPM = mapTempo(intervalBPM);\n\n if ( Math.abs(intervalBPM - tempo) < bpmVariance ) {\n // convert sampleIndex to seconds\n peaksAtTopTempo.push(peak.sampleIndex/sampleRate);\n }\n }\n }\n\n // filter out peaks that are very close to each other\n peaksAtTopTempo = peaksAtTopTempo.filter(function(peakTime, index, arr) {\n var dif = arr[index + 1] - peakTime;\n if (dif > 0.01) {\n return true;\n }\n });\n\n return peaksAtTopTempo;\n }\n\n // helper function for processPeaks\n function mapTempo(theoreticalTempo) {\n // these scenarios create infinite while loop\n if (!isFinite(theoreticalTempo) || theoreticalTempo === 0 ) {\n return;\n }\n\n // Adjust the tempo to fit within the 90-180 BPM range\n while (theoreticalTempo < 90) theoreticalTempo *= 2;\n while (theoreticalTempo > 180 && theoreticalTempo > 90) theoreticalTempo /= 2;\n\n return theoreticalTempo;\n }\n\n\n /*** SCHEDULE EVENTS ***/\n\n // Cue inspired by JavaScript setTimeout, and the\n // Tone.js Transport Timeline Event, MIT License Yotam Mann 2015 tonejs.org\n var Cue = function(callback, time, id, val) {\n this.callback = callback;\n this.time = time;\n this.id = id;\n this.val = val;\n };\n\n /**\n * Schedule events to trigger every time a MediaElement\n * (audio/video) reaches a playback cue point.\n *\n * Accepts a callback function, a time (in seconds) at which to trigger\n * the callback, and an optional parameter for the callback.\n *\n * Time will be passed as the first parameter to the callback function,\n * and param will be the second parameter.\n *\n *\n * @method addCue\n * @for p5.SoundFile\n * @param {Number} time Time in seconds, relative to this media\n * element's playback. For example, to trigger\n * an event every time playback reaches two\n * seconds, pass in the number 2. This will be\n * passed as the first parameter to\n * the callback function.\n * @param {Function} callback Name of a function that will be\n * called at the given time. The callback will\n * receive time and (optionally) param as its\n * two parameters.\n * @param {Object} [value] An object to be passed as the\n * second parameter to the\n * callback function.\n * @return {Number} id ID of this cue,\n * useful for removeCue(id)\n * @example\n *
\n */\n p5.SoundFile.prototype.addCue = function(time, callback, val) {\n var id = this._cueIDCounter++;\n\n var cue = new Cue(callback, time, id, val);\n this._cues.push(cue);\n\n // if (!this.elt.ontimeupdate) {\n // this.elt.ontimeupdate = this._onTimeUpdate.bind(this);\n // }\n\n return id;\n };\n\n /**\n * Remove a callback based on its ID. The ID is returned by the\n * addCue method.\n *\n * @method removeCue\n * @for p5.SoundFile\n * @param {Number} id ID of the cue, as returned by addCue\n */\n p5.SoundFile.prototype.removeCue = function(id) {\n var cueLength = this._cues.length;\n for (var i = 0; i < cueLength; i++) {\n var cue = this._cues[i];\n if (cue.id === id) {\n this._cues.splice(i, 1);\n break;\n }\n }\n\n if (this._cues.length === 0) {\n // TO DO: remove callback\n // this.elt.ontimeupdate = null\n }\n };\n\n /**\n * Remove all of the callbacks that had originally been scheduled\n * via the addCue method.\n *\n * @method clearCues\n */\n p5.SoundFile.prototype.clearCues = function() {\n this._cues = [];\n // this.elt.ontimeupdate = null;\n };\n\n // private method that checks for cues to be fired if events\n // have been scheduled using addCue(callback, time).\n p5.SoundFile.prototype._onTimeUpdate = function(position) {\n var playbackTime = position/this.buffer.sampleRate;\n var cueLength = this._cues.length;\n\n for (var i = 0 ; i < cueLength; i++) {\n var cue = this._cues[i];\n var callbackTime = cue.time;\n var val = cue.val;\n\n if (this._prevTime < callbackTime && callbackTime <= playbackTime) {\n\n // pass the scheduled callbackTime as parameter to the callback\n cue.callback(val);\n }\n\n }\n\n this._prevTime = playbackTime;\n };\n\n /**\n * Save a p5.SoundFile as a .wav file. The browser will prompt the user\n * to download the file to their device. To upload a file to a server, see\n * getBlob\n *\n * @method save\n * @for p5.SoundFile\n * @param {String} [fileName] name of the resulting .wav file.\n * @example\n *
\n * var inp, button, mySound;\n * var fileName = 'cool';\n * function preload() {\n * mySound = loadSound('assets/doorbell.mp3');\n * }\n * function setup() {\n * btn = createButton('click to save file');\n * btn.position(0, 0);\n * btn.mouseClicked(handleMouseClick);\n * }\n *\n * function handleMouseClick() {\n * mySound.save(fileName);\n * }\n *
\n */\n p5.SoundFile.prototype.save = function(fileName) {\n const dataView = convertToWav(this.buffer);\n p5.prototype.saveSound([dataView], fileName, 'wav');\n };\n\n /**\n * This method is useful for sending a SoundFile to a server. It returns the\n * .wav-encoded audio data as a \"Blob\".\n * A Blob is a file-like data object that can be uploaded to a server\n * with an http request. We'll\n * use the `httpDo` options object to send a POST request with some\n * specific options: we encode the request as `multipart/form-data`,\n * and attach the blob as one of the form values using `FormData`.\n *\n *\n * @method getBlob\n * @for p5.SoundFile\n * @returns {Blob} A file-like data object\n * @example\n *
\n *\n * function preload() {\n * mySound = loadSound('assets/doorbell.mp3');\n * }\n *\n * function setup() {\n * noCanvas();\n * var soundBlob = mySound.getBlob();\n *\n * // Now we can send the blob to a server...\n * var serverUrl = 'https://jsonplaceholder.typicode.com/posts';\n * var httpRequestOptions = {\n * method: 'POST',\n * body: new FormData().append('soundBlob', soundBlob),\n * headers: new Headers({\n * 'Content-Type': 'multipart/form-data'\n * })\n * };\n * httpDo(serverUrl, httpRequestOptions);\n *\n * // We can also create an `ObjectURL` pointing to the Blob\n * var blobUrl = URL.createObjectURL(soundBlob);\n *\n * // The `
\n */\n p5.SoundFile.prototype.getBlob = function() {\n const dataView = convertToWav(this.buffer);\n return new Blob([dataView], { type: 'audio/wav' });\n };\n\n // event handler to remove references to the bufferSourceNode when it is done playing\n function _clearOnEnd(e) {\n const thisBufferSourceNode = e.target;\n const soundFile = this;\n\n // delete this.bufferSourceNode from the sources array when it is done playing:\n thisBufferSourceNode._playing = false;\n thisBufferSourceNode.removeEventListener('ended', soundFile._clearOnEnd);\n\n // call the onended callback\n soundFile._onended(soundFile);\n\n soundFile.bufferSourceNodes.forEach(function (n, i) {\n if (n._playing === false) {\n soundFile.bufferSourceNodes.splice(i);\n }\n });\n\n if (soundFile.bufferSourceNodes.length === 0) {\n soundFile._playing = false;\n }\n }\n});\n","'use strict';\n\ndefine(function (require) {\n var p5sound = require('master');\n var processorNames = require('./audioWorklet/processorNames');\n\n /**\n * Amplitude measures volume between 0.0 and 1.0.\n * Listens to all p5sound by default, or use setInput()\n * to listen to a specific sound source. Accepts an optional\n * smoothing value, which defaults to 0.\n *\n * @class p5.Amplitude\n * @constructor\n * @param {Number} [smoothing] between 0.0 and .999 to smooth\n * amplitude readings (defaults to 0)\n * @example\n *
\n * var sound, amplitude, cnv;\n *\n * function preload(){\n * sound = loadSound('assets/beat.mp3');\n * }\n * function setup() {\n * cnv = createCanvas(100,100);\n * amplitude = new p5.Amplitude();\n *\n * // start / stop the sound when canvas is clicked\n * cnv.mouseClicked(function() {\n * if (sound.isPlaying() ){\n * sound.stop();\n * } else {\n * sound.play();\n * }\n * });\n * }\n * function draw() {\n * background(0);\n * fill(255);\n * var level = amplitude.getLevel();\n * var size = map(level, 0, 1, 0, 200);\n * ellipse(width/2, height/2, size, size);\n * }\n *\n *
\n */\n p5.Amplitude = function(smoothing) {\n\n // Set to 2048 for now. In future iterations, this should be inherited or parsed from p5sound's default\n this.bufferSize = 2048;\n\n // set audio context\n this.audiocontext = p5sound.audiocontext;\n this._workletNode = new AudioWorkletNode(this.audiocontext, processorNames.amplitudeProcessor, {\n outputChannelCount: [1],\n processorOptions: {\n normalize: false,\n smoothing: smoothing || 0\n }\n });\n\n this._workletNode.port.onmessage = function(event) {\n if (event.data.name === 'amplitude') {\n this.volume = event.data.volume;\n this.volNorm = event.data.volNorm;\n this.stereoVol = event.data.stereoVol;\n this.stereoVolNorm = event.data.stereoVolNorm;\n }\n }.bind(this);\n\n // for connections\n this.input = this._workletNode;\n\n this.output = this.audiocontext.createGain();\n\n // the variables to return\n this.volume = 0;\n this.volNorm = 0;\n this.stereoVol = [0, 0];\n this.stereoVolNorm = [0, 0];\n\n this.normalize = false;\n\n this._workletNode.connect(this.output);\n this.output.gain.value = 0;\n\n // this may only be necessary because of a Chrome bug\n this.output.connect(this.audiocontext.destination);\n\n // connect to p5sound master output by default, unless set by input()\n p5sound.meter.connect(this._workletNode);\n\n // add this p5.SoundFile to the soundArray\n p5sound.soundArray.push(this);\n };\n\n /**\n * Connects to the p5sound instance (master output) by default.\n * Optionally, you can pass in a specific source (i.e. a soundfile).\n *\n * @method setInput\n * @for p5.Amplitude\n * @param {soundObject|undefined} [snd] set the sound source\n * (optional, defaults to\n * master output)\n * @param {Number|undefined} [smoothing] a range between 0.0 and 1.0\n * to smooth amplitude readings\n * @example\n *
\n * function preload(){\n * sound1 = loadSound('assets/beat.mp3');\n * sound2 = loadSound('assets/drum.mp3');\n * }\n * function setup(){\n * amplitude = new p5.Amplitude();\n * sound1.play();\n * sound2.play();\n * amplitude.setInput(sound2);\n * }\n * function draw() {\n * background(0);\n * fill(255);\n * var level = amplitude.getLevel();\n * var size = map(level, 0, 1, 0, 200);\n * ellipse(width/2, height/2, size, size);\n * }\n * function mouseClicked(){\n * sound1.stop();\n * sound2.stop();\n * }\n *
\n */\n p5.Amplitude.prototype.setInput = function(source, smoothing) {\n\n p5sound.meter.disconnect();\n\n if (smoothing) {\n this._workletNode.parameters.get('smoothing').value = smoothing;\n }\n\n // connect to the master out of p5s instance if no snd is provided\n if (source == null) {\n console.log('Amplitude input source is not ready! Connecting to master output instead');\n p5sound.meter.connect(this._workletNode);\n }\n\n // if it is a p5.Signal\n else if (source instanceof p5.Signal) {\n source.output.connect(this._workletNode);\n }\n // connect to the sound if it is available\n else if (source) {\n source.connect(this._workletNode);\n this._workletNode.disconnect();\n this._workletNode.connect(this.output);\n }\n\n // otherwise, connect to the master out of p5s instance (default)\n else {\n p5sound.meter.connect(this._workletNode);\n }\n };\n\n p5.Amplitude.prototype.connect = function(unit) {\n if (unit) {\n if (unit.hasOwnProperty('input')) {\n this.output.connect(unit.input);\n } else {\n this.output.connect(unit);\n }\n } else {\n this.output.connect(this.panner.connect(p5sound.input));\n }\n };\n\n p5.Amplitude.prototype.disconnect = function() {\n if (this.output) {\n this.output.disconnect();\n }\n };\n\n /**\n * Returns a single Amplitude reading at the moment it is called.\n * For continuous readings, run in the draw loop.\n *\n * @method getLevel\n * @for p5.Amplitude\n * @param {Number} [channel] Optionally return only channel 0 (left) or 1 (right)\n * @return {Number} Amplitude as a number between 0.0 and 1.0\n * @example\n *
\n * function preload(){\n * sound = loadSound('assets/beat.mp3');\n * }\n * function setup() {\n * amplitude = new p5.Amplitude();\n * sound.play();\n * }\n * function draw() {\n * background(0);\n * fill(255);\n * var level = amplitude.getLevel();\n * var size = map(level, 0, 1, 0, 200);\n * ellipse(width/2, height/2, size, size);\n * }\n * function mouseClicked(){\n * sound.stop();\n * }\n *
\n */\n p5.Amplitude.prototype.getLevel = function(channel) {\n if (typeof channel !== 'undefined') {\n if (this.normalize) {\n return this.stereoVolNorm[channel];\n } else {\n return this.stereoVol[channel];\n }\n }\n else if (this.normalize) {\n return this.volNorm;\n }\n else {\n return this.volume;\n }\n };\n\n /**\n * Determines whether the results of Amplitude.process() will be\n * Normalized. To normalize, Amplitude finds the difference the\n * loudest reading it has processed and the maximum amplitude of\n * 1.0. Amplitude adds this difference to all values to produce\n * results that will reliably map between 0.0 and 1.0. However,\n * if a louder moment occurs, the amount that Normalize adds to\n * all the values will change. Accepts an optional boolean parameter\n * (true or false). Normalizing is off by default.\n *\n * @method toggleNormalize\n * @for p5.Amplitude\n * @param {boolean} [boolean] set normalize to true (1) or false (0)\n */\n p5.Amplitude.prototype.toggleNormalize = function(bool) {\n if (typeof bool === 'boolean') {\n this.normalize = bool;\n }\n else {\n this.normalize = !this.normalize;\n }\n this._workletNode.port.postMessage({ name: 'toggleNormalize', normalize: this.normalize });\n };\n\n /**\n * Smooth Amplitude analysis by averaging with the last analysis\n * frame. Off by default.\n *\n * @method smooth\n * @for p5.Amplitude\n * @param {Number} set smoothing from 0.0 <= 1\n */\n p5.Amplitude.prototype.smooth = function(s) {\n if (s >= 0 && s < 1) {\n this._workletNode.port.postMessage({ name: 'smoothing', smoothing: s });\n } else {\n console.log('Error: smoothing must be between 0 and 1');\n }\n };\n\n p5.Amplitude.prototype.dispose = function() {\n // remove reference from soundArray\n var index = p5sound.soundArray.indexOf(this);\n p5sound.soundArray.splice(index, 1);\n\n if (this.input) {\n this.input.disconnect();\n delete this.input;\n }\n if (this.output) {\n this.output.disconnect();\n delete this.output;\n }\n\n this._workletNode.disconnect();\n delete this._workletNode;\n };\n\n});\n","'use strict';\n\ndefine(function(require) {\n var p5sound = require('master');\n\n /**\n *
FFT (Fast Fourier Transform) is an analysis algorithm that\n * isolates individual\n * \n * audio frequencies within a waveform.
\n *\n *
Once instantiated, a p5.FFT object can return an array based on\n * two types of analyses: • FFT.waveform() computes\n * amplitude values along the time domain. The array indices correspond\n * to samples across a brief moment in time. Each value represents\n * amplitude of the waveform at that sample of time. \n * • FFT.analyze() computes amplitude values along the\n * frequency domain. The array indices correspond to frequencies (i.e.\n * pitches), from the lowest to the highest that humans can hear. Each\n * value represents amplitude at that slice of the frequency spectrum.\n * Use with getEnergy() to measure amplitude at specific\n * frequencies, or within a range of frequencies.
\n *\n *
FFT analyzes a very short snapshot of sound called a sample\n * buffer. It returns an array of amplitude measurements, referred\n * to as bins. The array is 1024 bins long by default.\n * You can change the bin array length, but it must be a power of 2\n * between 16 and 1024 in order for the FFT algorithm to function\n * correctly. The actual size of the FFT buffer is twice the\n * number of bins, so given a standard sample rate, the buffer is\n * 2048/44100 seconds long.
\n *\n *\n * @class p5.FFT\n * @constructor\n * @param {Number} [smoothing] Smooth results of Freq Spectrum.\n * 0.0 < smoothing < 1.0.\n * Defaults to 0.8.\n * @param {Number} [bins] Length of resulting array.\n * Must be a power of two between\n * 16 and 1024. Defaults to 1024.\n * @example\n *
\n * function preload(){\n * sound = loadSound('assets/Damscray_DancingTiger.mp3');\n * }\n *\n * function setup(){\n * var cnv = createCanvas(100,100);\n * cnv.mouseClicked(togglePlay);\n * fft = new p5.FFT();\n * sound.amp(0.2);\n * }\n *\n * function draw(){\n * background(0);\n *\n * var spectrum = fft.analyze();\n * noStroke();\n * fill(0,255,0); // spectrum is green\n * for (var i = 0; i< spectrum.length; i++){\n * var x = map(i, 0, spectrum.length, 0, width);\n * var h = -height + map(spectrum[i], 0, 255, height, 0);\n * rect(x, height, width / spectrum.length, h )\n * }\n *\n * var waveform = fft.waveform();\n * noFill();\n * beginShape();\n * stroke(255,0,0); // waveform is red\n * strokeWeight(1);\n * for (var i = 0; i< waveform.length; i++){\n * var x = map(i, 0, waveform.length, 0, width);\n * var y = map( waveform[i], -1, 1, 0, height);\n * vertex(x,y);\n * }\n * endShape();\n *\n * text('click to play/pause', 4, 10);\n * }\n *\n * // fade sound if mouse is over canvas\n * function togglePlay() {\n * if (sound.isPlaying()) {\n * sound.pause();\n * } else {\n * sound.loop();\n * }\n * }\n *
\n */\n p5.FFT = function(smoothing, bins) {\n this.input = this.analyser = p5sound.audiocontext.createAnalyser();\n\n Object.defineProperties(this, {\n bins: {\n get: function() {\n return this.analyser.fftSize / 2;\n },\n set: function(b) {\n this.analyser.fftSize = b * 2;\n },\n configurable: true,\n enumerable: true\n },\n smoothing: {\n get: function() {\n return this.analyser.smoothingTimeConstant;\n },\n set: function(s) {\n this.analyser.smoothingTimeConstant = s;\n },\n configurable: true,\n enumerable: true\n }\n });\n\n // set default smoothing and bins\n this.smooth(smoothing);\n this.bins = bins || 1024;\n\n // default connections to p5sound fftMeter\n p5sound.fftMeter.connect(this.analyser);\n\n this.freqDomain = new Uint8Array(this.analyser.frequencyBinCount);\n this.timeDomain = new Uint8Array(this.analyser.frequencyBinCount);\n\n // predefined frequency ranges, these will be tweakable\n this.bass = [20, 140];\n this.lowMid = [140, 400];\n this.mid = [400, 2600];\n this.highMid = [2600, 5200];\n this.treble = [5200, 14000];\n\n // add this p5.SoundFile to the soundArray\n p5sound.soundArray.push(this);\n };\n\n /**\n * Set the input source for the FFT analysis. If no source is\n * provided, FFT will analyze all sound in the sketch.\n *\n * @method setInput\n * @for p5.FFT\n * @param {Object} [source] p5.sound object (or web audio API source node)\n */\n p5.FFT.prototype.setInput = function(source) {\n if (!source) {\n p5sound.fftMeter.connect(this.analyser);\n } else {\n if (source.output) {\n source.output.connect(this.analyser);\n } else if (source.connect) {\n source.connect(this.analyser);\n }\n p5sound.fftMeter.disconnect();\n }\n };\n\n /**\n * Returns an array of amplitude values (between -1.0 and +1.0) that represent\n * a snapshot of amplitude readings in a single buffer. Length will be\n * equal to bins (defaults to 1024). Can be used to draw the waveform\n * of a sound.\n *\n * @method waveform\n * @for p5.FFT\n * @param {Number} [bins] Must be a power of two between\n * 16 and 1024. Defaults to 1024.\n * @param {String} [precision] If any value is provided, will return results\n * in a Float32 Array which is more precise\n * than a regular array.\n * @return {Array} Array Array of amplitude values (-1 to 1)\n * over time. Array length = bins.\n *\n */\n p5.FFT.prototype.waveform = function() {\n var bins, mode, normalArray;\n\n for (var i = 0; i < arguments.length; i++) {\n if (typeof arguments[i] === 'number') {\n bins = arguments[i];\n this.analyser.fftSize = bins * 2;\n }\n if (typeof arguments[i] === 'string') {\n mode = arguments[i];\n }\n }\n\n // getFloatFrequencyData doesnt work in Safari as of 5/2015\n if (mode && !p5.prototype._isSafari()) {\n timeToFloat(this, this.timeDomain);\n this.analyser.getFloatTimeDomainData(this.timeDomain);\n return this.timeDomain;\n } else {\n timeToInt(this, this.timeDomain);\n this.analyser.getByteTimeDomainData(this.timeDomain);\n var normalArray = new Array();\n for (var j = 0; j < this.timeDomain.length; j++) {\n var scaled = p5.prototype.map(this.timeDomain[j], 0, 255, -1, 1);\n normalArray.push(scaled);\n }\n return normalArray;\n }\n };\n\n /**\n * Returns an array of amplitude values (between 0 and 255)\n * across the frequency spectrum. Length is equal to FFT bins\n * (1024 by default). The array indices correspond to frequencies\n * (i.e. pitches), from the lowest to the highest that humans can\n * hear. Each value represents amplitude at that slice of the\n * frequency spectrum. Must be called prior to using\n * getEnergy().\n *\n * @method analyze\n * @for p5.FFT\n * @param {Number} [bins] Must be a power of two between\n * 16 and 1024. Defaults to 1024.\n * @param {Number} [scale] If \"dB,\" returns decibel\n * float measurements between\n * -140 and 0 (max).\n * Otherwise returns integers from 0-255.\n * @return {Array} spectrum Array of energy (amplitude/volume)\n * values across the frequency spectrum.\n * Lowest energy (silence) = 0, highest\n * possible is 255.\n * @example\n *
\n * var osc;\n * var fft;\n *\n * function setup(){\n * createCanvas(100,100);\n * osc = new p5.Oscillator();\n * osc.amp(0);\n * osc.start();\n * fft = new p5.FFT();\n * }\n *\n * function draw(){\n * background(0);\n *\n * var freq = map(mouseX, 0, 800, 20, 15000);\n * freq = constrain(freq, 1, 20000);\n * osc.freq(freq);\n *\n * var spectrum = fft.analyze();\n * noStroke();\n * fill(0,255,0); // spectrum is green\n * for (var i = 0; i< spectrum.length; i++){\n * var x = map(i, 0, spectrum.length, 0, width);\n * var h = -height + map(spectrum[i], 0, 255, height, 0);\n * rect(x, height, width / spectrum.length, h );\n * }\n *\n * stroke(255);\n * text('Freq: ' + round(freq)+'Hz', 10, 10);\n *\n * isMouseOverCanvas();\n * }\n *\n * // only play sound when mouse is over canvas\n * function isMouseOverCanvas() {\n * var mX = mouseX, mY = mouseY;\n * if (mX > 0 && mX < width && mY < height && mY > 0) {\n * osc.amp(0.5, 0.2);\n * } else {\n * osc.amp(0, 0.2);\n * }\n * }\n *
\n *\n *\n */\n p5.FFT.prototype.analyze = function() {\n var mode;\n\n for (var i = 0; i < arguments.length; i++) {\n if (typeof arguments[i] === 'number') {\n this.bins = arguments[i];\n this.analyser.fftSize = this.bins * 2;\n }\n if (typeof arguments[i] === 'string') {\n mode = arguments[i];\n }\n }\n\n if (mode && mode.toLowerCase() === 'db') {\n freqToFloat(this);\n this.analyser.getFloatFrequencyData(this.freqDomain);\n return this.freqDomain;\n } else {\n freqToInt(this, this.freqDomain);\n this.analyser.getByteFrequencyData(this.freqDomain);\n var normalArray = Array.apply([], this.freqDomain);\n \n return normalArray;\n }\n };\n\n /**\n * Returns the amount of energy (volume) at a specific\n * \n * frequency, or the average amount of energy between two\n * frequencies. Accepts Number(s) corresponding\n * to frequency (in Hz), or a String corresponding to predefined\n * frequency ranges (\"bass\", \"lowMid\", \"mid\", \"highMid\", \"treble\").\n * Returns a range between 0 (no energy/volume at that frequency) and\n * 255 (maximum energy).\n * NOTE: analyze() must be called prior to getEnergy(). Analyze()\n * tells the FFT to analyze frequency data, and getEnergy() uses\n * the results determine the value at a specific frequency or\n * range of frequencies.\n *\n * @method getEnergy\n * @for p5.FFT\n * @param {Number|String} frequency1 Will return a value representing\n * energy at this frequency. Alternately,\n * the strings \"bass\", \"lowMid\" \"mid\",\n * \"highMid\", and \"treble\" will return\n * predefined frequency ranges.\n * @param {Number} [frequency2] If a second frequency is given,\n * will return average amount of\n * energy that exists between the\n * two frequencies.\n * @return {Number} Energy Energy (volume/amplitude) from\n * 0 and 255.\n *\n */\n p5.FFT.prototype.getEnergy = function(frequency1, frequency2) {\n var nyquist = p5sound.audiocontext.sampleRate / 2;\n\n if (frequency1 === 'bass') {\n frequency1 = this.bass[0];\n frequency2 = this.bass[1];\n } else if (frequency1 === 'lowMid') {\n frequency1 = this.lowMid[0];\n frequency2 = this.lowMid[1];\n } else if (frequency1 === 'mid') {\n frequency1 = this.mid[0];\n frequency2 = this.mid[1];\n } else if (frequency1 === 'highMid') {\n frequency1 = this.highMid[0];\n frequency2 = this.highMid[1];\n } else if (frequency1 === 'treble') {\n frequency1 = this.treble[0];\n frequency2 = this.treble[1];\n }\n\n if (typeof frequency1 !== 'number') {\n throw 'invalid input for getEnergy()';\n } else if (!frequency2) {\n // if only one parameter:\n var index = Math.round(frequency1 / nyquist * this.freqDomain.length);\n return this.freqDomain[index];\n } else if (frequency1 && frequency2) {\n // if two parameters:\n // if second is higher than first\n if (frequency1 > frequency2) {\n var swap = frequency2;\n frequency2 = frequency1;\n frequency1 = swap;\n }\n var lowIndex = Math.round(frequency1 / nyquist * this.freqDomain.length);\n var highIndex = Math.round(frequency2 / nyquist * this.freqDomain.length);\n\n var total = 0;\n var numFrequencies = 0;\n // add up all of the values for the frequencies\n for (var i = lowIndex; i <= highIndex; i++) {\n total += this.freqDomain[i];\n numFrequencies += 1;\n }\n // divide by total number of frequencies\n var toReturn = total / numFrequencies;\n return toReturn;\n } else {\n throw 'invalid input for getEnergy()';\n }\n };\n\n // compatability with v.012, changed to getEnergy in v.0121. Will be deprecated...\n p5.FFT.prototype.getFreq = function(freq1, freq2) {\n console.log('getFreq() is deprecated. Please use getEnergy() instead.');\n var x = this.getEnergy(freq1, freq2);\n return x;\n };\n\n /**\n * Returns the\n * \n * spectral centroid of the input signal.\n * NOTE: analyze() must be called prior to getCentroid(). Analyze()\n * tells the FFT to analyze frequency data, and getCentroid() uses\n * the results determine the spectral centroid.\n *\n * @method getCentroid\n * @for p5.FFT\n * @return {Number} Spectral Centroid Frequency Frequency of the spectral centroid in Hz.\n *\n *\n * @example\n *
\n *\n *\n *function setup(){\n * cnv = createCanvas(100,100);\n * sound = new p5.AudioIn();\n * sound.start();\n * fft = new p5.FFT();\n * sound.connect(fft);\n *}\n *\n *\n *function draw(){\n *\n * var centroidplot = 0.0;\n * var spectralCentroid = 0;\n *\n *\n * background(0);\n * stroke(0,255,0);\n * var spectrum = fft.analyze();\n * fill(0,255,0); // spectrum is green\n *\n * //draw the spectrum\n * for (var i = 0; i< spectrum.length; i++){\n * var x = map(log(i), 0, log(spectrum.length), 0, width);\n * var h = map(spectrum[i], 0, 255, 0, height);\n * var rectangle_width = (log(i+1)-log(i))*(width/log(spectrum.length));\n * rect(x, height, rectangle_width, -h )\n * }\n\n * var nyquist = 22050;\n *\n * // get the centroid\n * spectralCentroid = fft.getCentroid();\n *\n * // the mean_freq_index calculation is for the display.\n * var mean_freq_index = spectralCentroid/(nyquist/spectrum.length);\n *\n * centroidplot = map(log(mean_freq_index), 0, log(spectrum.length), 0, width);\n *\n *\n * stroke(255,0,0); // the line showing where the centroid is will be red\n *\n * rect(centroidplot, 0, width / spectrum.length, height)\n * noStroke();\n * fill(255,255,255); // text is white\n * text(\"centroid: \", 10, 20);\n * text(round(spectralCentroid)+\" Hz\", 10, 40);\n *}\n *
\n */\n p5.FFT.prototype.getCentroid = function() {\n var nyquist = p5sound.audiocontext.sampleRate / 2;\n var cumulative_sum = 0;\n var centroid_normalization = 0;\n\n for (var i = 0; i < this.freqDomain.length; i++) {\n cumulative_sum += i * this.freqDomain[i];\n centroid_normalization += this.freqDomain[i];\n }\n\n var mean_freq_index = 0;\n\n if (centroid_normalization !== 0) {\n mean_freq_index = cumulative_sum / centroid_normalization;\n }\n\n var spec_centroid_freq =\n mean_freq_index * (nyquist / this.freqDomain.length);\n return spec_centroid_freq;\n };\n\n /**\n * Smooth FFT analysis by averaging with the last analysis frame.\n *\n * @method smooth\n * @param {Number} smoothing 0.0 < smoothing < 1.0.\n * Defaults to 0.8.\n */\n p5.FFT.prototype.smooth = function(s) {\n if (typeof s !== 'undefined') {\n this.smoothing = s;\n }\n return this.smoothing;\n };\n\n p5.FFT.prototype.dispose = function() {\n // remove reference from soundArray\n var index = p5sound.soundArray.indexOf(this);\n p5sound.soundArray.splice(index, 1);\n\n if (this.analyser) {\n this.analyser.disconnect();\n delete this.analyser;\n }\n };\n\n /**\n * Returns an array of average amplitude values for a given number\n * of frequency bands split equally. N defaults to 16.\n * NOTE: analyze() must be called prior to linAverages(). Analyze()\n * tells the FFT to analyze frequency data, and linAverages() uses\n * the results to group them into a smaller set of averages.\n *\n * @method linAverages\n * @for p5.FFT\n * @param {Number} N Number of returned frequency groups\n * @return {Array} linearAverages Array of average amplitude values for each group\n */\n p5.FFT.prototype.linAverages = function(N) {\n var N = N || 16; // This prevents undefined, null or 0 values of N\n\n var spectrum = this.freqDomain;\n var spectrumLength = spectrum.length;\n var spectrumStep = Math.floor(spectrumLength / N);\n\n var linearAverages = new Array(N);\n // Keep a second index for the current average group and place the values accordingly\n // with only one loop in the spectrum data\n var groupIndex = 0;\n\n for (var specIndex = 0; specIndex < spectrumLength; specIndex++) {\n linearAverages[groupIndex] =\n linearAverages[groupIndex] !== undefined\n ? (linearAverages[groupIndex] + spectrum[specIndex]) / 2\n : spectrum[specIndex];\n\n // Increase the group index when the last element of the group is processed\n if (specIndex % spectrumStep === spectrumStep - 1) {\n groupIndex++;\n }\n }\n\n return linearAverages;\n };\n\n /**\n * Returns an array of average amplitude values of the spectrum, for a given\n * set of \n * Octave Bands\n * NOTE: analyze() must be called prior to logAverages(). Analyze()\n * tells the FFT to analyze frequency data, and logAverages() uses\n * the results to group them into a smaller set of averages.\n *\n * @method logAverages\n * @for p5.FFT\n * @param {Array} octaveBands Array of Octave Bands objects for grouping\n * @return {Array} logAverages Array of average amplitude values for each group\n */\n p5.FFT.prototype.logAverages = function(octaveBands) {\n var nyquist = p5sound.audiocontext.sampleRate / 2;\n var spectrum = this.freqDomain;\n var spectrumLength = spectrum.length;\n\n var logAverages = new Array(octaveBands.length);\n // Keep a second index for the current average group and place the values accordingly\n // With only one loop in the spectrum data\n var octaveIndex = 0;\n\n for (var specIndex = 0; specIndex < spectrumLength; specIndex++) {\n var specIndexFrequency = Math.round(\n specIndex * nyquist / this.freqDomain.length\n );\n\n // Increase the group index if the current frequency exceeds the limits of the band\n if (specIndexFrequency > octaveBands[octaveIndex].hi) {\n octaveIndex++;\n }\n\n logAverages[octaveIndex] =\n logAverages[octaveIndex] !== undefined\n ? (logAverages[octaveIndex] + spectrum[specIndex]) / 2\n : spectrum[specIndex];\n }\n\n return logAverages;\n };\n\n /**\n * Calculates and Returns the 1/N\n * Octave Bands\n * N defaults to 3 and minimum central frequency to 15.625Hz.\n * (1/3 Octave Bands ~= 31 Frequency Bands)\n * Setting fCtr0 to a central value of a higher octave will ignore the lower bands\n * and produce less frequency groups.\n *\n * @method getOctaveBands\n * @for p5.FFT\n * @param {Number} N Specifies the 1/N type of generated octave bands\n * @param {Number} fCtr0 Minimum central frequency for the lowest band\n * @return {Array} octaveBands Array of octave band objects with their bounds\n */\n p5.FFT.prototype.getOctaveBands = function(N, fCtr0) {\n var N = N || 3; // Default to 1/3 Octave Bands\n var fCtr0 = fCtr0 || 15.625; // Minimum central frequency, defaults to 15.625Hz\n\n var octaveBands = [];\n var lastFrequencyBand = {\n lo: fCtr0 / Math.pow(2, 1 / (2 * N)),\n ctr: fCtr0,\n hi: fCtr0 * Math.pow(2, 1 / (2 * N))\n };\n octaveBands.push(lastFrequencyBand);\n\n var nyquist = p5sound.audiocontext.sampleRate / 2;\n while (lastFrequencyBand.hi < nyquist) {\n var newFrequencyBand = {};\n newFrequencyBand.lo = lastFrequencyBand.hi;\n newFrequencyBand.ctr = lastFrequencyBand.ctr * Math.pow(2, 1 / N);\n newFrequencyBand.hi = newFrequencyBand.ctr * Math.pow(2, 1 / (2 * N));\n\n octaveBands.push(newFrequencyBand);\n lastFrequencyBand = newFrequencyBand;\n }\n\n return octaveBands;\n };\n\n // helper methods to convert type from float (dB) to int (0-255)\n var freqToFloat = function(fft) {\n if (fft.freqDomain instanceof Float32Array === false) {\n fft.freqDomain = new Float32Array(fft.analyser.frequencyBinCount);\n }\n };\n var freqToInt = function(fft) {\n if (fft.freqDomain instanceof Uint8Array === false) {\n fft.freqDomain = new Uint8Array(fft.analyser.frequencyBinCount);\n }\n };\n var timeToFloat = function(fft) {\n if (fft.timeDomain instanceof Float32Array === false) {\n fft.timeDomain = new Float32Array(fft.analyser.frequencyBinCount);\n }\n };\n var timeToInt = function(fft) {\n if (fft.timeDomain instanceof Uint8Array === false) {\n fft.timeDomain = new Uint8Array(fft.analyser.frequencyBinCount);\n }\n };\n});\n","'use strict';\n\ndefine(function (require) {\n\n // Signal is built with the Tone.js signal by Yotam Mann\n // https://github.com/TONEnoTONE/Tone.js/\n var Signal = require('Tone/signal/Signal');\n var Add = require('Tone/signal/Add');\n var Mult = require('Tone/signal/Multiply');\n var Scale = require('Tone/signal/Scale');\n\n /**\n *
p5.Signal is a constant audio-rate signal used by p5.Oscillator\n * and p5.Envelope for modulation math.
\n *\n *
This is necessary because Web Audio is processed on a seprate clock.\n * For example, the p5 draw loop runs about 60 times per second. But\n * the audio clock must process samples 44100 times per second. If we\n * want to add a value to each of those samples, we can't do it in the\n * draw loop, but we can do it by adding a constant-rate audio signal.This class mostly functions behind the scenes in p5.sound, and returns\n * a Tone.Signal from the Tone.js library by Yotam Mann.\n * If you want to work directly with audio signals for modular\n * synthesis, check out\n * tone.js.
\n *\n * @class p5.Signal\n * @constructor\n * @return {Tone.Signal} A Signal object from the Tone.js library\n * @example\n *
\n * function setup() {\n * carrier = new p5.Oscillator('sine');\n * carrier.amp(1); // set amplitude\n * carrier.freq(220); // set frequency\n * carrier.start(); // start oscillating\n *\n * modulator = new p5.Oscillator('sawtooth');\n * modulator.disconnect();\n * modulator.amp(1);\n * modulator.freq(4);\n * modulator.start();\n *\n * // Modulator's default amplitude range is -1 to 1.\n * // Multiply it by -200, so the range is -200 to 200\n * // then add 220 so the range is 20 to 420\n * carrier.freq( modulator.mult(-200).add(220) );\n * }\n *
\n */\n p5.Signal = function(value) {\n var s = new Signal(value);\n // p5sound.soundArray.push(s);\n return s; // TODO: is this really a constructor?\n };\n\n /**\n * Fade to value, for smooth transitions\n *\n * @method fade\n * @for p5.Signal\n * @param {Number} value Value to set this signal\n * @param {Number} [secondsFromNow] Length of fade, in seconds from now\n */\n Signal.prototype.fade = Signal.prototype.linearRampToValueAtTime;\n Mult.prototype.fade = Signal.prototype.fade;\n Add.prototype.fade = Signal.prototype.fade;\n Scale.prototype.fade = Signal.prototype.fade;\n\n\n /**\n * Connect a p5.sound object or Web Audio node to this\n * p5.Signal so that its amplitude values can be scaled.\n *\n * @method setInput\n * @for p5.Signal\n * @param {Object} input\n */\n Signal.prototype.setInput = function(_input) {\n _input.connect(this);\n };\n Mult.prototype.setInput = Signal.prototype.setInput;\n Add.prototype.setInput = Signal.prototype.setInput;\n Scale.prototype.setInput = Signal.prototype.setInput;\n\n\n // signals can add / mult / scale themselves\n\n /**\n * Add a constant value to this audio signal,\n * and return the resulting audio signal. Does\n * not change the value of the original signal,\n * instead it returns a new p5.SignalAdd.\n *\n * @method add\n * @for p5.Signal\n * @param {Number} number\n * @return {p5.Signal} object\n */\n Signal.prototype.add = function(num) {\n var add = new Add(num);\n // add.setInput(this);\n this.connect(add);\n return add;\n };\n Mult.prototype.add = Signal.prototype.add;\n Add.prototype.add = Signal.prototype.add;\n Scale.prototype.add = Signal.prototype.add;\n\n /**\n * Multiply this signal by a constant value,\n * and return the resulting audio signal. Does\n * not change the value of the original signal,\n * instead it returns a new p5.SignalMult.\n *\n * @method mult\n * @for p5.Signal\n * @param {Number} number to multiply\n * @return {p5.Signal} object\n */\n Signal.prototype.mult = function(num) {\n var mult = new Mult(num);\n // mult.setInput(this);\n this.connect(mult);\n return mult;\n };\n Mult.prototype.mult = Signal.prototype.mult;\n Add.prototype.mult = Signal.prototype.mult;\n Scale.prototype.mult = Signal.prototype.mult;\n\n /**\n * Scale this signal value to a given range,\n * and return the result as an audio signal. Does\n * not change the value of the original signal,\n * instead it returns a new p5.SignalScale.\n *\n * @method scale\n * @for p5.Signal\n * @param {Number} number to multiply\n * @param {Number} inMin input range minumum\n * @param {Number} inMax input range maximum\n * @param {Number} outMin input range minumum\n * @param {Number} outMax input range maximum\n * @return {p5.Signal} object\n */\n Signal.prototype.scale = function(inMin, inMax, outMin, outMax) {\n var mapOutMin, mapOutMax;\n if (arguments.length === 4) {\n mapOutMin = p5.prototype.map(outMin, inMin, inMax, 0, 1) - 0.5;\n mapOutMax = p5.prototype.map(outMax, inMin, inMax, 0, 1) - 0.5;\n }\n else {\n mapOutMin = arguments[0];\n mapOutMax = arguments[1];\n }\n var scale = new Scale(mapOutMin, mapOutMax);\n this.connect(scale);\n return scale;\n };\n Mult.prototype.scale = Signal.prototype.scale;\n Add.prototype.scale = Signal.prototype.scale;\n Scale.prototype.scale = Signal.prototype.scale;\n\n});\n\n\n","define([\"Tone/core/Tone\", \"Tone/type/TimeBase\"], function (Tone) {\n\n\t/**\n\t * @class Tone.Frequency is a primitive type for encoding Frequency values. \n\t * Eventually all time values are evaluated to hertz\n\t * using the `eval` method. \n\t * @constructor\n\t * @extends {Tone.TimeBase}\n\t * @param {String|Number} val The time value.\n\t * @param {String=} units The units of the value.\n\t * @example\n\t * Tone.Frequency(\"C3\") // 261\n\t * Tone.Frequency(38, \"midi\") //\n\t * Tone.Frequency(\"C3\").transpose(4);\n\t */\n\tTone.Frequency = function(val, units){\n\t\tif (this instanceof Tone.Frequency){\n\t\t\t\n\t\t\tTone.TimeBase.call(this, val, units);\n\n\t\t} else {\n\t\t\treturn new Tone.Frequency(val, units);\n\t\t}\n\t};\n\n\tTone.extend(Tone.Frequency, Tone.TimeBase);\n\n\t///////////////////////////////////////////////////////////////////////////\n\t//\tAUGMENT BASE EXPRESSIONS\n\t///////////////////////////////////////////////////////////////////////////\n\n\t//clone the expressions so that \n\t//we can add more without modifying the original\n\tTone.Frequency.prototype._primaryExpressions = Object.create(Tone.TimeBase.prototype._primaryExpressions);\n\n\t/*\n\t * midi type primary expression\n\t * @type {Object}\n\t * @private\n\t */\n\tTone.Frequency.prototype._primaryExpressions.midi = {\n\t\tregexp : /^(\\d+(?:\\.\\d+)?midi)/,\n\t\tmethod : function(value){\n\t\t\treturn this.midiToFrequency(value);\n\t\t}\t\n\t};\n\n\t/*\n\t * note type primary expression\n\t * @type {Object}\n\t * @private\n\t */\n\tTone.Frequency.prototype._primaryExpressions.note = {\n\t\tregexp : /^([a-g]{1}(?:b|#|x|bb)?)(-?[0-9]+)/i,\n\t\tmethod : function(pitch, octave){\n\t\t\tvar index = noteToScaleIndex[pitch.toLowerCase()];\n\t\t\tvar noteNumber = index + (parseInt(octave) + 1) * 12;\n\t\t\treturn this.midiToFrequency(noteNumber);\n\t\t}\t\n\t};\n\n\t/*\n\t * BeatsBarsSixteenths type primary expression\n\t * @type {Object}\n\t * @private\n\t */\n\tTone.Frequency.prototype._primaryExpressions.tr = {\n\t\t\tregexp : /^(\\d+(?:\\.\\d+)?):(\\d+(?:\\.\\d+)?):?(\\d+(?:\\.\\d+)?)?/,\n\t\t\tmethod : function(m, q, s){\n\t\t\tvar total = 1;\n\t\t\tif (m && m !== \"0\"){\n\t\t\t\ttotal *= this._beatsToUnits(this._timeSignature() * parseFloat(m));\n\t\t\t}\n\t\t\tif (q && q !== \"0\"){\n\t\t\t\ttotal *= this._beatsToUnits(parseFloat(q));\n\t\t\t}\n\t\t\tif (s && s !== \"0\"){\n\t\t\t\ttotal *= this._beatsToUnits(parseFloat(s) / 4);\n\t\t\t}\n\t\t\treturn total;\n\t\t}\n\t};\n\n\t///////////////////////////////////////////////////////////////////////////\n\t//\tEXPRESSIONS\n\t///////////////////////////////////////////////////////////////////////////\n\n\t/**\n\t * Transposes the frequency by the given number of semitones.\n\t * @param {Interval} interval\n\t * @return {Tone.Frequency} this\n\t * @example\n\t * Tone.Frequency(\"A4\").transpose(3); //\"C5\"\n\t */\n\tTone.Frequency.prototype.transpose = function(interval){\n\t\tthis._expr = function(expr, interval){\n\t\t\tvar val = expr();\n\t\t\treturn val * this.intervalToFrequencyRatio(interval);\n\t\t}.bind(this, this._expr, interval);\n\t\treturn this;\n\t};\n\n\t/**\n\t * Takes an array of semitone intervals and returns\n\t * an array of frequencies transposed by those intervals.\n\t * @param {Array} intervals\n\t * @return {Tone.Frequency} this\n\t * @example\n\t * Tone.Frequency(\"A4\").harmonize([0, 3, 7]); //[\"A4\", \"C5\", \"E5\"]\n\t */\n\tTone.Frequency.prototype.harmonize = function(intervals){\n\t\tthis._expr = function(expr, intervals){\n\t\t\tvar val = expr();\n\t\t\tvar ret = [];\n\t\t\tfor (var i = 0; i < intervals.length; i++){\n\t\t\t\tret[i] = val * this.intervalToFrequencyRatio(intervals[i]);\n\t\t\t}\n\t\t\treturn ret;\n\t\t}.bind(this, this._expr, intervals);\n\t\treturn this;\n\t};\n\n\t///////////////////////////////////////////////////////////////////////////\n\t//\tUNIT CONVERSIONS\n\t///////////////////////////////////////////////////////////////////////////\n\n\t/**\n\t * Return the value of the frequency as a MIDI note\n\t * @return {MIDI}\n\t * @example\n\t * Tone.Frequency(\"C4\").toMidi(); //60\n\t */\n\tTone.Frequency.prototype.toMidi = function(){\n\t\treturn this.frequencyToMidi(this.valueOf());\n\t};\n\n\t/**\n\t * Return the value of the frequency in Scientific Pitch Notation\n\t * @return {Note}\n\t * @example\n\t * Tone.Frequency(69, \"midi\").toNote(); //\"A4\"\n\t */\n\tTone.Frequency.prototype.toNote = function(){\n\t\tvar freq = this.valueOf();\n\t\tvar log = Math.log(freq / Tone.Frequency.A4) / Math.LN2;\n\t\tvar noteNumber = Math.round(12 * log) + 57;\n\t\tvar octave = Math.floor(noteNumber/12);\n\t\tif(octave < 0){\n\t\t\tnoteNumber += -12 * octave;\n\t\t}\n\t\tvar noteName = scaleIndexToNote[noteNumber % 12];\n\t\treturn noteName + octave.toString();\n\t};\n\n\t/**\n\t * Return the duration of one cycle in seconds.\n\t * @return {Seconds}\n\t */\n\tTone.Frequency.prototype.toSeconds = function(){\n\t\treturn 1 / this.valueOf();\n\t};\n\n\t/**\n\t * Return the value in Hertz\n\t * @return {Frequency}\n\t */\n\tTone.Frequency.prototype.toFrequency = function(){\n\t\treturn this.valueOf();\n\t};\n\n\t/**\n\t * Return the duration of one cycle in ticks\n\t * @return {Ticks}\n\t */\n\tTone.Frequency.prototype.toTicks = function(){\n\t\tvar quarterTime = this._beatsToUnits(1);\n\t\tvar quarters = this.valueOf() / quarterTime;\n\t\treturn Math.floor(quarters * Tone.Transport.PPQ);\n\t};\n\n\t///////////////////////////////////////////////////////////////////////////\n\t//\tUNIT CONVERSIONS HELPERS\n\t///////////////////////////////////////////////////////////////////////////\n\n\t/**\n\t * Returns the value of a frequency in the current units\n\t * @param {Frequency} freq\n\t * @return {Number}\n\t * @private\n\t */\n\tTone.Frequency.prototype._frequencyToUnits = function(freq){\n\t\treturn freq;\n\t};\n\n\t/**\n\t * Returns the value of a tick in the current time units\n\t * @param {Ticks} ticks\n\t * @return {Number}\n\t * @private\n\t */\n\tTone.Frequency.prototype._ticksToUnits = function(ticks){\n\t\treturn 1 / ((ticks * 60) / (Tone.Transport.bpm.value * Tone.Transport.PPQ));\n\t};\n\n\t/**\n\t * Return the value of the beats in the current units\n\t * @param {Number} beats\n\t * @return {Number}\n\t * @private\n\t */\n\tTone.Frequency.prototype._beatsToUnits = function(beats){\n\t\treturn 1 / Tone.TimeBase.prototype._beatsToUnits.call(this, beats);\n\t};\n\n\t/**\n\t * Returns the value of a second in the current units\n\t * @param {Seconds} seconds\n\t * @return {Number}\n\t * @private\n\t */\n\tTone.Frequency.prototype._secondsToUnits = function(seconds){\n\t\treturn 1 / seconds;\n\t};\n\n\t/**\n\t * The default units if none are given.\n\t * @private\n\t */\n\tTone.Frequency.prototype._defaultUnits = \"hz\";\n\n\t///////////////////////////////////////////////////////////////////////////\n\t//\tFREQUENCY CONVERSIONS\n\t///////////////////////////////////////////////////////////////////////////\n\n\t/**\n\t * Note to scale index\n\t * @type {Object}\n\t */\n\tvar noteToScaleIndex = {\n\t\t\"cbb\" : -2, \"cb\" : -1, \"c\" : 0, \"c#\" : 1, \"cx\" : 2, \n\t\t\"dbb\" : 0, \"db\" : 1, \"d\" : 2, \"d#\" : 3, \"dx\" : 4,\n\t\t\"ebb\" : 2, \"eb\" : 3, \"e\" : 4, \"e#\" : 5, \"ex\" : 6, \n\t\t\"fbb\" : 3, \"fb\" : 4, \"f\" : 5, \"f#\" : 6, \"fx\" : 7,\n\t\t\"gbb\" : 5, \"gb\" : 6, \"g\" : 7, \"g#\" : 8, \"gx\" : 9,\n\t\t\"abb\" : 7, \"ab\" : 8, \"a\" : 9, \"a#\" : 10, \"ax\" : 11,\n\t\t\"bbb\" : 9, \"bb\" : 10, \"b\" : 11, \"b#\" : 12, \"bx\" : 13,\n\t};\n\n\t/**\n\t * scale index to note (sharps)\n\t * @type {Array}\n\t */\n\tvar scaleIndexToNote = [\"C\", \"C#\", \"D\", \"D#\", \"E\", \"F\", \"F#\", \"G\", \"G#\", \"A\", \"A#\", \"B\"];\n\n\t/**\n\t * The [concert pitch](https://en.wikipedia.org/wiki/Concert_pitch)\n\t * A4's values in Hertz. \n\t * @type {Frequency}\n\t * @static\n\t */\n\tTone.Frequency.A4 = 440;\n\n\t/**\n\t * Convert a MIDI note to frequency value. \n\t * @param {MIDI} midi The midi number to convert.\n\t * @return {Frequency} the corresponding frequency value\n\t * @example\n\t * tone.midiToFrequency(69); // returns 440\n\t */\n\tTone.Frequency.prototype.midiToFrequency = function(midi){\n\t\treturn Tone.Frequency.A4 * Math.pow(2, (midi - 69) / 12);\n\t};\n\n\t/**\n\t * Convert a frequency value to a MIDI note.\n\t * @param {Frequency} frequency The value to frequency value to convert.\n\t * @returns {MIDI}\n\t * @example\n\t * tone.midiToFrequency(440); // returns 69\n\t */\n\tTone.Frequency.prototype.frequencyToMidi = function(frequency){\n\t\treturn 69 + 12 * Math.log(frequency / Tone.Frequency.A4) / Math.LN2;\n\t};\n\n\treturn Tone.Frequency;\n});","define([\"Tone/core/Tone\", \"Tone/type/Time\"], function (Tone) {\n\n\t/**\n\t * @class Tone.TransportTime is a the time along the Transport's\n\t * timeline. It is similar to Tone.Time, but instead of evaluating\n\t * against the AudioContext's clock, it is evaluated against\n\t * the Transport's position. See [TransportTime wiki](https://github.com/Tonejs/Tone.js/wiki/TransportTime).\n\t * @constructor\n\t * @param {Time} val The time value as a number or string\n\t * @param {String=} units Unit values\n\t * @extends {Tone.Time}\n\t */\n\tTone.TransportTime = function(val, units){\n\t\tif (this instanceof Tone.TransportTime){\n\t\t\t\n\t\t\tTone.Time.call(this, val, units);\n\n\t\t} else {\n\t\t\treturn new Tone.TransportTime(val, units);\n\t\t}\n\t};\n\n\tTone.extend(Tone.TransportTime, Tone.Time);\n\n\t//clone the expressions so that \n\t//we can add more without modifying the original\n\tTone.TransportTime.prototype._unaryExpressions = Object.create(Tone.Time.prototype._unaryExpressions);\n\n\t/**\n\t * Adds an additional unary expression\n\t * which quantizes values to the next subdivision\n\t * @type {Object}\n\t * @private\n\t */\n\tTone.TransportTime.prototype._unaryExpressions.quantize = {\n\t\tregexp : /^@/,\n\t\tmethod : function(rh){\n\t\t\tvar subdivision = this._secondsToTicks(rh());\n\t\t\tvar multiple = Math.ceil(Tone.Transport.ticks / subdivision);\n\t\t\treturn this._ticksToUnits(multiple * subdivision);\n\t\t}\n\t};\n\n\t/**\n\t * Convert seconds into ticks\n\t * @param {Seconds} seconds\n\t * @return {Ticks}\n\t * @private\n\t */\n\tTone.TransportTime.prototype._secondsToTicks = function(seconds){\n\t\tvar quarterTime = this._beatsToUnits(1);\n\t\tvar quarters = seconds / quarterTime;\n\t\treturn Math.round(quarters * Tone.Transport.PPQ);\n\t};\n\n\t/**\n\t * Evaluate the time expression. Returns values in ticks\n\t * @return {Ticks}\n\t */\n\tTone.TransportTime.prototype.valueOf = function(){\n\t\tvar val = this._secondsToTicks(this._expr());\n\t\treturn val + (this._plusNow ? Tone.Transport.ticks : 0);\n\t};\n\n\t/**\n\t * Return the time in ticks.\n\t * @return {Ticks}\n\t */\n\tTone.TransportTime.prototype.toTicks = function(){\n\t\treturn this.valueOf();\n\t};\n\n\t/**\n\t * Return the time in seconds.\n\t * @return {Seconds}\n\t */\n\tTone.TransportTime.prototype.toSeconds = function(){\n\t\tvar val = this._expr();\n\t\treturn val + (this._plusNow ? Tone.Transport.seconds : 0);\n\t};\n\n\t/**\n\t * Return the time as a frequency value\n\t * @return {Frequency} \n\t */\n\tTone.TransportTime.prototype.toFrequency = function(){\n\t\treturn 1/this.toSeconds();\n\t};\n\n\treturn Tone.TransportTime;\n});","'use strict';\n\ndefine(function (require) {\n\n var p5sound = require('master');\n var Add = require('Tone/signal/Add');\n var Mult = require('Tone/signal/Multiply');\n var Scale = require('Tone/signal/Scale');\n var TimelineSignal = require('Tone/signal/TimelineSignal');\n\n /**\n *
Envelopes are pre-defined amplitude distribution over time.\n * Typically, envelopes are used to control the output volume\n * of an object, a series of fades referred to as Attack, Decay,\n * Sustain and Release (\n * ADSR\n * ). Envelopes can also control other Web Audio Parameters—for example, a p5.Envelope can\n * control an Oscillator's frequency like this: osc.freq(env).
\n *
Use setRange to change the attack/release level.\n * Use setADSR to change attackTime, decayTime, sustainPercent and releaseTime.
\n *
Use the play method to play the entire envelope,\n * the ramp method for a pingable trigger,\n * or triggerAttack/\n * triggerRelease to trigger noteOn/noteOff.
\n * var attackLevel = 1.0;\n * var releaseLevel = 0;\n *\n * var attackTime = 0.001;\n * var decayTime = 0.2;\n * var susPercent = 0.2;\n * var releaseTime = 0.5;\n *\n * var env, triOsc;\n *\n * function setup() {\n * var cnv = createCanvas(100, 100);\n *\n * textAlign(CENTER);\n * text('click to play', width/2, height/2);\n *\n * env = new p5.Envelope();\n * env.setADSR(attackTime, decayTime, susPercent, releaseTime);\n * env.setRange(attackLevel, releaseLevel);\n *\n * triOsc = new p5.Oscillator('triangle');\n * triOsc.amp(env);\n * triOsc.start();\n * triOsc.freq(220);\n *\n * cnv.mousePressed(playEnv);\n * }\n *\n * function playEnv() {\n * env.play();\n * }\n *
\n */\n p5.Envelope = function(t1, l1, t2, l2, t3, l3) {\n /**\n * Time until envelope reaches attackLevel\n * @property attackTime\n */\n this.aTime = t1 || 0.1;\n /**\n * Level once attack is complete.\n * @property attackLevel\n */\n this.aLevel = l1 || 1;\n /**\n * Time until envelope reaches decayLevel.\n * @property decayTime\n */\n this.dTime = t2 || 0.5;\n /**\n * Level after decay. The envelope will sustain here until it is released.\n * @property decayLevel\n */\n this.dLevel = l2 || 0;\n /**\n * Duration of the release portion of the envelope.\n * @property releaseTime\n */\n this.rTime = t3 || 0;\n /**\n * Level at the end of the release.\n * @property releaseLevel\n */\n this.rLevel = l3 || 0;\n\n this._rampHighPercentage = 0.98;\n\n this._rampLowPercentage = 0.02;\n\n\n this.output = p5sound.audiocontext.createGain();\n\n this.control = new TimelineSignal();\n\n this._init(); // this makes sure the envelope starts at zero\n\n this.control.connect(this.output); // connect to the output\n\n this.connection = null; // store connection\n\n //array of math operation signal chaining\n this.mathOps = [this.control];\n\n //whether envelope should be linear or exponential curve\n this.isExponential = false;\n\n // oscillator or buffer source to clear on env complete\n // to save resources if/when it is retriggered\n this.sourceToClear = null;\n\n // set to true if attack is set, then false on release\n this.wasTriggered = false;\n\n\n // add to the soundArray so we can dispose of the env later\n p5sound.soundArray.push(this);\n };\n\n // this init function just smooths the starting value to zero and gives a start point for the timeline\n // - it was necessary to remove glitches at the beginning.\n p5.Envelope.prototype._init = function () {\n var now = p5sound.audiocontext.currentTime;\n var t = now;\n this.control.setTargetAtTime(0.00001, t, .001);\n //also, compute the correct time constants\n this._setRampAD(this.aTime, this.dTime);\n };\n\n /**\n * Reset the envelope with a series of time/value pairs.\n *\n * @method set\n * @for p5.Envelope\n * @param {Number} attackTime Time (in seconds) before level\n * reaches attackLevel\n * @param {Number} attackLevel Typically an amplitude between\n * 0.0 and 1.0\n * @param {Number} decayTime Time\n * @param {Number} decayLevel Amplitude (In a standard ADSR envelope,\n * decayLevel = sustainLevel)\n * @param {Number} releaseTime Release Time (in seconds)\n * @param {Number} releaseLevel Amplitude\n * @example\n *
\n * var t1 = 0.1; // attack time in seconds\n * var l1 = 0.7; // attack level 0.0 to 1.0\n * var t2 = 0.3; // decay time in seconds\n * var l2 = 0.1; // decay level 0.0 to 1.0\n * var t3 = 0.2; // sustain time in seconds\n * var l3 = 0.5; // sustain level 0.0 to 1.0\n * // release level defaults to zero\n *\n * var env;\n * var triOsc;\n *\n * function setup() {\n * background(0);\n * noStroke();\n * fill(255);\n * textAlign(CENTER);\n * text('click to play', width/2, height/2);\n *\n * env = new p5.Envelope(t1, l1, t2, l2, t3, l3);\n * triOsc = new p5.Oscillator('triangle');\n * triOsc.amp(env); // give the env control of the triOsc's amp\n * triOsc.start();\n * }\n *\n * // mouseClick triggers envelope if over canvas\n * function mouseClicked() {\n * // is mouse over canvas?\n * if (mouseX > 0 && mouseX < width && mouseY > 0 && mouseY < height) {\n * env.play(triOsc);\n * }\n * }\n *
\n *\n */\n p5.Envelope.prototype.set = function(t1, l1, t2, l2, t3, l3) {\n this.aTime = t1;\n this.aLevel = l1;\n this.dTime = t2 || 0;\n this.dLevel = l2 || 0;\n this.rTime = t3 || 0;\n this.rLevel = l3 || 0;\n\n // set time constants for ramp\n this._setRampAD(t1, t2);\n };\n\n /**\n * Set values like a traditional\n * \n * ADSR envelope\n * .\n *\n * @method setADSR\n * @for p5.Envelope\n * @param {Number} attackTime Time (in seconds before envelope\n * reaches Attack Level\n * @param {Number} [decayTime] Time (in seconds) before envelope\n * reaches Decay/Sustain Level\n * @param {Number} [susRatio] Ratio between attackLevel and releaseLevel, on a scale from 0 to 1,\n * where 1.0 = attackLevel, 0.0 = releaseLevel.\n * The susRatio determines the decayLevel and the level at which the\n * sustain portion of the envelope will sustain.\n * For example, if attackLevel is 0.4, releaseLevel is 0,\n * and susAmt is 0.5, the decayLevel would be 0.2. If attackLevel is\n * increased to 1.0 (using setRange),\n * then decayLevel would increase proportionally, to become 0.5.\n * @param {Number} [releaseTime] Time in seconds from now (defaults to 0)\n * @example\n *
\n * var attackLevel = 1.0;\n * var releaseLevel = 0;\n *\n * var attackTime = 0.001;\n * var decayTime = 0.2;\n * var susPercent = 0.2;\n * var releaseTime = 0.5;\n *\n * var env, triOsc;\n *\n * function setup() {\n * var cnv = createCanvas(100, 100);\n *\n * textAlign(CENTER);\n * text('click to play', width/2, height/2);\n *\n * env = new p5.Envelope();\n * env.setADSR(attackTime, decayTime, susPercent, releaseTime);\n * env.setRange(attackLevel, releaseLevel);\n *\n * triOsc = new p5.Oscillator('triangle');\n * triOsc.amp(env);\n * triOsc.start();\n * triOsc.freq(220);\n *\n * cnv.mousePressed(playEnv);\n * }\n *\n * function playEnv() {\n * env.play();\n * }\n *
\n */\n p5.Envelope.prototype.setADSR = function(aTime, dTime, sPercent, rTime) {\n this.aTime = aTime;\n this.dTime = dTime || 0;\n\n // lerp\n this.sPercent = sPercent || 0;\n this.dLevel = typeof sPercent !== 'undefined' ? sPercent * (this.aLevel - this.rLevel) + this.rLevel : 0;\n\n this.rTime = rTime || 0;\n\n // also set time constants for ramp\n this._setRampAD(aTime, dTime);\n };\n\n /**\n * Set max (attackLevel) and min (releaseLevel) of envelope.\n *\n * @method setRange\n * @for p5.Envelope\n * @param {Number} aLevel attack level (defaults to 1)\n * @param {Number} rLevel release level (defaults to 0)\n * @example\n *
\n * var attackLevel = 1.0;\n * var releaseLevel = 0;\n *\n * var attackTime = 0.001;\n * var decayTime = 0.2;\n * var susPercent = 0.2;\n * var releaseTime = 0.5;\n *\n * var env, triOsc;\n *\n * function setup() {\n * var cnv = createCanvas(100, 100);\n *\n * textAlign(CENTER);\n * text('click to play', width/2, height/2);\n *\n * env = new p5.Envelope();\n * env.setADSR(attackTime, decayTime, susPercent, releaseTime);\n * env.setRange(attackLevel, releaseLevel);\n *\n * triOsc = new p5.Oscillator('triangle');\n * triOsc.amp(env);\n * triOsc.start();\n * triOsc.freq(220);\n *\n * cnv.mousePressed(playEnv);\n * }\n *\n * function playEnv() {\n * env.play();\n * }\n *
\n */\n p5.Envelope.prototype.setRange = function(aLevel, rLevel) {\n this.aLevel = aLevel || 1;\n this.rLevel = rLevel || 0;\n\n // not sure if this belongs here:\n\n // {Number} [dLevel] decay/sustain level (optional)\n // if (typeof(dLevel) !== 'undefined') {\n // this.dLevel = dLevel\n // } else if (this.sPercent) {\n // this.dLevel = this.sPercent ? this.sPercent * (this.aLevel - this.rLevel) + this.rLevel : 0;\n // }\n };\n\n // private (undocumented) method called when ADSR is set to set time constants for ramp\n //\n // Set the \n // time constants for simple exponential ramps.\n // The larger the time constant value, the slower the\n // transition will be.\n //\n // method _setRampAD\n // param {Number} attackTimeConstant attack time constant\n // param {Number} decayTimeConstant decay time constant\n //\n p5.Envelope.prototype._setRampAD = function(t1, t2) {\n this._rampAttackTime = this.checkExpInput(t1);\n this._rampDecayTime = this.checkExpInput(t2);\n\n var TCDenominator = 1.0;\n /// Aatish Bhatia's calculation for time constant for rise(to adjust 1/1-e calculation to any percentage)\n TCDenominator = Math.log(1.0 / this.checkExpInput(1.0 - this._rampHighPercentage));\n this._rampAttackTC = t1 / this.checkExpInput(TCDenominator);\n TCDenominator = Math.log(1.0 / this._rampLowPercentage);\n this._rampDecayTC = t2 / this.checkExpInput(TCDenominator);\n };\n\n // private method\n p5.Envelope.prototype.setRampPercentages = function(p1, p2) {\n //set the percentages that the simple exponential ramps go to\n this._rampHighPercentage = this.checkExpInput(p1);\n this._rampLowPercentage = this.checkExpInput(p2);\n var TCDenominator = 1.0;\n //now re-compute the time constants based on those percentages\n /// Aatish Bhatia's calculation for time constant for rise(to adjust 1/1-e calculation to any percentage)\n TCDenominator = Math.log(1.0 / this.checkExpInput(1.0 - this._rampHighPercentage));\n this._rampAttackTC = this._rampAttackTime / this.checkExpInput(TCDenominator);\n TCDenominator = Math.log(1.0 / this._rampLowPercentage);\n this._rampDecayTC = this._rampDecayTime / this.checkExpInput(TCDenominator);\n };\n\n\n /**\n * Assign a parameter to be controlled by this envelope.\n * If a p5.Sound object is given, then the p5.Envelope will control its\n * output gain. If multiple inputs are provided, the env will\n * control all of them.\n *\n * @method setInput\n * @for p5.Envelope\n * @param {Object} [...inputs] A p5.sound object or\n * Web Audio Param.\n */\n p5.Envelope.prototype.setInput = function() {\n for (var i = 0; i\n * Web Audio Audio Param.\n *\n * @method play\n * @for p5.Envelope\n * @param {Object} unit A p5.sound object or\n * Web Audio Param.\n * @param {Number} [startTime] time from now (in seconds) at which to play\n * @param {Number} [sustainTime] time to sustain before releasing the envelope\n * @example\n *
\n * var attackLevel = 1.0;\n * var releaseLevel = 0;\n *\n * var attackTime = 0.001;\n * var decayTime = 0.2;\n * var susPercent = 0.2;\n * var releaseTime = 0.5;\n *\n * var env, triOsc;\n *\n * function setup() {\n * var cnv = createCanvas(100, 100);\n *\n * textAlign(CENTER);\n * text('click to play', width/2, height/2);\n *\n * env = new p5.Envelope();\n * env.setADSR(attackTime, decayTime, susPercent, releaseTime);\n * env.setRange(attackLevel, releaseLevel);\n *\n * triOsc = new p5.Oscillator('triangle');\n * triOsc.amp(env);\n * triOsc.start();\n * triOsc.freq(220);\n *\n * cnv.mousePressed(playEnv);\n * }\n *\n * function playEnv() {\n * // trigger env on triOsc, 0 seconds from now\n * // After decay, sustain for 0.2 seconds before release\n * env.play(triOsc, 0, 0.2);\n * }\n *
\n */\n p5.Envelope.prototype.play = function(unit, secondsFromNow, susTime) {\n var tFromNow = secondsFromNow || 0;\n var susTime = susTime || 0;\n\n if (unit) {\n if (this.connection !== unit) {\n this.connect(unit);\n }\n }\n\n this.triggerAttack(unit, tFromNow);\n\n this.triggerRelease(unit, tFromNow + this.aTime + this.dTime + susTime);\n\n };\n\n /**\n * Trigger the Attack, and Decay portion of the Envelope.\n * Similar to holding down a key on a piano, but it will\n * hold the sustain level until you let go. Input can be\n * any p5.sound object, or a \n * Web Audio Param.\n *\n * @method triggerAttack\n * @for p5.Envelope\n * @param {Object} unit p5.sound Object or Web Audio Param\n * @param {Number} secondsFromNow time from now (in seconds)\n * @example\n *
\n *\n * var attackLevel = 1.0;\n * var releaseLevel = 0;\n *\n * var attackTime = 0.001;\n * var decayTime = 0.3;\n * var susPercent = 0.4;\n * var releaseTime = 0.5;\n *\n * var env, triOsc;\n *\n * function setup() {\n * var cnv = createCanvas(100, 100);\n * background(200);\n * textAlign(CENTER);\n * text('click to play', width/2, height/2);\n *\n * env = new p5.Envelope();\n * env.setADSR(attackTime, decayTime, susPercent, releaseTime);\n * env.setRange(attackLevel, releaseLevel);\n *\n * triOsc = new p5.Oscillator('triangle');\n * triOsc.amp(env);\n * triOsc.start();\n * triOsc.freq(220);\n *\n * cnv.mousePressed(envAttack);\n * }\n *\n * function envAttack() {\n * console.log('trigger attack');\n * env.triggerAttack();\n *\n * background(0,255,0);\n * text('attack!', width/2, height/2);\n * }\n *\n * function mouseReleased() {\n * env.triggerRelease();\n *\n * background(200);\n * text('click to play', width/2, height/2);\n * }\n *
\n */\n p5.Envelope.prototype.triggerAttack = function(unit, secondsFromNow) {\n var now = p5sound.audiocontext.currentTime;\n var tFromNow = secondsFromNow || 0;\n var t = now + tFromNow;\n this.lastAttack = t;\n this.wasTriggered = true;\n\n if (unit) {\n if (this.connection !== unit) {\n this.connect(unit);\n }\n }\n\n // get and set value (with linear ramp) to anchor automation\n var valToSet = this.control.getValueAtTime(t);\n\n if (this.isExponential === true)\n {\n this.control.exponentialRampToValueAtTime(this.checkExpInput(valToSet), t);\n }\n else\n {\n this.control.linearRampToValueAtTime(valToSet, t);\n }\n\n // after each ramp completes, cancel scheduled values\n // (so they can be overridden in case env has been re-triggered)\n // then, set current value (with linearRamp to avoid click)\n // then, schedule the next automation...\n\n // attack\n t += this.aTime;\n if (this.isExponential === true)\n {\n this.control.exponentialRampToValueAtTime(this.checkExpInput(this.aLevel), t);\n valToSet = this.checkExpInput(this.control.getValueAtTime(t));\n this.control.cancelScheduledValues(t);\n this.control.exponentialRampToValueAtTime(valToSet, t);\n }\n else\n {\n this.control.linearRampToValueAtTime(this.aLevel, t);\n valToSet = this.control.getValueAtTime(t);\n this.control.cancelScheduledValues(t);\n this.control.linearRampToValueAtTime(valToSet, t);\n\n }\n\n // decay to decay level (if using ADSR, then decay level == sustain level)\n t += this.dTime;\n if (this.isExponential === true)\n {\n this.control.exponentialRampToValueAtTime(this.checkExpInput(this.dLevel), t);\n valToSet = this.checkExpInput(this.control.getValueAtTime(t));\n this.control.cancelScheduledValues(t);\n this.control.exponentialRampToValueAtTime(valToSet, t);\n }\n else\n {\n this.control.linearRampToValueAtTime(this.dLevel, t);\n valToSet = this.control.getValueAtTime(t);\n this.control.cancelScheduledValues(t);\n this.control.linearRampToValueAtTime(valToSet, t);\n }\n };\n\n /**\n * Trigger the Release of the Envelope. This is similar to releasing\n * the key on a piano and letting the sound fade according to the\n * release level and release time.\n *\n * @method triggerRelease\n * @for p5.Envelope\n * @param {Object} unit p5.sound Object or Web Audio Param\n * @param {Number} secondsFromNow time to trigger the release\n * @example\n *
\n *\n * var attackLevel = 1.0;\n * var releaseLevel = 0;\n *\n * var attackTime = 0.001;\n * var decayTime = 0.3;\n * var susPercent = 0.4;\n * var releaseTime = 0.5;\n *\n * var env, triOsc;\n *\n * function setup() {\n * var cnv = createCanvas(100, 100);\n * background(200);\n * textAlign(CENTER);\n * text('click to play', width/2, height/2);\n *\n * env = new p5.Envelope();\n * env.setADSR(attackTime, decayTime, susPercent, releaseTime);\n * env.setRange(attackLevel, releaseLevel);\n *\n * triOsc = new p5.Oscillator('triangle');\n * triOsc.amp(env);\n * triOsc.start();\n * triOsc.freq(220);\n *\n * cnv.mousePressed(envAttack);\n * }\n *\n * function envAttack() {\n * console.log('trigger attack');\n * env.triggerAttack();\n *\n * background(0,255,0);\n * text('attack!', width/2, height/2);\n * }\n *\n * function mouseReleased() {\n * env.triggerRelease();\n *\n * background(200);\n * text('click to play', width/2, height/2);\n * }\n *
\n */\n p5.Envelope.prototype.triggerRelease = function(unit, secondsFromNow) {\n\n // only trigger a release if an attack was triggered\n if (!this.wasTriggered) {\n // this currently causes a bit of trouble:\n // if a later release has been scheduled (via the play function)\n // a new earlier release won't interrupt it, because\n // this.wasTriggered has already been set to false.\n // If we want new earlier releases to override, then we need to\n // keep track of the last release time, and if the new release time is\n // earlier, then use it.\n return;\n }\n\n var now = p5sound.audiocontext.currentTime;\n var tFromNow = secondsFromNow || 0;\n var t = now + tFromNow;\n\n if (unit) {\n if (this.connection !== unit) {\n this.connect(unit);\n }\n }\n\n // get and set value (with linear or exponential ramp) to anchor automation\n var valToSet = this.control.getValueAtTime(t);\n if (this.isExponential === true)\n {\n this.control.exponentialRampToValueAtTime(this.checkExpInput(valToSet), t);\n }\n else\n {\n this.control.linearRampToValueAtTime(valToSet, t);\n }\n\n // release\n t += this.rTime;\n\n if (this.isExponential === true)\n {\n this.control.exponentialRampToValueAtTime(this.checkExpInput(this.rLevel), t);\n valToSet = this.checkExpInput(this.control.getValueAtTime(t));\n this.control.cancelScheduledValues(t);\n this.control.exponentialRampToValueAtTime(valToSet, t);\n }\n else\n {\n this.control.linearRampToValueAtTime(this.rLevel, t);\n valToSet = this.control.getValueAtTime(t);\n this.control.cancelScheduledValues(t);\n this.control.linearRampToValueAtTime(valToSet, t);\n }\n\n this.wasTriggered = false;\n };\n\n /**\n * Exponentially ramp to a value using the first two\n * values from setADSR(attackTime, decayTime)\n * as \n * time constants for simple exponential ramps.\n * If the value is higher than current value, it uses attackTime,\n * while a decrease uses decayTime.\n *\n * @method ramp\n * @for p5.Envelope\n * @param {Object} unit p5.sound Object or Web Audio Param\n * @param {Number} secondsFromNow When to trigger the ramp\n * @param {Number} v Target value\n * @param {Number} [v2] Second target value (optional)\n * @example\n *
\n * var env, osc, amp, cnv;\n *\n * var attackTime = 0.001;\n * var decayTime = 0.2;\n * var attackLevel = 1;\n * var decayLevel = 0;\n *\n * function setup() {\n * cnv = createCanvas(100, 100);\n * fill(0,255,0);\n * noStroke();\n *\n * env = new p5.Envelope();\n * env.setADSR(attackTime, decayTime);\n *\n * osc = new p5.Oscillator();\n * osc.amp(env);\n * osc.start();\n *\n * amp = new p5.Amplitude();\n *\n * cnv.mousePressed(triggerRamp);\n * }\n *\n * function triggerRamp() {\n * env.ramp(osc, 0, attackLevel, decayLevel);\n * }\n *\n * function draw() {\n * background(20,20,20);\n * text('click me', 10, 20);\n * var h = map(amp.getLevel(), 0, 0.4, 0, height);;\n *\n * rect(0, height, width, -h);\n * }\n *
\n */\n p5.Envelope.prototype.ramp = function(unit, secondsFromNow, v1, v2) {\n\n var now = p5sound.audiocontext.currentTime;\n var tFromNow = secondsFromNow || 0;\n var t = now + tFromNow;\n var destination1 = this.checkExpInput(v1);\n var destination2 = typeof v2 !== 'undefined' ? this.checkExpInput(v2) : undefined;\n\n // connect env to unit if not already connected\n if (unit) {\n if (this.connection !== unit) {\n this.connect(unit);\n }\n }\n\n //get current value\n var currentVal = this.checkExpInput(this.control.getValueAtTime(t));\n // this.control.cancelScheduledValues(t);\n\n //if it's going up\n if (destination1 > currentVal) {\n this.control.setTargetAtTime(destination1, t, this._rampAttackTC);\n t += this._rampAttackTime;\n }\n\n //if it's going down\n else if (destination1 < currentVal) {\n this.control.setTargetAtTime(destination1, t, this._rampDecayTC);\n t += this._rampDecayTime;\n }\n\n // Now the second part of envelope begins\n if (destination2 === undefined) return;\n\n //if it's going up\n if (destination2 > destination1) {\n this.control.setTargetAtTime(destination2, t, this._rampAttackTC);\n }\n\n //if it's going down\n else if (destination2 < destination1) {\n this.control.setTargetAtTime(destination2, t, this._rampDecayTC);\n }\n };\n\n\n p5.Envelope.prototype.connect = function(unit) {\n this.connection = unit;\n\n // assume we're talking about output gain\n // unless given a different audio param\n if (unit instanceof p5.Oscillator ||\n unit instanceof p5.SoundFile ||\n unit instanceof p5.AudioIn ||\n unit instanceof p5.Reverb ||\n unit instanceof p5.Noise ||\n unit instanceof p5.Filter ||\n unit instanceof p5.Delay\n ) {\n unit = unit.output.gain;\n }\n if (unit instanceof AudioParam) {\n //set the initial value\n unit.setValueAtTime(0, p5sound.audiocontext.currentTime);\n }\n if (unit instanceof p5.Signal) {\n unit.setValue(0);\n }\n this.output.connect(unit);\n };\n\n p5.Envelope.prototype.disconnect = function() {\n if (this.output) {\n this.output.disconnect();\n }\n };\n\n\n // Signal Math\n\n /**\n * Add a value to the p5.Oscillator's output amplitude,\n * and return the oscillator. Calling this method\n * again will override the initial add() with new values.\n *\n * @method add\n * @for p5.Envelope\n * @param {Number} number Constant number to add\n * @return {p5.Envelope} Envelope Returns this envelope\n * with scaled output\n */\n p5.Envelope.prototype.add = function(num) {\n var add = new Add(num);\n var thisChain = this.mathOps.length;\n var nextChain = this.output;\n return p5.prototype._mathChain(this, add, thisChain, nextChain, Add);\n };\n\n /**\n * Multiply the p5.Envelope's output amplitude\n * by a fixed value. Calling this method\n * again will override the initial mult() with new values.\n *\n * @method mult\n * @for p5.Envelope\n * @param {Number} number Constant number to multiply\n * @return {p5.Envelope} Envelope Returns this envelope\n * with scaled output\n */\n p5.Envelope.prototype.mult = function(num) {\n var mult = new Mult(num);\n var thisChain = this.mathOps.length;\n var nextChain = this.output;\n return p5.prototype._mathChain(this, mult, thisChain, nextChain, Mult);\n };\n\n /**\n * Scale this envelope's amplitude values to a given\n * range, and return the envelope. Calling this method\n * again will override the initial scale() with new values.\n *\n * @method scale\n * @for p5.Envelope\n * @param {Number} inMin input range minumum\n * @param {Number} inMax input range maximum\n * @param {Number} outMin input range minumum\n * @param {Number} outMax input range maximum\n * @return {p5.Envelope} Envelope Returns this envelope\n * with scaled output\n */\n p5.Envelope.prototype.scale = function(inMin, inMax, outMin, outMax) {\n var scale = new Scale(inMin, inMax, outMin, outMax);\n var thisChain = this.mathOps.length;\n var nextChain = this.output;\n return p5.prototype._mathChain(this, scale, thisChain, nextChain, Scale);\n };\n\n\n // get rid of the oscillator\n p5.Envelope.prototype.dispose = function() {\n // remove reference from soundArray\n var index = p5sound.soundArray.indexOf(this);\n p5sound.soundArray.splice(index, 1);\n\n this.disconnect();\n if (this.control) {\n this.control.dispose();\n this.control = null;\n }\n for (var i = 1; i < this.mathOps.length; i++) {\n this.mathOps[i].dispose();\n }\n };\n\n // Different name for backwards compatibility, replicates p5.Envelope class\n p5.Env = function(t1, l1, t2, l2, t3, l3) {\n console.warn('WARNING: p5.Env is now deprecated and may be removed in future versions. ' +\n 'Please use the new p5.Envelope instead.');\n p5.Envelope.call(this, t1, l1, t2, l2, t3, l3);\n };\n p5.Env.prototype = Object.create(p5.Envelope.prototype);\n\n});\n","'use strict';\n\ndefine(function (require) {\n\n var p5sound = require('master');\n require('oscillator');\n\n /**\n * Creates a Pulse object, an oscillator that implements\n * Pulse Width Modulation.\n * The pulse is created with two oscillators.\n * Accepts a parameter for frequency, and to set the\n * width between the pulses. See \n * p5.Oscillator for a full list of methods.\n *\n * @class p5.Pulse\n * @extends p5.Oscillator\n * @constructor\n * @param {Number} [freq] Frequency in oscillations per second (Hz)\n * @param {Number} [w] Width between the pulses (0 to 1.0,\n * defaults to 0)\n * @example\n *
Note: This uses the getUserMedia/\n * Stream API, which is not supported by certain browsers. Access in Chrome browser\n * is limited to localhost and https, but access over http may be limited.
\n *\n * @class p5.AudioIn\n * @constructor\n * @param {Function} [errorCallback] A function to call if there is an error\n * accessing the AudioIn. For example,\n * Safari and iOS devices do not\n * currently allow microphone access.\n * @example\n *
\n * var mic;\n * function setup(){\n * mic = new p5.AudioIn()\n * mic.start();\n * }\n * function draw(){\n * background(0);\n * micLevel = mic.getLevel();\n * ellipse(width/2, constrain(height-micLevel*height*5, 0, height), 10, 10);\n * }\n *
\n */\n p5.AudioIn = function(errorCallback) {\n // set up audio input\n /**\n * @property {GainNode} input\n */\n this.input = p5sound.audiocontext.createGain();\n /**\n * @property {GainNode} output\n */\n this.output = p5sound.audiocontext.createGain();\n\n /**\n * @property {MediaStream|null} stream\n */\n this.stream = null;\n /**\n * @property {MediaStreamAudioSourceNode|null} mediaStream\n */\n this.mediaStream = null;\n /**\n * @property {Number|null} currentSource\n */\n this.currentSource = null;\n\n /**\n * Client must allow browser to access their microphone / audioin source.\n * Default: false. Will become true when the client enables acces.\n *\n * @property {Boolean} enabled\n */\n this.enabled = false;\n\n /**\n * Input amplitude, connect to it by default but not to master out\n *\n * @property {p5.Amplitude} amplitude\n */\n this.amplitude = new p5.Amplitude();\n this.output.connect(this.amplitude.input);\n\n if (!window.MediaStreamTrack || !window.navigator.mediaDevices || !window.navigator.mediaDevices.getUserMedia) {\n errorCallback ? errorCallback() : window.alert('This browser does not support MediaStreamTrack and mediaDevices');\n }\n\n // add to soundArray so we can dispose on close\n p5sound.soundArray.push(this);\n };\n\n /**\n * Start processing audio input. This enables the use of other\n * AudioIn methods like getLevel(). Note that by default, AudioIn\n * is not connected to p5.sound's output. So you won't hear\n * anything unless you use the connect() method. \n *\n * Certain browsers limit access to the user's microphone. For example,\n * Chrome only allows access from localhost and over https. For this reason,\n * you may want to include an errorCallback—a function that is called in case\n * the browser won't provide mic access.\n *\n * @method start\n * @for p5.AudioIn\n * @param {Function} [successCallback] Name of a function to call on\n * success.\n * @param {Function} [errorCallback] Name of a function to call if\n * there was an error. For example,\n * some browsers do not support\n * getUserMedia.\n */\n p5.AudioIn.prototype.start = function(successCallback, errorCallback) {\n var self = this;\n\n if (this.stream) {\n this.stop();\n }\n\n // set the audio source\n var audioSource = p5sound.inputSources[self.currentSource];\n var constraints = {\n audio: {\n sampleRate: p5sound.audiocontext.sampleRate,\n echoCancellation: false\n }\n };\n\n // if developers determine which source to use\n if (p5sound.inputSources[this.currentSource]) {\n constraints.audio.deviceId = audioSource.deviceId;\n }\n\n window.navigator.mediaDevices.getUserMedia( constraints )\n .then( function(stream) {\n self.stream = stream;\n self.enabled = true;\n // Wrap a MediaStreamSourceNode around the live input\n self.mediaStream = p5sound.audiocontext.createMediaStreamSource(stream);\n self.mediaStream.connect(self.output);\n // only send to the Amplitude reader, so we can see it but not hear it.\n self.amplitude.setInput(self.output);\n if (successCallback) successCallback();\n })\n .catch( function(err) {\n if (errorCallback) errorCallback(err);\n else console.error(err);\n });\n };\n\n /**\n * Turn the AudioIn off. If the AudioIn is stopped, it cannot getLevel().\n * If re-starting, the user may be prompted for permission access.\n *\n * @method stop\n * @for p5.AudioIn\n */\n p5.AudioIn.prototype.stop = function() {\n if (this.stream) {\n this.stream.getTracks().forEach(function(track) {\n track.stop();\n });\n\n this.mediaStream.disconnect();\n\n delete this.mediaStream;\n delete this.stream;\n }\n };\n\n /**\n * Connect to an audio unit. If no parameter is provided, will\n * connect to the master output (i.e. your speakers). \n *\n * @method connect\n * @for p5.AudioIn\n * @param {Object} [unit] An object that accepts audio input,\n * such as an FFT\n */\n p5.AudioIn.prototype.connect = function(unit) {\n if (unit) {\n if (unit.hasOwnProperty('input')) {\n this.output.connect(unit.input);\n }\n else if (unit.hasOwnProperty('analyser')) {\n this.output.connect(unit.analyser);\n }\n else {\n this.output.connect(unit);\n }\n }\n else {\n this.output.connect(p5sound.input);\n }\n };\n\n /**\n * Disconnect the AudioIn from all audio units. For example, if\n * connect() had been called, disconnect() will stop sending\n * signal to your speakers. \n *\n * @method disconnect\n * @for p5.AudioIn\n */\n p5.AudioIn.prototype.disconnect = function() {\n if (this.output) {\n this.output.disconnect();\n // stay connected to amplitude even if not outputting to p5\n this.output.connect(this.amplitude.input);\n }\n };\n\n /**\n * Read the Amplitude (volume level) of an AudioIn. The AudioIn\n * class contains its own instance of the Amplitude class to help\n * make it easy to get a microphone's volume level. Accepts an\n * optional smoothing value (0.0 < 1.0). NOTE: AudioIn must\n * .start() before using .getLevel(). \n *\n * @method getLevel\n * @for p5.AudioIn\n * @param {Number} [smoothing] Smoothing is 0.0 by default.\n * Smooths values based on previous values.\n * @return {Number} Volume level (between 0.0 and 1.0)\n */\n p5.AudioIn.prototype.getLevel = function(smoothing) {\n if (smoothing) {\n this.amplitude.smoothing = smoothing;\n }\n return this.amplitude.getLevel();\n };\n\n /**\n * Set amplitude (volume) of a mic input between 0 and 1.0. \n *\n * @method amp\n * @for p5.AudioIn\n * @param {Number} vol between 0 and 1.0\n * @param {Number} [time] ramp time (optional)\n */\n p5.AudioIn.prototype.amp = function(vol, t) {\n if (t) {\n var rampTime = t || 0;\n var currentVol = this.output.gain.value;\n this.output.gain.cancelScheduledValues(p5sound.audiocontext.currentTime);\n this.output.gain.setValueAtTime(currentVol, p5sound.audiocontext.currentTime);\n this.output.gain.linearRampToValueAtTime(vol, rampTime + p5sound.audiocontext.currentTime);\n } else {\n this.output.gain.cancelScheduledValues(p5sound.audiocontext.currentTime);\n this.output.gain.setValueAtTime(vol, p5sound.audiocontext.currentTime);\n }\n };\n\n /**\n * Returns a list of available input sources. This is a wrapper\n * for and it returns a Promise.\n *\n * @method getSources\n * @for p5.AudioIn\n * @param {Function} [successCallback] This callback function handles the sources when they\n * have been enumerated. The callback function\n * receives the deviceList array as its only argument\n * @param {Function} [errorCallback] This optional callback receives the error\n * message as its argument.\n * @returns {Promise} Returns a Promise that can be used in place of the callbacks, similar\n * to the enumerateDevices() method\n * @example\n *
\n */\n p5.AudioIn.prototype.getSources = function (onSuccess, onError) {\n return new Promise( function(resolve, reject) {\n window.navigator.mediaDevices.enumerateDevices()\n .then( function(devices) {\n p5sound.inputSources = devices.filter(function(device) {\n return device.kind === 'audioinput';\n });\n resolve(p5sound.inputSources);\n if (onSuccess) {\n onSuccess(p5sound.inputSources);\n }\n })\n .catch( function(error) {\n reject(error);\n if (onError) {\n onError(error);\n } else {\n console.error('This browser does not support MediaStreamTrack.getSources()');\n }\n });\n });\n };\n\n /**\n * Set the input source. Accepts a number representing a\n * position in the array returned by getSources().\n * This is only available in browsers that support\n * navigator.mediaDevices.enumerateDevices(). \n *\n * @method setSource\n * @for p5.AudioIn\n * @param {number} num position of input source in the array\n */\n p5.AudioIn.prototype.setSource = function(num) {\n if (p5sound.inputSources.length > 0 && num < p5sound.inputSources.length) {\n // set the current source\n this.currentSource = num;\n console.log('set source to ', p5sound.inputSources[this.currentSource]);\n } else {\n console.log('unable to set input source');\n }\n\n // restart stream if currently active\n if (this.stream && this.stream.active) {\n this.start();\n }\n };\n\n // private method\n p5.AudioIn.prototype.dispose = function() {\n // remove reference from soundArray\n var index = p5sound.soundArray.indexOf(this);\n p5sound.soundArray.splice(index, 1);\n\n this.stop();\n\n if (this.output) {\n this.output.disconnect();\n }\n if (this.amplitude) {\n this.amplitude.disconnect();\n }\n delete this.amplitude;\n delete this.output;\n };\n\n});\n","define([\"Tone/core/Tone\", \"Tone/signal/Signal\", \"Tone/signal/Expr\", \n\t\"Tone/signal/EqualPowerGain\", \"Tone/core/Gain\"], function(Tone){\n\n\t\"use strict\";\n\n\t/**\n\t * @class Tone.Crossfade provides equal power fading between two inputs. \n\t * More on crossfading technique [here](https://en.wikipedia.org/wiki/Fade_(audio_engineering)#Crossfading).\n\t *\n\t * @constructor\n\t * @extends {Tone}\n\t * @param {NormalRange} [initialFade=0.5]\n\t * @example\n\t * var crossFade = new Tone.CrossFade(0.5);\n\t * //connect effect A to crossfade from\n\t * //effect output 0 to crossfade input 0\n\t * effectA.connect(crossFade, 0, 0);\n\t * //connect effect B to crossfade from\n\t * //effect output 0 to crossfade input 1\n\t * effectB.connect(crossFade, 0, 1);\n\t * crossFade.fade.value = 0;\n\t * // ^ only effectA is output\n\t * crossFade.fade.value = 1;\n\t * // ^ only effectB is output\n\t * crossFade.fade.value = 0.5;\n\t * // ^ the two signals are mixed equally. \n\t */\t\t\n\tTone.CrossFade = function(initialFade){\n\n\t\tthis.createInsOuts(2, 1);\n\n\t\t/**\n\t\t * Alias for input[0]. \n\t\t * @type {Tone.Gain}\n\t\t */\n\t\tthis.a = this.input[0] = new Tone.Gain();\n\n\t\t/**\n\t\t * Alias for input[1]. \n\t\t * @type {Tone.Gain}\n\t\t */\n\t\tthis.b = this.input[1] = new Tone.Gain();\n\n\t\t/**\n\t\t * \tThe mix between the two inputs. A fade value of 0\n\t\t * \twill output 100% input[0] and \n\t\t * \ta value of 1 will output 100% input[1]. \n\t\t * @type {NormalRange}\n\t\t * @signal\n\t\t */\n\t\tthis.fade = new Tone.Signal(this.defaultArg(initialFade, 0.5), Tone.Type.NormalRange);\n\n\t\t/**\n\t\t * equal power gain cross fade\n\t\t * @private\n\t\t * @type {Tone.EqualPowerGain}\n\t\t */\n\t\tthis._equalPowerA = new Tone.EqualPowerGain();\n\n\t\t/**\n\t\t * equal power gain cross fade\n\t\t * @private\n\t\t * @type {Tone.EqualPowerGain}\n\t\t */\n\t\tthis._equalPowerB = new Tone.EqualPowerGain();\n\t\t\n\t\t/**\n\t\t * invert the incoming signal\n\t\t * @private\n\t\t * @type {Tone}\n\t\t */\n\t\tthis._invert = new Tone.Expr(\"1 - $0\");\n\n\t\t//connections\n\t\tthis.a.connect(this.output);\n\t\tthis.b.connect(this.output);\n\t\tthis.fade.chain(this._equalPowerB, this.b.gain);\n\t\tthis.fade.chain(this._invert, this._equalPowerA, this.a.gain);\n\t\tthis._readOnly(\"fade\");\n\t};\n\n\tTone.extend(Tone.CrossFade);\n\n\t/**\n\t * clean up\n\t * @returns {Tone.CrossFade} this\n\t */\n\tTone.CrossFade.prototype.dispose = function(){\n\t\tTone.prototype.dispose.call(this);\n\t\tthis._writable(\"fade\");\n\t\tthis._equalPowerA.dispose();\n\t\tthis._equalPowerA = null;\n\t\tthis._equalPowerB.dispose();\n\t\tthis._equalPowerB = null;\n\t\tthis.fade.dispose();\n\t\tthis.fade = null;\n\t\tthis._invert.dispose();\n\t\tthis._invert = null;\n\t\tthis.a.dispose();\n\t\tthis.a = null;\n\t\tthis.b.dispose();\n\t\tthis.b = null;\n\t\treturn this;\n\t};\n\n\treturn Tone.CrossFade;\n});\n","define([\"Tone/core/Tone\", \"Tone/signal/Add\", \"Tone/signal/Subtract\", \"Tone/signal/Multiply\", \n\t\"Tone/signal/GreaterThan\", \"Tone/signal/GreaterThanZero\", \"Tone/signal/Abs\", \"Tone/signal/Negate\", \n\t\"Tone/signal/Modulo\", \"Tone/signal/Pow\", \"Tone/signal/AudioToGain\"], \n\tfunction(Tone){\n\n\t\"use strict\";\n\n\t/**\n\t * @class Evaluate an expression at audio rate.
\n\t * Parsing code modified from https://code.google.com/p/tapdigit/\n\t * Copyright 2011 2012 Ariya Hidayat, New BSD License\n\t *\n\t * @extends {Tone.SignalBase}\n\t * @constructor\n\t * @param {string} expr the expression to generate\n\t * @example\n\t * //adds the signals from input[0] and input[1].\n\t * var expr = new Tone.Expr(\"$0 + $1\");\n\t */\n\tTone.Expr = function(){\n\n\t\tvar expr = this._replacements(Array.prototype.slice.call(arguments));\n\t\tvar inputCount = this._parseInputs(expr);\n\n\t\t/**\n\t\t * hold onto all of the nodes for disposal\n\t\t * @type {Array}\n\t\t * @private\n\t\t */\n\t\tthis._nodes = [];\n\n\t\t/**\n\t\t * The inputs. The length is determined by the expression. \n\t\t * @type {Array}\n\t\t */\n\t\tthis.input = new Array(inputCount);\n\n\t\t//create a gain for each input\n\t\tfor (var i = 0; i < inputCount; i++){\n\t\t\tthis.input[i] = this.context.createGain();\n\t\t}\n\n\t\t//parse the syntax tree\n\t\tvar tree = this._parseTree(expr);\n\t\t//evaluate the results\n\t\tvar result;\n\t\ttry {\n\t\t\tresult = this._eval(tree);\n\t\t} catch (e){\n\t\t\tthis._disposeNodes();\n\t\t\tthrow new Error(\"Tone.Expr: Could evaluate expression: \"+expr);\n\t\t}\n\n\t\t/**\n\t\t * The output node is the result of the expression\n\t\t * @type {Tone}\n\t\t */\n\t\tthis.output = result;\n\t};\n\n\tTone.extend(Tone.Expr, Tone.SignalBase);\n\n\t//some helpers to cut down the amount of code\n\tfunction applyBinary(Constructor, args, self){\n\t\tvar op = new Constructor();\n\t\tself._eval(args[0]).connect(op, 0, 0);\n\t\tself._eval(args[1]).connect(op, 0, 1);\n\t\treturn op;\n\t}\n\tfunction applyUnary(Constructor, args, self){\n\t\tvar op = new Constructor();\n\t\tself._eval(args[0]).connect(op, 0, 0);\n\t\treturn op;\n\t}\n\tfunction getNumber(arg){\n\t\treturn arg ? parseFloat(arg) : undefined;\n\t}\n\tfunction literalNumber(arg){\n\t\treturn arg && arg.args ? parseFloat(arg.args) : undefined;\n\t}\n\n\t/*\n\t * the Expressions that Tone.Expr can parse.\n\t *\n\t * each expression belongs to a group and contains a regexp \n\t * for selecting the operator as well as that operators method\n\t * \n\t * @type {Object}\n\t * @private\n\t */\n\tTone.Expr._Expressions = {\n\t\t//values\n\t\t\"value\" : {\n\t\t\t\"signal\" : {\n\t\t\t\tregexp : /^\\d+\\.\\d+|^\\d+/,\n\t\t\t\tmethod : function(arg){\n\t\t\t\t\tvar sig = new Tone.Signal(getNumber(arg));\n\t\t\t\t\treturn sig;\n\t\t\t\t}\n\t\t\t},\n\t\t\t\"input\" : {\n\t\t\t\tregexp : /^\\$\\d/,\n\t\t\t\tmethod : function(arg, self){\n\t\t\t\t\treturn self.input[getNumber(arg.substr(1))];\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\t\t//syntactic glue\n\t\t\"glue\" : {\n\t\t\t\"(\" : {\n\t\t\t\tregexp : /^\\(/,\n\t\t\t},\n\t\t\t\")\" : {\n\t\t\t\tregexp : /^\\)/,\n\t\t\t},\n\t\t\t\",\" : {\n\t\t\t\tregexp : /^,/,\n\t\t\t}\n\t\t},\n\t\t//functions\n\t\t\"func\" : {\n\t\t\t\"abs\" : {\n\t\t\t\tregexp : /^abs/,\n\t\t\t\tmethod : applyUnary.bind(this, Tone.Abs)\n\t\t\t},\n\t\t\t\"mod\" : {\n\t\t\t\tregexp : /^mod/,\n\t\t\t\tmethod : function(args, self){\n\t\t\t\t\tvar modulus = literalNumber(args[1]);\n\t\t\t\t\tvar op = new Tone.Modulo(modulus);\n\t\t\t\t\tself._eval(args[0]).connect(op);\n\t\t\t\t\treturn op;\n\t\t\t\t}\n\t\t\t},\n\t\t\t\"pow\" : {\n\t\t\t\tregexp : /^pow/,\n\t\t\t\tmethod : function(args, self){\n\t\t\t\t\tvar exp = literalNumber(args[1]);\n\t\t\t\t\tvar op = new Tone.Pow(exp);\n\t\t\t\t\tself._eval(args[0]).connect(op);\n\t\t\t\t\treturn op;\n\t\t\t\t}\n\t\t\t},\n\t\t\t\"a2g\" : {\n\t\t\t\tregexp : /^a2g/,\n\t\t\t\tmethod : function(args, self){\n\t\t\t\t\tvar op = new Tone.AudioToGain();\n\t\t\t\t\tself._eval(args[0]).connect(op);\n\t\t\t\t\treturn op;\n\t\t\t\t}\n\t\t\t},\n\t\t},\n\t\t//binary expressions\n\t\t\"binary\" : {\n\t\t\t\"+\" : {\n\t\t\t\tregexp : /^\\+/,\n\t\t\t\tprecedence : 1,\n\t\t\t\tmethod : applyBinary.bind(this, Tone.Add)\n\t\t\t},\n\t\t\t\"-\" : {\n\t\t\t\tregexp : /^\\-/,\n\t\t\t\tprecedence : 1,\n\t\t\t\tmethod : function(args, self){\n\t\t\t\t\t//both unary and binary op\n\t\t\t\t\tif (args.length === 1){\n\t\t\t\t\t\treturn applyUnary(Tone.Negate, args, self);\n\t\t\t\t\t} else {\n\t\t\t\t\t\treturn applyBinary(Tone.Subtract, args, self);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t},\n\t\t\t\"*\" : {\n\t\t\t\tregexp : /^\\*/,\n\t\t\t\tprecedence : 0,\n\t\t\t\tmethod : applyBinary.bind(this, Tone.Multiply)\n\t\t\t}\n\t\t},\n\t\t//unary expressions\n\t\t\"unary\" : {\n\t\t\t\"-\" : {\n\t\t\t\tregexp : /^\\-/,\n\t\t\t\tmethod : applyUnary.bind(this, Tone.Negate)\n\t\t\t},\n\t\t\t\"!\" : {\n\t\t\t\tregexp : /^\\!/,\n\t\t\t\tmethod : applyUnary.bind(this, Tone.NOT)\n\t\t\t},\n\t\t},\n\t};\n\t\t\n\t/**\n\t * @param {string} expr the expression string\n\t * @return {number} the input count\n\t * @private\n\t */\n\tTone.Expr.prototype._parseInputs = function(expr){\n\t\tvar inputArray = expr.match(/\\$\\d/g);\n\t\tvar inputMax = 0;\n\t\tif (inputArray !== null){\n\t\t\tfor (var i = 0; i < inputArray.length; i++){\n\t\t\t\tvar inputNum = parseInt(inputArray[i].substr(1)) + 1;\n\t\t\t\tinputMax = Math.max(inputMax, inputNum);\n\t\t\t}\n\t\t}\n\t\treturn inputMax;\n\t};\n\n\t/**\n\t * @param {Array} args \tan array of arguments\n\t * @return {string} the results of the replacements being replaced\n\t * @private\n\t */\n\tTone.Expr.prototype._replacements = function(args){\n\t\tvar expr = args.shift();\n\t\tfor (var i = 0; i < args.length; i++){\n\t\t\texpr = expr.replace(/\\%/i, args[i]);\n\t\t}\n\t\treturn expr;\n\t};\n\n\t/**\n\t * tokenize the expression based on the Expressions object\n\t * @param {string} expr \n\t * @return {Object} returns two methods on the tokenized list, next and peek\n\t * @private\n\t */\n\tTone.Expr.prototype._tokenize = function(expr){\n\t\tvar position = -1;\n\t\tvar tokens = [];\n\n\t\twhile(expr.length > 0){\n\t\t\texpr = expr.trim();\n\t\t\tvar token = getNextToken(expr);\n\t\t\ttokens.push(token);\n\t\t\texpr = expr.substr(token.value.length);\n\t\t}\n\n\t\tfunction getNextToken(expr){\n\t\t\tfor (var type in Tone.Expr._Expressions){\n\t\t\t\tvar group = Tone.Expr._Expressions[type];\n\t\t\t\tfor (var opName in group){\n\t\t\t\t\tvar op = group[opName];\n\t\t\t\t\tvar reg = op.regexp;\n\t\t\t\t\tvar match = expr.match(reg);\n\t\t\t\t\tif (match !== null){\n\t\t\t\t\t\treturn {\n\t\t\t\t\t\t\ttype : type,\n\t\t\t\t\t\t\tvalue : match[0],\n\t\t\t\t\t\t\tmethod : op.method\n\t\t\t\t\t\t};\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\tthrow new SyntaxError(\"Tone.Expr: Unexpected token \"+expr);\n\t\t}\n\n\t\treturn {\n\t\t\tnext : function(){\n\t\t\t\treturn tokens[++position];\n\t\t\t},\n\t\t\tpeek : function(){\n\t\t\t\treturn tokens[position + 1];\n\t\t\t}\n\t\t};\n\t};\n\n\t/**\n\t * recursively parse the string expression into a syntax tree\n\t * \n\t * @param {string} expr \n\t * @return {Object}\n\t * @private\n\t */\n\tTone.Expr.prototype._parseTree = function(expr){\n\t\tvar lexer = this._tokenize(expr);\n\t\tvar isUndef = this.isUndef.bind(this);\n\n\t\tfunction matchSyntax(token, syn) {\n\t\t\treturn !isUndef(token) && \n\t\t\t\ttoken.type === \"glue\" &&\n\t\t\t\ttoken.value === syn;\n\t\t}\n\n\t\tfunction matchGroup(token, groupName, prec) {\n\t\t\tvar ret = false;\n\t\t\tvar group = Tone.Expr._Expressions[groupName];\n\t\t\tif (!isUndef(token)){\n\t\t\t\tfor (var opName in group){\n\t\t\t\t\tvar op = group[opName];\n\t\t\t\t\tif (op.regexp.test(token.value)){\n\t\t\t\t\t\tif (!isUndef(prec)){\n\t\t\t\t\t\t\tif(op.precedence === prec){\t\n\t\t\t\t\t\t\t\treturn true;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\treturn true;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn ret;\n\t\t}\n\n\t\tfunction parseExpression(precedence) {\n\t\t\tif (isUndef(precedence)){\n\t\t\t\tprecedence = 5;\n\t\t\t}\n\t\t\tvar expr;\n\t\t\tif (precedence < 0){\n\t\t\t\texpr = parseUnary();\n\t\t\t} else {\n\t\t\t\texpr = parseExpression(precedence-1);\n\t\t\t}\n\t\t\tvar token = lexer.peek();\n\t\t\twhile (matchGroup(token, \"binary\", precedence)) {\n\t\t\t\ttoken = lexer.next();\n\t\t\t\texpr = {\n\t\t\t\t\toperator: token.value,\n\t\t\t\t\tmethod : token.method,\n\t\t\t\t\targs : [\n\t\t\t\t\t\texpr,\n\t\t\t\t\t\tparseExpression(precedence-1)\n\t\t\t\t\t]\n\t\t\t\t};\n\t\t\t\ttoken = lexer.peek();\n\t\t\t}\n\t\t\treturn expr;\n\t\t}\n\n\t\tfunction parseUnary() {\n\t\t\tvar token, expr;\n\t\t\ttoken = lexer.peek();\n\t\t\tif (matchGroup(token, \"unary\")) {\n\t\t\t\ttoken = lexer.next();\n\t\t\t\texpr = parseUnary();\n\t\t\t\treturn {\n\t\t\t\t\toperator: token.value,\n\t\t\t\t\tmethod : token.method,\n\t\t\t\t\targs : [expr]\n\t\t\t\t};\n\t\t\t}\n\t\t\treturn parsePrimary();\n\t\t}\n\n\t\tfunction parsePrimary() {\n\t\t\tvar token, expr;\n\t\t\ttoken = lexer.peek();\n\t\t\tif (isUndef(token)) {\n\t\t\t\tthrow new SyntaxError(\"Tone.Expr: Unexpected termination of expression\");\n\t\t\t}\n\t\t\tif (token.type === \"func\") {\n\t\t\t\ttoken = lexer.next();\n\t\t\t\treturn parseFunctionCall(token);\n\t\t\t}\n\t\t\tif (token.type === \"value\") {\n\t\t\t\ttoken = lexer.next();\n\t\t\t\treturn {\n\t\t\t\t\tmethod : token.method,\n\t\t\t\t\targs : token.value\n\t\t\t\t};\n\t\t\t}\n\t\t\tif (matchSyntax(token, \"(\")) {\n\t\t\t\tlexer.next();\n\t\t\t\texpr = parseExpression();\n\t\t\t\ttoken = lexer.next();\n\t\t\t\tif (!matchSyntax(token, \")\")) {\n\t\t\t\t\tthrow new SyntaxError(\"Expected )\");\n\t\t\t\t}\n\t\t\t\treturn expr;\n\t\t\t}\n\t\t\tthrow new SyntaxError(\"Tone.Expr: Parse error, cannot process token \" + token.value);\n\t\t}\n\n\t\tfunction parseFunctionCall(func) {\n\t\t\tvar token, args = [];\n\t\t\ttoken = lexer.next();\n\t\t\tif (!matchSyntax(token, \"(\")) {\n\t\t\t\tthrow new SyntaxError(\"Tone.Expr: Expected ( in a function call \\\"\" + func.value + \"\\\"\");\n\t\t\t}\n\t\t\ttoken = lexer.peek();\n\t\t\tif (!matchSyntax(token, \")\")) {\n\t\t\t\targs = parseArgumentList();\n\t\t\t}\n\t\t\ttoken = lexer.next();\n\t\t\tif (!matchSyntax(token, \")\")) {\n\t\t\t\tthrow new SyntaxError(\"Tone.Expr: Expected ) in a function call \\\"\" + func.value + \"\\\"\");\n\t\t\t}\n\t\t\treturn {\n\t\t\t\tmethod : func.method,\n\t\t\t\targs : args,\n\t\t\t\tname : name\n\t\t\t};\n\t\t}\n\n\t\tfunction parseArgumentList() {\n\t\t\tvar token, expr, args = [];\n\t\t\twhile (true) {\n\t\t\t\texpr = parseExpression();\n\t\t\t\tif (isUndef(expr)) {\n\t\t\t\t\t// TODO maybe throw exception?\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\targs.push(expr);\n\t\t\t\ttoken = lexer.peek();\n\t\t\t\tif (!matchSyntax(token, \",\")) {\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tlexer.next();\n\t\t\t}\n\t\t\treturn args;\n\t\t}\n\n\t\treturn parseExpression();\n\t};\n\n\t/**\n\t * recursively evaluate the expression tree\n\t * @param {Object} tree \n\t * @return {AudioNode} the resulting audio node from the expression\n\t * @private\n\t */\n\tTone.Expr.prototype._eval = function(tree){\n\t\tif (!this.isUndef(tree)){\n\t\t\tvar node = tree.method(tree.args, this);\n\t\t\tthis._nodes.push(node);\n\t\t\treturn node;\n\t\t} \n\t};\n\n\t/**\n\t * dispose all the nodes\n\t * @private\n\t */\n\tTone.Expr.prototype._disposeNodes = function(){\n\t\tfor (var i = 0; i < this._nodes.length; i++){\n\t\t\tvar node = this._nodes[i];\n\t\t\tif (this.isFunction(node.dispose)) {\n\t\t\t\tnode.dispose();\n\t\t\t} else if (this.isFunction(node.disconnect)) {\n\t\t\t\tnode.disconnect();\n\t\t\t}\n\t\t\tnode = null;\n\t\t\tthis._nodes[i] = null;\n\t\t}\n\t\tthis._nodes = null;\n\t};\n\n\t/**\n\t * clean up\n\t */\n\tTone.Expr.prototype.dispose = function(){\n\t\tTone.prototype.dispose.call(this);\n\t\tthis._disposeNodes();\n\t};\n\n\treturn Tone.Expr;\n});","define([\"Tone/core/Tone\", \"Tone/signal/GreaterThanZero\", \"Tone/signal/Subtract\", \"Tone/signal/Signal\"], \n\tfunction(Tone){\n\n\t\"use strict\";\n\n\t/**\n\t * @class Output 1 if the signal is greater than the value, otherwise outputs 0.\n\t * can compare two signals or a signal and a number. \n\t * \n\t * @constructor\n\t * @extends {Tone.Signal}\n\t * @param {number} [value=0] the value to compare to the incoming signal\n\t * @example\n\t * var gt = new Tone.GreaterThan(2);\n\t * var sig = new Tone.Signal(4).connect(gt);\n\t * //output of gt is equal 1. \n\t */\n\tTone.GreaterThan = function(value){\n\n\t\tthis.createInsOuts(2, 0);\n\t\t\n\t\t/**\n\t\t * subtract the amount from the incoming signal\n\t\t * @type {Tone.Subtract}\n\t\t * @private\n\t\t */\n\t\tthis._param = this.input[0] = new Tone.Subtract(value);\n\t\tthis.input[1] = this._param.input[1];\n\n\t\t/**\n\t\t * compare that amount to zero\n\t\t * @type {Tone.GreaterThanZero}\n\t\t * @private\n\t\t */\n\t\tthis._gtz = this.output = new Tone.GreaterThanZero();\n\n\t\t//connect\n\t\tthis._param.connect(this._gtz);\n\t};\n\n\tTone.extend(Tone.GreaterThan, Tone.Signal);\n\n\t/**\n\t * dispose method\n\t * @returns {Tone.GreaterThan} this\n\t */\n\tTone.GreaterThan.prototype.dispose = function(){\n\t\tTone.prototype.dispose.call(this);\n\t\tthis._param.dispose();\n\t\tthis._param = null;\n\t\tthis._gtz.dispose();\n\t\tthis._gtz = null;\n\t\treturn this;\n\t};\n\n\treturn Tone.GreaterThan;\n});","define([\"Tone/core/Tone\", \"Tone/signal/WaveShaper\", \"Tone/signal/SignalBase\"], \nfunction(Tone){\n\n\t\"use strict\";\n\n\t/**\n\t * @class Return the absolute value of an incoming signal. \n\t * \n\t * @constructor\n\t * @extends {Tone.SignalBase}\n\t * @example\n\t * var signal = new Tone.Signal(-1);\n\t * var abs = new Tone.Abs();\n\t * signal.connect(abs);\n\t * //the output of abs is 1. \n\t */\n\tTone.Abs = function(){\n\t\t/**\n\t\t * @type {Tone.LessThan}\n\t\t * @private\n\t\t */\n\t\tthis._abs = this.input = this.output = new Tone.WaveShaper(function(val){\n\t\t\tif (val === 0){\n\t\t\t\treturn 0;\n\t\t\t} else {\n\t\t\t\treturn Math.abs(val);\n\t\t\t}\n\t\t}, 127);\n\t};\n\n\tTone.extend(Tone.Abs, Tone.SignalBase);\n\n\t/**\n\t * dispose method\n\t * @returns {Tone.Abs} this\n\t */\n\tTone.Abs.prototype.dispose = function(){\n\t\tTone.prototype.dispose.call(this);\n\t\tthis._abs.dispose();\n\t\tthis._abs = null;\n\t\treturn this;\n\t}; \n\n\treturn Tone.Abs;\n});","define([\"Tone/core/Tone\", \"Tone/signal/WaveShaper\", \"Tone/signal/Multiply\", \"Tone/signal/Subtract\"], \nfunction(Tone){\n\n\t\"use strict\";\n\n\t/**\n\t * @class Signal-rate modulo operator. Only works in AudioRange [-1, 1] and for modulus\n\t * values in the NormalRange. \n\t *\n\t * @constructor\n\t * @extends {Tone.SignalBase}\n\t * @param {NormalRange} modulus The modulus to apply.\n\t * @example\n\t * var mod = new Tone.Modulo(0.2)\n\t * var sig = new Tone.Signal(0.5).connect(mod);\n\t * //mod outputs 0.1\n\t */\n\tTone.Modulo = function(modulus){\n\n\t\tthis.createInsOuts(1, 0);\n\n\t\t/**\n\t\t * A waveshaper gets the integer multiple of \n\t\t * the input signal and the modulus.\n\t\t * @private\n\t\t * @type {Tone.WaveShaper}\n\t\t */\n\t\tthis._shaper = new Tone.WaveShaper(Math.pow(2, 16));\n\n\t\t/**\n\t\t * the integer multiple is multiplied by the modulus\n\t\t * @type {Tone.Multiply}\n\t\t * @private\n\t\t */\n\t\tthis._multiply = new Tone.Multiply();\n\n\t\t/**\n\t\t * and subtracted from the input signal\n\t\t * @type {Tone.Subtract}\n\t\t * @private\n\t\t */\n\t\tthis._subtract = this.output = new Tone.Subtract();\n\n\t\t/**\n\t\t * the modulus signal\n\t\t * @type {Tone.Signal}\n\t\t * @private\n\t\t */\n\t\tthis._modSignal = new Tone.Signal(modulus);\n\n\t\t//connections\n\t\tthis.input.fan(this._shaper, this._subtract);\n\t\tthis._modSignal.connect(this._multiply, 0, 0);\n\t\tthis._shaper.connect(this._multiply, 0, 1);\n\t\tthis._multiply.connect(this._subtract, 0, 1);\n\t\tthis._setWaveShaper(modulus);\n\t};\n\n\tTone.extend(Tone.Modulo, Tone.SignalBase);\n\n\t/**\n\t * @param {number} mod the modulus to apply\n\t * @private\n\t */\n\tTone.Modulo.prototype._setWaveShaper = function(mod){\n\t\tthis._shaper.setMap(function(val){\n\t\t\tvar multiple = Math.floor((val + 0.0001) / mod);\n\t\t\treturn multiple;\n\t\t});\n\t};\n\n\t/**\n\t * The modulus value.\n\t * @memberOf Tone.Modulo#\n\t * @type {NormalRange}\n\t * @name value\n\t */\n\tObject.defineProperty(Tone.Modulo.prototype, \"value\", {\n\t\tget : function(){\n\t\t\treturn this._modSignal.value;\n\t\t},\n\t\tset : function(mod){\n\t\t\tthis._modSignal.value = mod;\n\t\t\tthis._setWaveShaper(mod);\n\t\t}\n\t});\n\n\t/**\n\t * clean up\n\t * @returns {Tone.Modulo} this\n\t */\n\tTone.Modulo.prototype.dispose = function(){\n\t\tTone.prototype.dispose.call(this);\n\t\tthis._shaper.dispose();\n\t\tthis._shaper = null;\n\t\tthis._multiply.dispose();\n\t\tthis._multiply = null;\n\t\tthis._subtract.dispose();\n\t\tthis._subtract = null;\n\t\tthis._modSignal.dispose();\n\t\tthis._modSignal = null;\n\t\treturn this;\n\t};\n\n\treturn Tone.Modulo;\n});","define([\"Tone/core/Tone\", \"Tone/signal/WaveShaper\"], function(Tone){\n\n\t\"use strict\";\n\n\t/**\n\t * @class Pow applies an exponent to the incoming signal. The incoming signal\n\t * must be AudioRange.\n\t *\n\t * @extends {Tone.SignalBase}\n\t * @constructor\n\t * @param {Positive} exp The exponent to apply to the incoming signal, must be at least 2. \n\t * @example\n\t * var pow = new Tone.Pow(2);\n\t * var sig = new Tone.Signal(0.5).connect(pow);\n\t * //output of pow is 0.25. \n\t */\n\tTone.Pow = function(exp){\n\n\t\t/**\n\t\t * the exponent\n\t\t * @private\n\t\t * @type {number}\n\t\t */\n\t\tthis._exp = this.defaultArg(exp, 1);\n\n\t\t/**\n\t\t * @type {WaveShaperNode}\n\t\t * @private\n\t\t */\n\t\tthis._expScaler = this.input = this.output = new Tone.WaveShaper(this._expFunc(this._exp), 8192);\n\t};\n\n\tTone.extend(Tone.Pow, Tone.SignalBase);\n\n\t/**\n\t * The value of the exponent.\n\t * @memberOf Tone.Pow#\n\t * @type {number}\n\t * @name value\n\t */\n\tObject.defineProperty(Tone.Pow.prototype, \"value\", {\n\t\tget : function(){\n\t\t\treturn this._exp;\n\t\t},\n\t\tset : function(exp){\n\t\t\tthis._exp = exp;\n\t\t\tthis._expScaler.setMap(this._expFunc(this._exp));\n\t\t}\n\t});\n\n\n\t/**\n\t * the function which maps the waveshaper\n\t * @param {number} exp\n\t * @return {function}\n\t * @private\n\t */\n\tTone.Pow.prototype._expFunc = function(exp){\n\t\treturn function(val){\n\t\t\treturn Math.pow(Math.abs(val), exp);\n\t\t};\n\t};\n\n\t/**\n\t * Clean up.\n\t * @returns {Tone.Pow} this\n\t */\n\tTone.Pow.prototype.dispose = function(){\n\t\tTone.prototype.dispose.call(this);\n\t\tthis._expScaler.dispose();\n\t\tthis._expScaler = null;\n\t\treturn this;\n\t};\n\n\treturn Tone.Pow;\n});","define([\"Tone/core/Tone\", \"Tone/signal/WaveShaper\", \"Tone/signal/Signal\"], function(Tone){\n\n\t\"use strict\";\n\n\t/**\n\t * @class AudioToGain converts an input in AudioRange [-1,1] to NormalRange [0,1]. \n\t * See Tone.GainToAudio.\n\t *\n\t * @extends {Tone.SignalBase}\n\t * @constructor\n\t * @example\n\t * var a2g = new Tone.AudioToGain();\n\t */\n\tTone.AudioToGain = function(){\n\n\t\t/**\n\t\t * @type {WaveShaperNode}\n\t\t * @private\n\t\t */\n\t\tthis._norm = this.input = this.output = new Tone.WaveShaper(function(x){\n\t\t\treturn (x + 1) / 2;\n\t\t});\n\t};\n\n\tTone.extend(Tone.AudioToGain, Tone.SignalBase);\n\n\t/**\n\t * clean up\n\t * @returns {Tone.AudioToGain} this\n\t */\n\tTone.AudioToGain.prototype.dispose = function(){\n\t\tTone.prototype.dispose.call(this);\n\t\tthis._norm.dispose();\n\t\tthis._norm = null;\n\t\treturn this;\n\t};\n\n\treturn Tone.AudioToGain;\n});","define([\"Tone/core/Tone\", \"Tone/signal/WaveShaper\"], function(Tone){\n\n\t\"use strict\";\n\n\t/**\n\t * @class Convert an incoming signal between 0, 1 to an equal power gain scale.\n\t *\n\t * @extends {Tone.SignalBase}\n\t * @constructor\n\t * @example\n\t * var eqPowGain = new Tone.EqualPowerGain();\n\t */\n\tTone.EqualPowerGain = function(){\n\n\t\t/**\n\t\t * @type {Tone.WaveShaper}\n\t\t * @private\n\t\t */\n\t\tthis._eqPower = this.input = this.output = new Tone.WaveShaper(function(val){\n\t\t\tif (Math.abs(val) < 0.001){\n\t\t\t\t//should output 0 when input is 0\n\t\t\t\treturn 0;\n\t\t\t} else {\n\t\t\t\treturn this.equalPowerScale(val);\n\t\t\t}\n\t\t}.bind(this), 4096);\n\t};\n\n\tTone.extend(Tone.EqualPowerGain, Tone.SignalBase);\n\n\t/**\n\t * clean up\n\t * @returns {Tone.EqualPowerGain} this\n\t */\n\tTone.EqualPowerGain.prototype.dispose = function(){\n\t\tTone.prototype.dispose.call(this);\n\t\tthis._eqPower.dispose();\n\t\tthis._eqPower = null;\n\t\treturn this;\n\t};\n\n\treturn Tone.EqualPowerGain;\n});","'use strict';\n\ndefine(function (require) {\n\n var Effect = require('effect');\n var EQFilter = require('eqFilter');\n\n /**\n * p5.EQ is an audio effect that performs the function of a multiband\n * audio equalizer. Equalization is used to adjust the balance of\n * frequency compoenents of an audio signal. This process is commonly used\n * in sound production and recording to change the waveform before it reaches\n * a sound output device. EQ can also be used as an audio effect to create\n * interesting distortions by filtering out parts of the spectrum. p5.EQ is\n * built using a chain of Web Audio Biquad Filter Nodes and can be\n * instantiated with 3 or 8 bands. Bands can be added or removed from\n * the EQ by directly modifying p5.EQ.bands (the array that stores filters).\n *\n * This class extends p5.Effect.\n * Methods amp(), chain(),\n * drywet(), connect(), and\n * disconnect() are available.\n *\n * @class p5.EQ\n * @constructor\n * @extends p5.Effect\n * @param {Number} [_eqsize] Constructor will accept 3 or 8, defaults to 3\n * @return {Object} p5.EQ object\n *\n * @example\n *
\n * var eq;\n * var band_names;\n * var band_index;\n *\n * var soundFile, play;\n *\n * function preload() {\n * soundFormats('mp3', 'ogg');\n * soundFile = loadSound('assets/beat');\n * }\n *\n * function setup() {\n * eq = new p5.EQ(3);\n * soundFile.disconnect();\n * eq.process(soundFile);\n *\n * band_names = ['lows','mids','highs'];\n * band_index = 0;\n * play = false;\n * textAlign(CENTER);\n * }\n *\n * function draw() {\n * background(30);\n * noStroke();\n * fill(255);\n * text('click to kill',50,25);\n *\n * fill(255, 40, 255);\n * textSize(26);\n * text(band_names[band_index],50,55);\n *\n * fill(255);\n * textSize(9);\n * text('space = play/pause',50,80);\n * }\n *\n * //If mouse is over canvas, cycle to the next band and kill the frequency\n * function mouseClicked() {\n * for (var i = 0; i < eq.bands.length; i++) {\n * eq.bands[i].gain(0);\n * }\n * eq.bands[band_index].gain(-40);\n * if (mouseX > 0 && mouseX < width && mouseY < height && mouseY > 0) {\n * band_index === 2 ? band_index = 0 : band_index++;\n * }\n * }\n *\n * //use space bar to trigger play / pause\n * function keyPressed() {\n * if (key===' ') {\n * play = !play\n * play ? soundFile.loop() : soundFile.pause();\n * }\n * }\n *
\n */\n p5.EQ = function(_eqsize) {\n Effect.call(this);\n\n //p5.EQ can be of size (3) or (8), defaults to 3\n _eqsize = _eqsize === 3 || _eqsize === 8 ? _eqsize : 3;\n\n var factor;\n _eqsize === 3 ? factor = Math.pow(2,3) : factor = 2;\n\n /**\n * The p5.EQ is built with abstracted p5.Filter objects.\n * To modify any bands, use methods of the \n * p5.Filter API, especially `gain` and `freq`.\n * Bands are stored in an array, with indices 0 - 3, or 0 - 7\n * @property {Array} bands\n *\n */\n this.bands = [];\n\n\n var freq, res;\n for (var i = 0; i < _eqsize; i++) {\n if (i === _eqsize - 1) {\n freq = 21000;\n res = .01;\n } else if (i === 0) {\n freq = 100;\n res = .1;\n }\n else if (i===1) {\n freq = _eqsize === 3 ? 360 * factor : 360;\n res = 1;\n }else {\n freq = this.bands[i-1].freq() * factor;\n res = 1;\n }\n this.bands[i] = this._newBand(freq, res);\n\n if (i>0) {\n this.bands[i-1].connect(this.bands[i].biquad);\n } else {\n this.input.connect(this.bands[i].biquad);\n }\n }\n this.bands[_eqsize-1].connect(this.output);\n };\n p5.EQ.prototype = Object.create(Effect.prototype);\n\n /**\n * Process an input by connecting it to the EQ\n * @method process\n * @param {Object} src Audio source\n */\n p5.EQ.prototype.process = function (src) {\n src.connect(this.input);\n };\n\n // /**\n // * Set the frequency and gain of each band in the EQ. This method should be\n // * called with 3 or 8 frequency and gain pairs, depending on the size of the EQ.\n // * ex. eq.set(freq0, gain0, freq1, gain1, freq2, gain2);\n // *\n // * @method set\n // * @for p5.EQ\n // * @param {Number} [freq0] Frequency value for band with index 0\n // * @param {Number} [gain0] Gain value for band with index 0\n // * @param {Number} [freq1] Frequency value for band with index 1\n // * @param {Number} [gain1] Gain value for band with index 1\n // * @param {Number} [freq2] Frequency value for band with index 2\n // * @param {Number} [gain2] Gain value for band with index 2\n // * @param {Number} [freq3] Frequency value for band with index 3\n // * @param {Number} [gain3] Gain value for band with index 3\n // * @param {Number} [freq4] Frequency value for band with index 4\n // * @param {Number} [gain4] Gain value for band with index 4\n // * @param {Number} [freq5] Frequency value for band with index 5\n // * @param {Number} [gain5] Gain value for band with index 5\n // * @param {Number} [freq6] Frequency value for band with index 6\n // * @param {Number} [gain6] Gain value for band with index 6\n // * @param {Number} [freq7] Frequency value for band with index 7\n // * @param {Number} [gain7] Gain value for band with index 7\n // */\n p5.EQ.prototype.set = function() {\n if (arguments.length === this.bands.length * 2) {\n for (var i = 0; i < arguments.length; i+=2) {\n this.bands[i/2].freq(arguments[i]);\n this.bands[i/2].gain(arguments[i+1]);\n }\n }\n else {\n console.error('Argument mismatch. .set() should be called with ' + this.bands.length*2 +\n ' arguments. (one frequency and gain value pair for each band of the eq)');\n }\n };\n\n /**\n * Add a new band. Creates a p5.Filter and strips away everything but\n * the raw biquad filter. This method returns an abstracted p5.Filter,\n * which can be added to p5.EQ.bands, in order to create new EQ bands.\n * @private\n * @for p5.EQ\n * @method _newBand\n * @param {Number} freq\n * @param {Number} res\n * @return {Object} Abstracted Filter\n */\n p5.EQ.prototype._newBand = function(freq, res) {\n return new EQFilter(freq, res);\n };\n\n p5.EQ.prototype.dispose = function () {\n Effect.prototype.dispose.apply(this);\n\n if (this.bands) {\n while (this.bands.length > 0) {\n delete this.bands.pop().dispose();\n }\n delete this.bands;\n }\n };\n\n return p5.EQ;\n});\n","'use strict';\n\ndefine(function (require) {\n var Filter = require('filter');\n var p5sound = require('master');\n\n /**\n * EQFilter extends p5.Filter with constraints\n * necessary for the p5.EQ\n *\n * @private\n */\n var EQFilter = function(freq, res) {\n Filter.call(this, 'peaking');\n this.disconnect();\n this.set(freq, res);\n this.biquad.gain.value = 0;\n delete this.input;\n delete this.output;\n delete this._drywet;\n delete this.wet;\n\n };\n EQFilter.prototype = Object.create(Filter.prototype);\n\n EQFilter.prototype.amp = function() {\n console.warn('`amp()` is not available for p5.EQ bands. Use `.gain()`');\n };\n EQFilter.prototype.drywet = function() {\n console.warn('`drywet()` is not available for p5.EQ bands.');\n };\n EQFilter.prototype.connect = function(unit) {\n var u = unit || p5.soundOut.input;\n if (this.biquad) {\n this.biquad.connect(u.input ? u.input : u);\n } else {\n this.output.connect(u.input ? u.input : u);\n }\n };\n\n EQFilter.prototype.disconnect = function() {\n if (this.biquad) {\n this.biquad.disconnect();\n }\n };\n EQFilter.prototype.dispose = function() {\n // remove reference form soundArray\n var index = p5sound.soundArray.indexOf(this);\n p5sound.soundArray.splice(index, 1);\n this.disconnect();\n delete this.biquad;\n };\n\n return EQFilter;\n});\n","'use strict'\n\ndefine(function (require) {\n var p5sound = require('master');\n var Effect = require('effect');\n\n /**\n * Panner3D is based on the \n * Web Audio Spatial Panner Node.\n * This panner is a spatial processing node that allows audio to be positioned\n * and oriented in 3D space.\n *\n * The position is relative to an \n * Audio Context Listener, which can be accessed\n * by p5.soundOut.audiocontext.listener\n *\n *\n * @class p5.Panner3D\n * @constructor\n */\n\tp5.Panner3D = function() {\n Effect.call(this);\n\n /**\n * \n * Web Audio Spatial Panner Node\n *\n * Properties include\n * - panningModel: \"equal power\" or \"HRTF\"\n * - distanceModel: \"linear\", \"inverse\", or \"exponential\"\n *\n * @property {AudioNode} panner\n *\n */\n this.panner = this.ac.createPanner();\n this.panner.panningModel = 'HRTF';\n this.panner.distanceModel = 'linear';\n this.panner.connect(this.output);\n this.input.connect(this.panner);\n\t};\n\n p5.Panner3D.prototype = Object.create(Effect.prototype);\n\n\n /**\n * Connect an audio sorce\n *\n * @method process\n * @for p5.Panner3D\n * @param {Object} src Input source\n */\n p5.Panner3D.prototype.process = function(src) {\n src.connect(this.input);\n }\n /**\n * Set the X,Y,Z position of the Panner\n * @method set\n * @for p5.Panner3D\n * @param {Number} xVal\n * @param {Number} yVal\n * @param {Number} zVal\n * @param {Number} time\n * @return {Array} Updated x, y, z values as an array\n */\n p5.Panner3D.prototype.set = function(xVal, yVal, zVal, time) {\n this.positionX(xVal,time);\n this.positionY(yVal,time);\n this.positionZ(zVal,time);\n return [this.panner.positionX.value,\n this.panner.positionY.value,\n this.panner.positionZ.value];\n };\n\n /**\n * Getter and setter methods for position coordinates\n * @method positionX\n * @for p5.Panner3D\n * @return {Number} updated coordinate value\n */\n /**\n * Getter and setter methods for position coordinates\n * @method positionY\n * @for p5.Panner3D\n * @return {Number} updated coordinate value\n */\n /**\n * Getter and setter methods for position coordinates\n * @method positionZ\n * @for p5.Panner3D\n * @return {Number} updated coordinate value\n */\n p5.Panner3D.prototype.positionX = function(xVal, time) {\n var t = time || 0;\n if (typeof xVal === 'number') {\n this.panner.positionX.value = xVal;\n this.panner.positionX.cancelScheduledValues(this.ac.currentTime + 0.01 + t);\n this.panner.positionX.linearRampToValueAtTime(xVal, this.ac.currentTime + 0.02 + t);\n } else if (xVal) {\n xVal.connect(this.panner.positionX);\n }\n return this.panner.positionX.value;\n };\n p5.Panner3D.prototype.positionY = function(yVal, time) {\n var t = time || 0;\n if (typeof yVal === 'number') {\n this.panner.positionY.value = yVal;\n this.panner.positionY.cancelScheduledValues(this.ac.currentTime + 0.01 + t);\n this.panner.positionY.linearRampToValueAtTime(yVal, this.ac.currentTime + 0.02 + t);\n } else if (yVal) {\n yVal.connect(this.panner.positionY);\n }\n return this.panner.positionY.value;\n };\n p5.Panner3D.prototype.positionZ = function(zVal, time) {\n var t = time || 0;\n if (typeof zVal === 'number') {\n this.panner.positionZ.value = zVal;\n this.panner.positionZ.cancelScheduledValues(this.ac.currentTime + 0.01 + t);\n this.panner.positionZ.linearRampToValueAtTime(zVal, this.ac.currentTime + 0.02 + t);\n } else if (zVal) {\n zVal.connect(this.panner.positionZ);\n }\n return this.panner.positionZ.value;\n };\n\n /**\n * Set the X,Y,Z position of the Panner\n * @method orient\n * @for p5.Panner3D\n * @param {Number} xVal\n * @param {Number} yVal\n * @param {Number} zVal\n * @param {Number} time\n * @return {Array} Updated x, y, z values as an array\n */\n p5.Panner3D.prototype.orient = function(xVal, yVal, zVal, time) {\n this.orientX(xVal,time);\n this.orientY(yVal,time);\n this.orientZ(zVal,time);\n return [this.panner.orientationX.value,\n this.panner.orientationY.value,\n this.panner.orientationZ.value];\n };\n\n /**\n * Getter and setter methods for orient coordinates\n * @method orientX\n * @for p5.Panner3D\n * @return {Number} updated coordinate value\n */\n /**\n * Getter and setter methods for orient coordinates\n * @method orientY\n * @for p5.Panner3D\n * @return {Number} updated coordinate value\n */\n /**\n * Getter and setter methods for orient coordinates\n * @method orientZ\n * @for p5.Panner3D\n * @return {Number} updated coordinate value\n */\n p5.Panner3D.prototype.orientX = function(xVal, time) {\n var t = time || 0;\n if (typeof xVal === 'number') {\n this.panner.orientationX.value = xVal;\n this.panner.orientationX.cancelScheduledValues(this.ac.currentTime + 0.01 + t);\n this.panner.orientationX.linearRampToValueAtTime(xVal, this.ac.currentTime + 0.02 + t);\n } else if (xVal) {\n xVal.connect(this.panner.orientationX);\n }\n return this.panner.orientationX.value;\n };\n p5.Panner3D.prototype.orientY = function(yVal, time) {\n var t = time || 0;\n if (typeof yVal === 'number') {\n this.panner.orientationY.value = yVal;\n this.panner.orientationY.cancelScheduledValues(this.ac.currentTime + 0.01 + t);\n this.panner.orientationY.linearRampToValueAtTime(yVal, this.ac.currentTime + 0.02 + t);\n } else if (yVal) {\n yVal.connect(this.panner.orientationY);\n }\n return this.panner.orientationY.value;\n };\n p5.Panner3D.prototype.orientZ = function(zVal, time) {\n var t = time || 0;\n if (typeof zVal === 'number') {\n this.panner.orientationZ.value = zVal;\n this.panner.orientationZ.cancelScheduledValues(this.ac.currentTime + 0.01 + t);\n this.panner.orientationZ.linearRampToValueAtTime(zVal, this.ac.currentTime + 0.02 + t);\n } else if (zVal) {\n zVal.connect(this.panner.orientationZ);\n }\n return this.panner.orientationZ.value;\n };\n\n /**\n * Set the rolloff factor and max distance\n * @method setFalloff\n * @for p5.Panner3D\n * @param {Number} [maxDistance]\n * @param {Number} [rolloffFactor]\n */\n p5.Panner3D.prototype.setFalloff = function(maxDistance, rolloffFactor) {\n this.maxDist(maxDistance);\n this.rolloff(rolloffFactor);\n };\n /**\n * Maxium distance between the source and the listener\n * @method maxDist\n * @for p5.Panner3D\n * @param {Number} maxDistance\n * @return {Number} updated value\n */\n p5.Panner3D.prototype.maxDist = function(maxDistance){\n if (typeof maxDistance === 'number') {\n this.panner.maxDistance = maxDistance;\n }\n return this.panner.maxDistance;\n };\n\n /**\n * How quickly the volume is reduced as the source moves away from the listener\n * @method rollof\n * @for p5.Panner3D\n * @param {Number} rolloffFactor\n * @return {Number} updated value\n */\n p5.Panner3D.prototype.rolloff = function(rolloffFactor){\n if (typeof rolloffFactor === 'number') {\n this.panner.rolloffFactor = rolloffFactor;\n }\n return this.panner.rolloffFactor;\n };\n\n p5.Panner3D.dispose = function() {\n Effect.prototype.dispose.apply(this);\n if (this.panner) {\n this.panner.disconnect();\n delete this.panner;\n }\n };\n\n return p5.Panner3D;\n\n});\n","'use strict'\n\ndefine(function (require) {\n var p5sound = require('master');\n var Effect = require('effect');\n\n// /**\n// * listener is a class that can construct both a Spatial Panner\n// * and a Spatial Listener. The panner is based on the \n// * Web Audio Spatial Panner Node\n// * https://www.w3.org/TR/webaudio/#the-listenernode-interface\n// * This panner is a spatial processing node that allows audio to be positioned\n// * and oriented in 3D space. \n// *\n// * The Listener modifies the properties of the Audio Context Listener. \n// * Both objects types use the same methods. The default is a spatial panner.\n// *\n// * p5.Panner3D - Constructs a Spatial Panner \n// * p5.Listener3D - Constructs a Spatial Listener \n// *\n// * @class listener\n// * @constructor\n// * @return {Object} p5.Listener3D Object\n// *\n// * @param {Web Audio Node} listener Web Audio Spatial Panning Node\n// * @param {AudioParam} listener.panningModel \"equal power\" or \"HRTF\"\n// * @param {AudioParam} listener.distanceModel \"linear\", \"inverse\", or \"exponential\"\n// * @param {String} [type] [Specify construction of a spatial panner or listener]\n// */\n \n\tp5.Listener3D = function(type) {\n this.ac = p5sound.audiocontext;\n this.listener = this.ac.listener;\n\t}; \n\n// /**\n// * Connect an audio sorce\n// * @param {Object} src Input source\n// */\n p5.Listener3D.prototype.process = function(src) {\n src.connect(this.input);\n }\n// /**\n// * Set the X,Y,Z position of the Panner\n// * @param {[Number]} xVal\n// * @param {[Number]} yVal\n// * @param {[Number]} zVal\n// * @param {[Number]} time\n// * @return {[Array]} [Updated x, y, z values as an array]\n// */\n p5.Listener3D.prototype.position = function(xVal, yVal, zVal, time) {\n this.positionX(xVal,time);\n this.positionY(yVal,time);\n this.positionZ(zVal,time);\n return [this.listener.positionX.value, \n this.listener.positionY.value,\n this.listener.positionZ.value];\n };\n\n// /**\n// * Getter and setter methods for position coordinates\n// * @return {Number} [updated coordinate value]\n// */\n p5.Listener3D.prototype.positionX = function(xVal, time) {\n var t = time || 0;\n if (typeof xVal === 'number') {\n this.listener.positionX.value = xVal;\n this.listener.positionX.cancelScheduledValues(this.ac.currentTime + 0.01 + t);\n this.listener.positionX.linearRampToValueAtTime(xVal, this.ac.currentTime + 0.02 + t);\n } else if (xVal) {\n xVal.connect(this.listener.positionX);\n }\n return this.listener.positionX.value;\n };\n p5.Listener3D.prototype.positionY = function(yVal, time) {\n var t = time || 0;\n if (typeof yVal === 'number') {\n this.listener.positionY.value = yVal;\n this.listener.positionY.cancelScheduledValues(this.ac.currentTime + 0.01 + t);\n this.listener.positionY.linearRampToValueAtTime(yVal, this.ac.currentTime + 0.02 + t);\n } else if (yVal) {\n yVal.connect(this.listener.positionY);\n }\n return this.listener.positionY.value;\n };\n p5.Listener3D.prototype.positionZ = function(zVal, time) {\n var t = time || 0;\n if (typeof zVal === 'number') {\n this.listener.positionZ.value = zVal;\n this.listener.positionZ.cancelScheduledValues(this.ac.currentTime + 0.01 + t);\n this.listener.positionZ.linearRampToValueAtTime(zVal, this.ac.currentTime + 0.02 + t);\n } else if (zVal) {\n zVal.connect(this.listener.positionZ);\n }\n return this.listener.positionZ.value;\n };\n\n// cannot define method when class definition is commented\n// /**\n// * Overrides the listener orient() method because Listener has slightly\n// * different params. In human terms, Forward vectors are the direction the \n// * nose is pointing. Up vectors are the direction of the top of the head.\n// *\n// * @method orient\n// * @param {Number} xValF Forward vector X direction\n// * @param {Number} yValF Forward vector Y direction\n// * @param {Number} zValF Forward vector Z direction\n// * @param {Number} xValU Up vector X direction\n// * @param {Number} yValU Up vector Y direction\n// * @param {Number} zValU Up vector Z direction\n// * @param {Number} time \n// * @return {Array} All orienation params\n// */\n p5.Listener3D.prototype.orient = function(xValF, yValF, zValF, \n xValU, yValU, zValU, time) {\n\n if (arguments.length === 3 || arguments.length === 4) {\n time = arguments[3];\n this.orientForward(xValF, yValF, zValF, time);\n } else if (arguments.length === 6 || arguments === 7) {\n this.orientForward(xValF, yValF, zValF);\n this.orientUp(xValU, yValU, zValU, time);\n }\n \n return [this.listener.forwardX.value, \n this.listener.forwardY.value,\n this.listener.forwardZ.value,\n this.listener.upX.value,\n this.listener.upY.value,\n this.listener.upZ.value];\n };\n\n\n p5.Listener3D.prototype.orientForward = function(xValF, yValF, zValF, time) {\n this.forwardX(xValF,time);\n this.forwardY(yValF,time);\n this.forwardZ(zValF,time);\n\n return [this.listener.forwardX, \n this.listener.forwardY,\n this.listener.forwardZ];\n };\n\n p5.Listener3D.prototype.orientUp = function(xValU, yValU, zValU, time) {\n this.upX(xValU,time);\n this.upY(yValU,time);\n this.upZ(zValU,time);\n\n return [this.listener.upX, \n this.listener.upY,\n this.listener.upZ];\n };\n// /**\n// * Getter and setter methods for orient coordinates\n// * @return {Number} [updated coordinate value]\n// */\n p5.Listener3D.prototype.forwardX = function(xVal, time) {\n var t = time || 0;\n if (typeof xVal === 'number') {\n this.listener.forwardX.value = xVal;\n this.listener.forwardX.cancelScheduledValues(this.ac.currentTime + 0.01 + t);\n this.listener.forwardX.linearRampToValueAtTime(xVal, this.ac.currentTime + 0.02 + t);\n } else if (xVal) {\n xVal.connect(this.listener.forwardX);\n }\n return this.listener.forwardX.value;\n };\n p5.Listener3D.prototype.forwardY = function(yVal, time) {\n var t = time || 0;\n if (typeof yVal === 'number') {\n this.listener.forwardY.value = yVal;\n this.listener.forwardY.cancelScheduledValues(this.ac.currentTime + 0.01 + t);\n this.listener.forwardY.linearRampToValueAtTime(yVal, this.ac.currentTime + 0.02 + t);\n } else if (yVal) {\n yVal.connect(this.listener.forwardY);\n }\n return this.listener.forwardY.value;\n };\n p5.Listener3D.prototype.forwardZ = function(zVal, time) {\n var t = time || 0;\n if (typeof zVal === 'number') {\n this.listener.forwardZ.value = zVal;\n this.listener.forwardZ.cancelScheduledValues(this.ac.currentTime + 0.01 + t);\n this.listener.forwardZ.linearRampToValueAtTime(zVal, this.ac.currentTime + 0.02 + t);\n } else if (zVal) {\n zVal.connect(this.listener.forwardZ);\n }\n return this.listener.forwardZ.value;\n };\n p5.Listener3D.prototype.upX = function(xVal, time) {\n var t = time || 0;\n if (typeof xVal === 'number') {\n this.listener.upX.value = xVal;\n this.listener.upX.cancelScheduledValues(this.ac.currentTime + 0.01 + t);\n this.listener.upX.linearRampToValueAtTime(xVal, this.ac.currentTime + 0.02 + t);\n } else if (xVal) {\n xVal.connect(this.listener.upX);\n }\n return this.listener.upX.value;\n };\n p5.Listener3D.prototype.upY = function(yVal, time) {\n var t = time || 0;\n if (typeof yVal === 'number') {\n this.listener.upY.value = yVal;\n this.listener.upY.cancelScheduledValues(this.ac.currentTime + 0.01 + t);\n this.listener.upY.linearRampToValueAtTime(yVal, this.ac.currentTime + 0.02 + t);\n } else if (yVal) {\n yVal.connect(this.listener.upY);\n }\n return this.listener.upY.value;\n };\n p5.Listener3D.prototype.upZ = function(zVal, time) {\n var t = time || 0;\n if (typeof zVal === 'number') {\n this.listener.upZ.value = zVal;\n this.listener.upZ.cancelScheduledValues(this.ac.currentTime + 0.01 + t);\n this.listener.upZ.linearRampToValueAtTime(zVal, this.ac.currentTime + 0.02 + t);\n } else if (zVal) {\n zVal.connect(this.listener.upZ);\n }\n return this.listener.upZ.value;\n };\n \n return p5.Listener3D;\n\n});","'use strict';\n\ndefine(function (require) {\n var Filter = require('filter');\n var Effect = require('effect');\n\n /**\n * Delay is an echo effect. It processes an existing sound source,\n * and outputs a delayed version of that sound. The p5.Delay can\n * produce different effects depending on the delayTime, feedback,\n * filter, and type. In the example below, a feedback of 0.5 (the\n * defaul value) will produce a looping delay that decreases in\n * volume by 50% each repeat. A filter will cut out the high\n * frequencies so that the delay does not sound as piercing as the\n * original source.\n *\n *\n * This class extends p5.Effect.\n * Methods amp(), chain(),\n * drywet(), connect(), and\n * disconnect() are available.\n * @class p5.Delay\n * @extends p5.Effect\n * @constructor\n * @example\n *
\n * var noise, env, delay;\n *\n * function setup() {\n * background(0);\n * noStroke();\n * fill(255);\n * textAlign(CENTER);\n * text('click to play', width/2, height/2);\n *\n * noise = new p5.Noise('brown');\n * noise.amp(0);\n * noise.start();\n *\n * delay = new p5.Delay();\n *\n * // delay.process() accepts 4 parameters:\n * // source, delayTime, feedback, filter frequency\n * // play with these numbers!!\n * delay.process(noise, .12, .7, 2300);\n *\n * // play the noise with an envelope,\n * // a series of fades ( time / value pairs )\n * env = new p5.Envelope(.01, 0.2, .2, .1);\n * }\n *\n * // mouseClick triggers envelope\n * function mouseClicked() {\n * // is mouse over canvas?\n * if (mouseX > 0 && mouseX < width && mouseY > 0 && mouseY < height) {\n * env.play(noise);\n * }\n * }\n *
\n */\n p5.Delay = function() {\n \tEffect.call(this);\n\n this._split = this.ac.createChannelSplitter(2);\n this._merge = this.ac.createChannelMerger(2);\n\n this._leftGain = this.ac.createGain();\n this._rightGain = this.ac.createGain();\n\n /**\n * The p5.Delay is built with two\n * \n * Web Audio Delay Nodes, one for each stereo channel.\n *\n * @property {DelayNode} leftDelay\n */\n this.leftDelay = this.ac.createDelay();\n /**\n * The p5.Delay is built with two\n * \n * Web Audio Delay Nodes, one for each stereo channel.\n *\n * @property {DelayNode} rightDelay\n */\n this.rightDelay = this.ac.createDelay();\n\n this._leftFilter = new Filter();\n this._rightFilter = new Filter();\n this._leftFilter.disconnect();\n this._rightFilter.disconnect();\n\n this._leftFilter.biquad.frequency.setValueAtTime(1200, this.ac.currentTime);\n this._rightFilter.biquad.frequency.setValueAtTime(1200, this.ac.currentTime);\n this._leftFilter.biquad.Q.setValueAtTime(0.3, this.ac.currentTime);\n this._rightFilter.biquad.Q.setValueAtTime(0.3, this.ac.currentTime);\n\n // graph routing\n this.input.connect(this._split);\n this.leftDelay.connect(this._leftGain);\n this.rightDelay.connect(this._rightGain);\n this._leftGain.connect(this._leftFilter.input);\n this._rightGain.connect(this._rightFilter.input);\n this._merge.connect(this.wet);\n\n\n this._leftFilter.biquad.gain.setValueAtTime(1, this.ac.currentTime);\n this._rightFilter.biquad.gain.setValueAtTime(1, this.ac.currentTime);\n\n // default routing\n this.setType(0);\n\n this._maxDelay = this.leftDelay.delayTime.maxValue;\n\n // set initial feedback to 0.5\n this.feedback(0.5);\n\n\n };\n\n p5.Delay.prototype = Object.create(Effect.prototype);\n /**\n * Add delay to an audio signal according to a set\n * of delay parameters.\n *\n * @method process\n * @for p5.Delay\n * @param {Object} Signal An object that outputs audio\n * @param {Number} [delayTime] Time (in seconds) of the delay/echo.\n * Some browsers limit delayTime to\n * 1 second.\n * @param {Number} [feedback] sends the delay back through itself\n * in a loop that decreases in volume\n * each time.\n * @param {Number} [lowPass] Cutoff frequency. Only frequencies\n * below the lowPass will be part of the\n * delay.\n */\n p5.Delay.prototype.process = function(src, _delayTime, _feedback, _filter) {\n var feedback = _feedback || 0;\n var delayTime = _delayTime || 0;\n if (feedback >= 1.0) {\n throw new Error('Feedback value will force a positive feedback loop.');\n }\n if (delayTime >= this._maxDelay) {\n throw new Error('Delay Time exceeds maximum delay time of ' + this._maxDelay + ' second.');\n }\n\n src.connect(this.input);\n this.leftDelay.delayTime.setValueAtTime(delayTime, this.ac.currentTime);\n this.rightDelay.delayTime.setValueAtTime(delayTime, this.ac.currentTime);\n this._leftGain.gain.value = feedback;\n this._rightGain.gain.value = feedback;\n\n if (_filter) {\n this._leftFilter.freq(_filter);\n this._rightFilter.freq(_filter);\n }\n };\n\n /**\n * Set the delay (echo) time, in seconds. Usually this value will be\n * a floating point number between 0.0 and 1.0.\n *\n * @method delayTime\n * @for p5.Delay\n * @param {Number} delayTime Time (in seconds) of the delay\n */\n p5.Delay.prototype.delayTime = function(t) {\n // if t is an audio node...\n if (typeof t !== 'number') {\n t.connect(this.leftDelay.delayTime);\n t.connect(this.rightDelay.delayTime);\n }\n\n else {\n this.leftDelay.delayTime.cancelScheduledValues(this.ac.currentTime);\n this.rightDelay.delayTime.cancelScheduledValues(this.ac.currentTime);\n this.leftDelay.delayTime.linearRampToValueAtTime(t, this.ac.currentTime);\n this.rightDelay.delayTime.linearRampToValueAtTime(t, this.ac.currentTime);\n }\n };\n\n /**\n * Feedback occurs when Delay sends its signal back through its input\n * in a loop. The feedback amount determines how much signal to send each\n * time through the loop. A feedback greater than 1.0 is not desirable because\n * it will increase the overall output each time through the loop,\n * creating an infinite feedback loop. The default value is 0.5\n *\n * @method feedback\n * @for p5.Delay\n * @param {Number|Object} feedback 0.0 to 1.0, or an object such as an\n * Oscillator that can be used to\n * modulate this param\n * @returns {Number} Feedback value\n *\n */\n p5.Delay.prototype.feedback = function(f) {\n // if f is an audio node...\n if (f && typeof f !== 'number') {\n f.connect(this._leftGain.gain);\n f.connect(this._rightGain.gain);\n }\n else if (f >= 1.0) {\n throw new Error('Feedback value will force a positive feedback loop.');\n }\n else if (typeof f === 'number') {\n this._leftGain.gain.value = f;\n this._rightGain.gain.value = f;\n }\n\n // return value of feedback\n return this._leftGain.gain.value;\n };\n\n /**\n * Set a lowpass filter frequency for the delay. A lowpass filter\n * will cut off any frequencies higher than the filter frequency.\n *\n * @method filter\n * @for p5.Delay\n * @param {Number|Object} cutoffFreq A lowpass filter will cut off any\n * frequencies higher than the filter frequency.\n * @param {Number|Object} res Resonance of the filter frequency\n * cutoff, or an object (i.e. a p5.Oscillator)\n * that can be used to modulate this parameter.\n * High numbers (i.e. 15) will produce a resonance,\n * low numbers (i.e. .2) will produce a slope.\n */\n p5.Delay.prototype.filter = function(freq, q) {\n this._leftFilter.set(freq, q);\n this._rightFilter.set(freq, q);\n };\n\n\n /**\n * Choose a preset type of delay. 'pingPong' bounces the signal\n * from the left to the right channel to produce a stereo effect.\n * Any other parameter will revert to the default delay setting.\n *\n * @method setType\n * @for p5.Delay\n * @param {String|Number} type 'pingPong' (1) or 'default' (0)\n */\n p5.Delay.prototype.setType = function(t) {\n if (t === 1) {\n t = 'pingPong';\n }\n this._split.disconnect();\n this._leftFilter.disconnect();\n this._rightFilter.disconnect();\n this._split.connect(this.leftDelay, 0);\n this._split.connect(this.rightDelay, 1);\n switch(t) {\n case 'pingPong':\n this._rightFilter.setType( this._leftFilter.biquad.type );\n this._leftFilter.output.connect(this._merge, 0, 0);\n this._rightFilter.output.connect(this._merge, 0, 1);\n this._leftFilter.output.connect(this.rightDelay);\n this._rightFilter.output.connect(this.leftDelay);\n break;\n default:\n this._leftFilter.output.connect(this._merge, 0, 0);\n this._rightFilter.output.connect(this._merge, 0, 1);\n this._leftFilter.output.connect(this.leftDelay);\n this._rightFilter.output.connect(this.rightDelay);\n }\n };\n\n // DocBlocks for methods inherited from p5.Effect\n /**\n * Set the output level of the delay effect.\n *\n * @method amp\n * @for p5.Delay\n * @param {Number} volume amplitude between 0 and 1.0\n * @param {Number} [rampTime] create a fade that lasts rampTime\n * @param {Number} [timeFromNow] schedule this event to happen\n * seconds from now\n */\n /**\n * Send output to a p5.sound or web audio object\n *\n * @method connect\n * @for p5.Delay\n * @param {Object} unit\n */\n /**\n * Disconnect all output.\n *\n * @method disconnect\n * @for p5.Delay\n */\n\n p5.Delay.prototype.dispose = function() {\n\n Effect.prototype.dispose.apply(this);\n\n this._split.disconnect();\n this._leftFilter.dispose();\n this._rightFilter.dispose();\n this._merge.disconnect();\n this._leftGain.disconnect();\n this._rightGain.disconnect();\n this.leftDelay.disconnect();\n this.rightDelay.disconnect();\n\n this._split = undefined;\n this._leftFilter = undefined;\n this._rightFilter = undefined;\n this._merge = undefined;\n this._leftGain = undefined;\n this._rightGain = undefined;\n this.leftDelay = undefined;\n this.rightDelay = undefined;\n };\n\n});\n","'use strict';\n\ndefine(function (require) {\n var CustomError = require('errorHandler');\n var Effect = require('effect');\n\n /**\n * Reverb adds depth to a sound through a large number of decaying\n * echoes. It creates the perception that sound is occurring in a\n * physical space. The p5.Reverb has paramters for Time (how long does the\n * reverb last) and decayRate (how much the sound decays with each echo)\n * that can be set with the .set() or .process() methods. The p5.Convolver\n * extends p5.Reverb allowing you to recreate the sound of actual physical\n * spaces through convolution.\n *\n * This class extends p5.Effect.\n * Methods amp(), chain(),\n * drywet(), connect(), and\n * disconnect() are available.\n *\n * @class p5.Reverb\n * @extends p5.Effect\n * @constructor\n * @example\n *
\n * var soundFile, reverb;\n * function preload() {\n * soundFile = loadSound('assets/Damscray_DancingTiger.mp3');\n * }\n *\n * function setup() {\n * reverb = new p5.Reverb();\n * soundFile.disconnect(); // so we'll only hear reverb...\n *\n * // connect soundFile to reverb, process w/\n * // 3 second reverbTime, decayRate of 2%\n * reverb.process(soundFile, 3, 2);\n * soundFile.play();\n * }\n *
\n */\n\n\n p5.Reverb = function() {\n Effect.call(this);\n\n this._initConvolverNode();\n\n // otherwise, Safari distorts\n this.input.gain.value = 0.5;\n\n // default params\n this._seconds = 3;\n this._decay = 2;\n this._reverse = false;\n\n this._buildImpulse();\n\n };\n\n p5.Reverb.prototype = Object.create(Effect.prototype);\n\n p5.Reverb.prototype._initConvolverNode = function() {\n this.convolverNode = this.ac.createConvolver();\n this.input.connect(this.convolverNode);\n this.convolverNode.connect(this.wet);\n };\n\n p5.Reverb.prototype._teardownConvolverNode = function() {\n if (this.convolverNode) {\n this.convolverNode.disconnect();\n delete this.convolverNode;\n }\n };\n\n p5.Reverb.prototype._setBuffer = function(audioBuffer) {\n this._teardownConvolverNode();\n this._initConvolverNode();\n this.convolverNode.buffer = audioBuffer;\n };\n /**\n * Connect a source to the reverb, and assign reverb parameters.\n *\n * @method process\n * @for p5.Reverb\n * @param {Object} src p5.sound / Web Audio object with a sound\n * output.\n * @param {Number} [seconds] Duration of the reverb, in seconds.\n * Min: 0, Max: 10. Defaults to 3.\n * @param {Number} [decayRate] Percentage of decay with each echo.\n * Min: 0, Max: 100. Defaults to 2.\n * @param {Boolean} [reverse] Play the reverb backwards or forwards.\n */\n p5.Reverb.prototype.process = function(src, seconds, decayRate, reverse) {\n src.connect(this.input);\n var rebuild = false;\n if (seconds) {\n this._seconds = seconds;\n rebuild = true;\n }\n if (decayRate) {\n this._decay = decayRate;\n }\n if (reverse) {\n this._reverse = reverse;\n }\n if (rebuild) {\n this._buildImpulse();\n }\n };\n\n /**\n * Set the reverb settings. Similar to .process(), but without\n * assigning a new input.\n *\n * @method set\n * @for p5.Reverb\n * @param {Number} [seconds] Duration of the reverb, in seconds.\n * Min: 0, Max: 10. Defaults to 3.\n * @param {Number} [decayRate] Percentage of decay with each echo.\n * Min: 0, Max: 100. Defaults to 2.\n * @param {Boolean} [reverse] Play the reverb backwards or forwards.\n */\n p5.Reverb.prototype.set = function(seconds, decayRate, reverse) {\n var rebuild = false;\n if (seconds) {\n this._seconds = seconds;\n rebuild = true;\n }\n if (decayRate) {\n this._decay = decayRate;\n }\n if (reverse) {\n this._reverse = reverse;\n }\n if (rebuild) {\n this._buildImpulse();\n }\n };\n\n // DocBlocks for methods inherited from p5.Effect\n /**\n * Set the output level of the reverb effect.\n *\n * @method amp\n * @for p5.Reverb\n * @param {Number} volume amplitude between 0 and 1.0\n * @param {Number} [rampTime] create a fade that lasts rampTime\n * @param {Number} [timeFromNow] schedule this event to happen\n * seconds from now\n */\n /**\n * Send output to a p5.sound or web audio object\n *\n * @method connect\n * @for p5.Reverb\n * @param {Object} unit\n */\n /**\n * Disconnect all output.\n *\n * @method disconnect\n * @for p5.Reverb\n */\n\n /**\n * Inspired by Simple Reverb by Jordan Santell\n * https://github.com/web-audio-components/simple-reverb/blob/master/index.js\n *\n * Utility function for building an impulse response\n * based on the module parameters.\n *\n * @private\n */\n p5.Reverb.prototype._buildImpulse = function() {\n var rate = this.ac.sampleRate;\n var length = rate*this._seconds;\n var decay = this._decay;\n var impulse = this.ac.createBuffer(2, length, rate);\n var impulseL = impulse.getChannelData(0);\n var impulseR = impulse.getChannelData(1);\n var n, i;\n for (i = 0; i < length; i++) {\n n = this._reverse ? length - i : i;\n impulseL[i] = (Math.random() * 2 - 1) * Math.pow(1 - n / length, decay);\n impulseR[i] = (Math.random() * 2 - 1) * Math.pow(1 - n / length, decay);\n }\n this._setBuffer(impulse);\n };\n\n p5.Reverb.prototype.dispose = function() {\n Effect.prototype.dispose.apply(this);\n this._teardownConvolverNode();\n };\n\n // =======================================================================\n // *** p5.Convolver ***\n // =======================================================================\n\n /**\n *
p5.Convolver extends p5.Reverb. It can emulate the sound of real\n * physical spaces through a process called \n * convolution.
\n *\n *
Convolution multiplies any audio input by an \"impulse response\"\n * to simulate the dispersion of sound over time. The impulse response is\n * generated from an audio file that you provide. One way to\n * generate an impulse response is to pop a balloon in a reverberant space\n * and record the echo. Convolution can also be used to experiment with\n * sound.
\n *\n *
Use the method createConvolution(path) to instantiate a\n * p5.Convolver with a path to your impulse response audio file.
\n *\n * @class p5.Convolver\n * @extends p5.Effect\n * @constructor\n * @param {String} path path to a sound file\n * @param {Function} [callback] function to call when loading succeeds\n * @param {Function} [errorCallback] function to call if loading fails.\n * This function will receive an error or\n * XMLHttpRequest object with information\n * about what went wrong.\n * @example\n *
\n * var cVerb, sound;\n * function preload() {\n * // We have both MP3 and OGG versions of all sound assets\n * soundFormats('ogg', 'mp3');\n *\n * // Try replacing 'bx-spring' with other soundfiles like\n * // 'concrete-tunnel' 'small-plate' 'drum' 'beatbox'\n * cVerb = createConvolver('assets/bx-spring.mp3');\n *\n * // Try replacing 'Damscray_DancingTiger' with\n * // 'beat', 'doorbell', lucky_dragons_-_power_melody'\n * sound = loadSound('assets/Damscray_DancingTiger.mp3');\n * }\n *\n * function setup() {\n * // disconnect from master output...\n * sound.disconnect();\n *\n * // ...and process with cVerb\n * // so that we only hear the convolution\n * cVerb.process(sound);\n *\n * sound.play();\n * }\n *
\n */\n p5.Convolver = function(path, callback, errorCallback) {\n \t p5.Reverb.call(this);\n\n /**\n * Internally, the p5.Convolver uses the a\n * \n * Web Audio Convolver Node.\n *\n * @property {ConvolverNode} convolverNode\n */\n this._initConvolverNode();\n\n // otherwise, Safari distorts\n this.input.gain.value = 0.5;\n\n if (path) {\n this.impulses = [];\n this._loadBuffer(path, callback, errorCallback);\n }\n else {\n // parameters\n this._seconds = 3;\n this._decay = 2;\n this._reverse = false;\n\n this._buildImpulse();\n }\n\n };\n\n p5.Convolver.prototype = Object.create(p5.Reverb.prototype);\n\n p5.prototype.registerPreloadMethod('createConvolver', p5.prototype);\n\n /**\n * Create a p5.Convolver. Accepts a path to a soundfile\n * that will be used to generate an impulse response.\n *\n * @method createConvolver\n * @for p5\n * @param {String} path path to a sound file\n * @param {Function} [callback] function to call if loading is successful.\n * The object will be passed in as the argument\n * to the callback function.\n * @param {Function} [errorCallback] function to call if loading is not successful.\n * A custom error will be passed in as the argument\n * to the callback function.\n * @return {p5.Convolver}\n * @example\n *
\n * var cVerb, sound;\n * function preload() {\n * // We have both MP3 and OGG versions of all sound assets\n * soundFormats('ogg', 'mp3');\n *\n * // Try replacing 'bx-spring' with other soundfiles like\n * // 'concrete-tunnel' 'small-plate' 'drum' 'beatbox'\n * cVerb = createConvolver('assets/bx-spring.mp3');\n *\n * // Try replacing 'Damscray_DancingTiger' with\n * // 'beat', 'doorbell', lucky_dragons_-_power_melody'\n * sound = loadSound('assets/Damscray_DancingTiger.mp3');\n * }\n *\n * function setup() {\n * // disconnect from master output...\n * sound.disconnect();\n *\n * // ...and process with cVerb\n * // so that we only hear the convolution\n * cVerb.process(sound);\n *\n * sound.play();\n * }\n *
\n */\n p5.prototype.createConvolver = function(path, callback, errorCallback) {\n // if loading locally without a server\n if (window.location.origin.indexOf('file://') > -1 && window.cordova === 'undefined') {\n alert('This sketch may require a server to load external files. Please see http://bit.ly/1qcInwS');\n }\n var self = this;\n var cReverb = new p5.Convolver(path, function(buffer) {\n if (typeof callback === 'function') {\n callback(buffer);\n }\n\n if (typeof self._decrementPreload === 'function') {\n self._decrementPreload();\n }\n }, errorCallback);\n cReverb.impulses = [];\n return cReverb;\n };\n\n /**\n * Private method to load a buffer as an Impulse Response,\n * assign it to the convolverNode, and add to the Array of .impulses.\n *\n * @param {String} path\n * @param {Function} callback\n * @param {Function} errorCallback\n * @private\n */\n p5.Convolver.prototype._loadBuffer = function(path, callback, errorCallback) {\n var path = p5.prototype._checkFileFormats(path);\n var self = this;\n var errorTrace = new Error().stack;\n var ac = p5.prototype.getAudioContext();\n\n var request = new XMLHttpRequest();\n request.open('GET', path, true);\n request.responseType = 'arraybuffer';\n\n request.onload = function() {\n if (request.status === 200) {\n // on success loading file:\n ac.decodeAudioData(request.response,\n function(buff) {\n var buffer = {};\n var chunks = path.split('/');\n buffer.name = chunks[chunks.length - 1];\n buffer.audioBuffer = buff;\n self.impulses.push(buffer);\n self._setBuffer(buffer.audioBuffer);\n if (callback) {\n callback(buffer);\n }\n },\n // error decoding buffer. \"e\" is undefined in Chrome 11/22/2015\n function() {\n var err = new CustomError('decodeAudioData', errorTrace, self.url);\n var msg = 'AudioContext error at decodeAudioData for ' + self.url;\n if (errorCallback) {\n err.msg = msg;\n errorCallback(err);\n } else {\n console.error(msg +'\\n The error stack trace includes: \\n' + err.stack);\n }\n }\n );\n }\n // if request status != 200, it failed\n else {\n var err = new CustomError('loadConvolver', errorTrace, self.url);\n var msg = 'Unable to load ' + self.url +\n '. The request status was: ' + request.status + ' (' + request.statusText + ')';\n\n if (errorCallback) {\n err.message = msg;\n errorCallback(err);\n } else {\n console.error(msg +'\\n The error stack trace includes: \\n' + err.stack);\n }\n }\n };\n\n // if there is another error, aside from 404...\n request.onerror = function() {\n var err = new CustomError('loadConvolver', errorTrace, self.url);\n var msg = 'There was no response from the server at ' + self.url + '. Check the url and internet connectivity.';\n\n if (errorCallback) {\n err.message = msg;\n errorCallback(err);\n } else {\n console.error(msg +'\\n The error stack trace includes: \\n' + err.stack);\n }\n };\n request.send();\n };\n\n p5.Convolver.prototype.set = null;\n\n /**\n * Connect a source to the reverb, and assign reverb parameters.\n *\n * @method process\n * @for p5.Convolver\n * @param {Object} src p5.sound / Web Audio object with a sound\n * output.\n * @example\n *
\n * var cVerb, sound;\n * function preload() {\n * soundFormats('ogg', 'mp3');\n *\n * cVerb = createConvolver('assets/concrete-tunnel.mp3');\n *\n * sound = loadSound('assets/beat.mp3');\n * }\n *\n * function setup() {\n * // disconnect from master output...\n * sound.disconnect();\n *\n * // ...and process with (i.e. connect to) cVerb\n * // so that we only hear the convolution\n * cVerb.process(sound);\n *\n * sound.play();\n * }\n *
\n */\n p5.Convolver.prototype.process = function(src) {\n src.connect(this.input);\n };\n\n /**\n * If you load multiple impulse files using the .addImpulse method,\n * they will be stored as Objects in this Array. Toggle between them\n * with the toggleImpulse(id) method.\n *\n * @property {Array} impulses\n * @for p5.Convolver\n */\n p5.Convolver.prototype.impulses = [];\n\n /**\n * Load and assign a new Impulse Response to the p5.Convolver.\n * The impulse is added to the .impulses array. Previous\n * impulses can be accessed with the .toggleImpulse(id)\n * method.\n *\n * @method addImpulse\n * @for p5.Convolver\n * @param {String} path path to a sound file\n * @param {Function} callback function (optional)\n * @param {Function} errorCallback function (optional)\n */\n p5.Convolver.prototype.addImpulse = function(path, callback, errorCallback) {\n // if loading locally without a server\n if (window.location.origin.indexOf('file://') > -1 && window.cordova === 'undefined') {\n alert('This sketch may require a server to load external files. Please see http://bit.ly/1qcInwS');\n }\n this._loadBuffer(path, callback, errorCallback);\n };\n\n /**\n * Similar to .addImpulse, except that the .impulses\n * Array is reset to save memory. A new .impulses\n * array is created with this impulse as the only item.\n *\n * @method resetImpulse\n * @for p5.Convolver\n * @param {String} path path to a sound file\n * @param {Function} callback function (optional)\n * @param {Function} errorCallback function (optional)\n */\n p5.Convolver.prototype.resetImpulse = function(path, callback, errorCallback) {\n // if loading locally without a server\n if (window.location.origin.indexOf('file://') > -1 && window.cordova === 'undefined') {\n alert('This sketch may require a server to load external files. Please see http://bit.ly/1qcInwS');\n }\n this.impulses = [];\n this._loadBuffer(path, callback, errorCallback);\n };\n\n /**\n * If you have used .addImpulse() to add multiple impulses\n * to a p5.Convolver, then you can use this method to toggle between\n * the items in the .impulses Array. Accepts a parameter\n * to identify which impulse you wish to use, identified either by its\n * original filename (String) or by its position in the .impulses\n * Array (Number). \n * You can access the objects in the .impulses Array directly. Each\n * Object has two attributes: an .audioBuffer (type:\n * Web Audio \n * AudioBuffer) and a .name, a String that corresponds\n * with the original filename.\n *\n * @method toggleImpulse\n * @for p5.Convolver\n * @param {String|Number} id Identify the impulse by its original filename\n * (String), or by its position in the\n * .impulses Array (Number).\n */\n p5.Convolver.prototype.toggleImpulse = function(id) {\n if (typeof id === 'number' && id < this.impulses.length) {\n this._setBuffer(this.impulses[id].audioBuffer);\n }\n if (typeof id === 'string') {\n for (var i = 0; i < this.impulses.length; i++) {\n if (this.impulses[i].name === id) {\n this._setBuffer(this.impulses[i].audioBuffer);\n break;\n }\n }\n }\n };\n\n p5.Convolver.prototype.dispose = function() {\n p5.Reverb.prototype.dispose.apply(this);\n\n // remove all the Impulse Response buffers\n for (var i in this.impulses) {\n if (this.impulses[i]) {\n this.impulses[i] = null;\n }\n }\n };\n\n});\n","'use strict';\n\ndefine(function (require) {\n var p5sound = require('master');\n\n // requires the Tone.js library's Clock (MIT license, Yotam Mann)\n // https://github.com/TONEnoTONE/Tone.js/\n var Clock = require('Tone/core/Clock');\n\n p5.Metro = function() {\n this.clock = new Clock({\n 'callback': this.ontick.bind(this)\n });\n this.syncedParts = [];\n this.bpm = 120; // gets overridden by p5.Part\n this._init();\n\n this.prevTick = 0;\n this.tatumTime = 0;\n\n this.tickCallback = function() {};\n };\n\n p5.Metro.prototype.ontick = function(tickTime) {\n var elapsedTime = tickTime - this.prevTick;\n var secondsFromNow = tickTime - p5sound.audiocontext.currentTime;\n if (elapsedTime - this.tatumTime <= -0.02) {\n return;\n } else {\n // console.log('ok', this.syncedParts[0].phrases[0].name);\n this.prevTick = tickTime;\n\n // for all of the active things on the metro:\n var self = this;\n this.syncedParts.forEach(function(thisPart) {\n if (!thisPart.isPlaying) return;\n thisPart.incrementStep(secondsFromNow);\n // each synced source keeps track of its own beat number\n thisPart.phrases.forEach(function(thisPhrase) {\n var phraseArray = thisPhrase.sequence;\n var bNum = self.metroTicks % phraseArray.length;\n if (phraseArray[bNum] !== 0 && (self.metroTicks < phraseArray.length || !thisPhrase.looping) ) {\n thisPhrase.callback(secondsFromNow, phraseArray[bNum]);\n }\n });\n });\n this.metroTicks += 1;\n this.tickCallback(secondsFromNow);\n }\n };\n\n p5.Metro.prototype.setBPM = function(bpm, rampTime) {\n var beatTime = 60 / (bpm*this.tatums);\n var now = p5sound.audiocontext.currentTime;\n this.tatumTime = beatTime;\n\n var rampTime = rampTime || 0;\n this.clock.frequency.setValueAtTime(this.clock.frequency.value, now);\n this.clock.frequency.linearRampToValueAtTime(bpm, now + rampTime);\n this.bpm = bpm;\n };\n\n p5.Metro.prototype.getBPM = function() {\n return this.clock.getRate() / this.tatums * 60;\n };\n\n p5.Metro.prototype._init = function() {\n this.metroTicks = 0;\n // this.setBPM(120);\n };\n\n // clear existing synced parts, add only this one\n p5.Metro.prototype.resetSync = function(part) {\n this.syncedParts = [part];\n };\n\n // push a new synced part to the array\n p5.Metro.prototype.pushSync = function(part) {\n this.syncedParts.push(part);\n };\n\n p5.Metro.prototype.start = function(timeFromNow) {\n var t = timeFromNow || 0;\n var now = p5sound.audiocontext.currentTime;\n this.clock.start(now + t);\n this.setBPM(this.bpm);\n };\n\n p5.Metro.prototype.stop = function(timeFromNow) {\n var t = timeFromNow || 0;\n var now = p5sound.audiocontext.currentTime;\n this.clock.stop(now + t);\n };\n\n p5.Metro.prototype.beatLength = function(tatums) {\n this.tatums = 1/tatums / 4; // lowest possible division of a beat\n };\n\n});\n","define([\"Tone/core/Tone\", \"Tone/core/Timeline\", \"Tone/type/Type\"], function (Tone) {\n\n\t\"use strict\";\n\n\t/**\n\t * @class A Timeline State. Provides the methods: setStateAtTime(\"state\", time)\n\t * and getValueAtTime(time).\n\t *\n\t * @extends {Tone.Timeline}\n\t * @param {String} initial The initial state of the TimelineState. \n\t * Defaults to undefined\n\t */\n\tTone.TimelineState = function(initial){\n\n\t\tTone.Timeline.call(this);\n\n\t\t/**\n\t\t * The initial state\n\t\t * @private\n\t\t * @type {String}\n\t\t */\n\t\tthis._initial = initial;\n\t};\n\n\tTone.extend(Tone.TimelineState, Tone.Timeline);\n\n\t/**\n\t * Returns the scheduled state scheduled before or at\n\t * the given time.\n\t * @param {Number} time The time to query.\n\t * @return {String} The name of the state input in setStateAtTime.\n\t */\n\tTone.TimelineState.prototype.getValueAtTime = function(time){\n\t\tvar event = this.get(time);\n\t\tif (event !== null){\n\t\t\treturn event.state;\n\t\t} else {\n\t\t\treturn this._initial;\n\t\t}\n\t};\n\n\t/**\n\t * Returns the scheduled state scheduled before or at\n\t * the given time.\n\t * @param {String} state The name of the state to set.\n\t * @param {Number} time The time to query.\n\t */\n\tTone.TimelineState.prototype.setStateAtTime = function(state, time){\n\t\tthis.add({\n\t\t\t\"state\" : state,\n\t\t\t\"time\" : time\n\t\t});\n\t};\n\n\treturn Tone.TimelineState;\n});","'use strict';\n\ndefine(function(require) {\n var p5sound = require('master');\n\n var BPM = 120;\n\n /**\n * Set the global tempo, in beats per minute, for all\n * p5.Parts. This method will impact all active p5.Parts.\n *\n * @method setBPM\n * @for p5\n * @param {Number} BPM Beats Per Minute\n * @param {Number} rampTime Seconds from now\n */\n p5.prototype.setBPM = function(bpm, rampTime) {\n BPM = bpm;\n for (var i in p5sound.parts) {\n if (p5sound.parts[i]) {\n p5sound.parts[i].setBPM(bpm, rampTime);\n }\n }\n };\n\n /**\n *
A phrase is a pattern of musical events over time, i.e.\n * a series of notes and rests.
\n *\n *
Phrases must be added to a p5.Part for playback, and\n * each part can play multiple phrases at the same time.\n * For example, one Phrase might be a kick drum, another\n * could be a snare, and another could be the bassline.
\n *\n *
The first parameter is a name so that the phrase can be\n * modified or deleted later. The callback is a a function that\n * this phrase will call at every step—for example it might be\n * called playNote(value){}. The array determines\n * which value is passed into the callback at each step of the\n * phrase. It can be numbers, an object with multiple numbers,\n * or a zero (0) indicates a rest so the callback won't be called).
\n *\n * @class p5.Phrase\n * @constructor\n * @param {String} name Name so that you can access the Phrase.\n * @param {Function} callback The name of a function that this phrase\n * will call. Typically it will play a sound,\n * and accept two parameters: a time at which\n * to play the sound (in seconds from now),\n * and a value from the sequence array. The\n * time should be passed into the play() or\n * start() method to ensure precision.\n * @param {Array} sequence Array of values to pass into the callback\n * at each step of the phrase.\n * @example\n *
\n */\n p5.Phrase = function(name, callback, sequence) {\n this.phraseStep = 0;\n this.name = name;\n this.callback = callback;\n /**\n * Array of values to pass into the callback\n * at each step of the phrase. Depending on the callback\n * function's requirements, these values may be numbers,\n * strings, or an object with multiple parameters.\n * Zero (0) indicates a rest.\n *\n * @property {Array} sequence\n */\n this.sequence = sequence;\n };\n\n /**\n *
A p5.Part plays back one or more p5.Phrases. Instantiate a part\n * with steps and tatums. By default, each step represents a 1/16th note.
\n *\n *
See p5.Phrase for more about musical timing.
\n *\n * @class p5.Part\n * @constructor\n * @param {Number} [steps] Steps in the part\n * @param {Number} [tatums] Divisions of a beat, e.g. use 1/4, or 0.25 for a quater note (default is 1/16, a sixteenth note)\n * @example\n *
\n * var box, drum, myPart;\n * var boxPat = [1,0,0,2,0,2,0,0];\n * var drumPat = [0,1,1,0,2,0,1,0];\n * var msg = 'click to play';\n *\n * function preload() {\n * box = loadSound('assets/beatbox.mp3');\n * drum = loadSound('assets/drum.mp3');\n * }\n *\n * function setup() {\n * noStroke();\n * fill(255);\n * textAlign(CENTER);\n * masterVolume(0.1);\n *\n * var boxPhrase = new p5.Phrase('box', playBox, boxPat);\n * var drumPhrase = new p5.Phrase('drum', playDrum, drumPat);\n * myPart = new p5.Part();\n * myPart.addPhrase(boxPhrase);\n * myPart.addPhrase(drumPhrase);\n * myPart.setBPM(60);\n * masterVolume(0.1);\n * }\n *\n * function draw() {\n * background(0);\n * text(msg, width/2, height/2);\n * }\n *\n * function playBox(time, playbackRate) {\n * box.rate(playbackRate);\n * box.play(time);\n * }\n *\n * function playDrum(time, playbackRate) {\n * drum.rate(playbackRate);\n * drum.play(time);\n * }\n *\n * function mouseClicked() {\n * if (mouseX > 0 && mouseX < width && mouseY > 0 && mouseY < height) {\n * myPart.start();\n * msg = 'playing part';\n * }\n * }\n *
\n */\n p5.Part = function(steps, bLength) {\n this.length = steps || 0; // how many beats\n this.partStep = 0;\n this.phrases = [];\n this.isPlaying = false;\n this.noLoop();\n this.tatums = bLength || 0.0625; // defaults to quarter note\n\n this.metro = new p5.Metro();\n this.metro._init();\n this.metro.beatLength(this.tatums);\n this.metro.setBPM(BPM);\n p5sound.parts.push(this);\n this.callback = function() {};\n };\n\n /**\n * Set the tempo of this part, in Beats Per Minute.\n *\n * @method setBPM\n * @for p5.Part\n * @param {Number} BPM Beats Per Minute\n * @param {Number} [rampTime] Seconds from now\n */\n p5.Part.prototype.setBPM = function(tempo, rampTime) {\n this.metro.setBPM(tempo, rampTime);\n };\n\n /**\n * Returns the tempo, in Beats Per Minute, of this part.\n *\n * @method getBPM\n * @for p5.Part\n * @return {Number}\n */\n p5.Part.prototype.getBPM = function() {\n return this.metro.getBPM();\n };\n\n /**\n * Start playback of this part. It will play\n * through all of its phrases at a speed\n * determined by setBPM.\n *\n * @method start\n * @for p5.Part\n * @param {Number} [time] seconds from now\n */\n p5.Part.prototype.start = function(time) {\n if (!this.isPlaying) {\n this.isPlaying = true;\n this.metro.resetSync(this);\n var t = time || 0;\n this.metro.start(t);\n }\n };\n\n /**\n * Loop playback of this part. It will begin\n * looping through all of its phrases at a speed\n * determined by setBPM.\n *\n * @method loop\n * @for p5.Part\n * @param {Number} [time] seconds from now\n */\n p5.Part.prototype.loop = function(time) {\n this.looping = true;\n // rest onended function\n this.onended = function() {\n this.partStep = 0;\n };\n var t = time || 0;\n this.start(t);\n };\n\n /**\n * Tell the part to stop looping.\n *\n * @method noLoop\n * @for p5.Part\n */\n p5.Part.prototype.noLoop = function() {\n this.looping = false;\n // rest onended function\n this.onended = function() {\n this.stop();\n };\n };\n\n /**\n * Stop the part and cue it to step 0. Playback will resume from the begining of the Part when it is played again.\n *\n * @method stop\n * @for p5.Part\n * @param {Number} [time] seconds from now\n */\n p5.Part.prototype.stop = function(time) {\n this.partStep = 0;\n this.pause(time);\n };\n\n /**\n * Pause the part. Playback will resume\n * from the current step.\n *\n * @method pause\n * @for p5.Part\n * @param {Number} time seconds from now\n */\n p5.Part.prototype.pause = function(time) {\n this.isPlaying = false;\n var t = time || 0;\n this.metro.stop(t);\n };\n\n /**\n * Add a p5.Phrase to this Part.\n *\n * @method addPhrase\n * @for p5.Part\n * @param {p5.Phrase} phrase reference to a p5.Phrase\n */\n p5.Part.prototype.addPhrase = function(name, callback, array) {\n var p;\n if (arguments.length === 3) {\n p = new p5.Phrase(name, callback, array);\n } else if (arguments[0] instanceof p5.Phrase) {\n p = arguments[0];\n } else {\n throw 'invalid input. addPhrase accepts name, callback, array or a p5.Phrase';\n }\n this.phrases.push(p);\n // reset the length if phrase is longer than part's existing length\n if (p.sequence.length > this.length) {\n this.length = p.sequence.length;\n }\n };\n\n /**\n * Remove a phrase from this part, based on the name it was\n * given when it was created.\n *\n * @method removePhrase\n * @for p5.Part\n * @param {String} phraseName\n */\n p5.Part.prototype.removePhrase = function(name) {\n for (var i in this.phrases) {\n if (this.phrases[i].name === name) {\n this.phrases.splice(i, 1);\n }\n }\n };\n\n /**\n * Get a phrase from this part, based on the name it was\n * given when it was created. Now you can modify its array.\n *\n * @method getPhrase\n * @for p5.Part\n * @param {String} phraseName\n */\n p5.Part.prototype.getPhrase = function(name) {\n for (var i in this.phrases) {\n if (this.phrases[i].name === name) {\n return this.phrases[i];\n }\n }\n };\n\n /**\n * Find all sequences with the specified name, and replace their patterns with the specified array.\n *\n * @method replaceSequence\n * @for p5.Part\n * @param {String} phraseName\n * @param {Array} sequence Array of values to pass into the callback\n * at each step of the phrase.\n */\n p5.Part.prototype.replaceSequence = function(name, array) {\n for (var i in this.phrases) {\n if (this.phrases[i].name === name) {\n this.phrases[i].sequence = array;\n }\n }\n };\n\n p5.Part.prototype.incrementStep = function(time) {\n if (this.partStep < this.length - 1) {\n this.callback(time);\n this.partStep += 1;\n } else {\n if (!this.looping && this.partStep === this.length - 1) {\n console.log('done');\n // this.callback(time);\n this.onended();\n }\n }\n };\n\n /**\n * Set the function that will be called at every step. This will clear the previous function.\n *\n * @method onStep\n * @for p5.Part\n * @param {Function} callback The name of the callback\n * you want to fire\n * on every beat/tatum.\n */\n p5.Part.prototype.onStep = function(callback) {\n this.callback = callback;\n };\n\n\n // ===============\n // p5.Score\n // ===============\n\n /**\n * A Score consists of a series of Parts. The parts will\n * be played back in order. For example, you could have an\n * A part, a B part, and a C part, and play them back in this order\n * new p5.Score(a, a, b, a, c)\n *\n * @class p5.Score\n * @constructor\n * @param {p5.Part} [...parts] One or multiple parts, to be played in sequence.\n */\n p5.Score = function() {\n // for all of the arguments\n this.parts = [];\n this.currentPart = 0;\n\n var thisScore = this;\n for (var i in arguments) {\n if (arguments[i] && this.parts[i]) {\n this.parts[i] = arguments[i];\n this.parts[i].nextPart = this.parts[i + 1];\n this.parts[i].onended = function() {\n thisScore.resetPart(i);\n playNextPart(thisScore);\n };\n }\n }\n this.looping = false;\n };\n\n p5.Score.prototype.onended = function() {\n if (this.looping) {\n // this.resetParts();\n this.parts[0].start();\n } else {\n this.parts[this.parts.length - 1].onended = function() {\n this.stop();\n this.resetParts();\n };\n }\n this.currentPart = 0;\n };\n\n /**\n * Start playback of the score.\n *\n * @method start\n * @for p5.Score\n */\n p5.Score.prototype.start = function() {\n this.parts[this.currentPart].start();\n this.scoreStep = 0;\n };\n\n /**\n * Stop playback of the score.\n *\n * @method stop\n * @for p5.Score\n */\n p5.Score.prototype.stop = function() {\n this.parts[this.currentPart].stop();\n this.currentPart = 0;\n this.scoreStep = 0;\n };\n\n /**\n * Pause playback of the score.\n *\n * @method pause\n * @for p5.Score\n */\n p5.Score.prototype.pause = function() {\n this.parts[this.currentPart].stop();\n };\n\n /**\n * Loop playback of the score.\n *\n * @method loop\n * @for p5.Score\n */\n p5.Score.prototype.loop = function() {\n this.looping = true;\n this.start();\n };\n\n /**\n * Stop looping playback of the score. If it\n * is currently playing, this will go into effect\n * after the current round of playback completes.\n *\n * @method noLoop\n * @for p5.Score\n */\n p5.Score.prototype.noLoop = function() {\n this.looping = false;\n };\n\n p5.Score.prototype.resetParts = function() {\n var self = this;\n this.parts.forEach(function(part) {\n self.resetParts[part];\n });\n };\n\n p5.Score.prototype.resetPart = function(i) {\n this.parts[i].stop();\n this.parts[i].partStep = 0;\n for (var p in this.parts[i].phrases) {\n if (this.parts[i]) {\n this.parts[i].phrases[p].phraseStep = 0;\n }\n }\n };\n\n /**\n * Set the tempo for all parts in the score\n *\n * @method setBPM\n * @for p5.Score\n * @param {Number} BPM Beats Per Minute\n * @param {Number} rampTime Seconds from now\n */\n p5.Score.prototype.setBPM = function(bpm, rampTime) {\n for (var i in this.parts) {\n if (this.parts[i]) {\n this.parts[i].setBPM(bpm, rampTime);\n }\n }\n };\n\n function playNextPart(aScore) {\n aScore.currentPart++;\n if (aScore.currentPart >= aScore.parts.length) {\n aScore.scoreStep = 0;\n aScore.onended();\n } else {\n aScore.scoreStep = 0;\n aScore.parts[aScore.currentPart - 1].stop();\n aScore.parts[aScore.currentPart].start();\n }\n }\n\n});\n","'use strict';\n\ndefine(function (require) {\n var p5sound = require('master');\n var Clock = require('Tone/core/Clock');\n\n /**\n * SoundLoop\n *\n * @class p5.SoundLoop\n * @constructor\n *\n * @param {Function} callback this function will be called on each iteration of theloop\n * @param {Number|String} [interval] amount of time or beats for each iteration of the loop\n * defaults to 1\n *\n * @example\n *
\n * var click;\n * var looper1;\n *\n * function preload() {\n * click = loadSound('assets/drum.mp3');\n * }\n *\n * function setup() {\n * //the looper's callback is passed the timeFromNow\n * //this value should be used as a reference point from\n * //which to schedule sounds\n * looper1 = new p5.SoundLoop(function(timeFromNow){\n * click.play(timeFromNow);\n * background(255 * (looper1.iterations % 2));\n * }, 2);\n *\n * //stop after 10 iteratios;\n * looper1.maxIterations = 10;\n * //start the loop\n * looper1.start();\n * }\n *
\n */\n p5.SoundLoop = function(callback, interval) {\n this.callback = callback;\n /**\n * musicalTimeMode uses Tone.Time convention\n\t * true if string, false if number\n * @property {Boolean} musicalTimeMode\n */\n this.musicalTimeMode = typeof this._interval === 'number' ? false : true;\n\n this._interval = interval || 1;\n\n /**\n * musicalTimeMode variables\n * modify these only when the interval is specified in musicalTime format as a string\n */\n this._timeSignature = 4;\n this._bpm = 60;\n\n this.isPlaying = false;\n\n /**\n * Set a limit to the number of loops to play. defaults to Infinity\n * @property {Number} maxIterations\n */\n this.maxIterations = Infinity;\n var self = this;\n\n this.clock = new Clock({\n 'callback' : function(time) {\n var timeFromNow = time - p5sound.audiocontext.currentTime;\n /**\n * Do not initiate the callback if timeFromNow is < 0\n * This ususually occurs for a few milliseconds when the page\n * is not fully loaded\n *\n * The callback should only be called until maxIterations is reached\n */\n if (timeFromNow > 0 && self.iterations <= self.maxIterations) {\n self.callback(timeFromNow);}\n },\n 'frequency' : this._calcFreq()\n });\n };\n\n /**\n * Start the loop\n * @method start\n * @for p5.SoundLoop\n * @param {Number} [timeFromNow] schedule a starting time\n */\n p5.SoundLoop.prototype.start = function(timeFromNow) {\n var t = timeFromNow || 0;\n var now = p5sound.audiocontext.currentTime;\n if (!this.isPlaying) {\n this.clock.start(now + t);\n this.isPlaying = true;\n }\n };\n\n /**\n * Stop the loop\n * @method stop\n * @for p5.SoundLoop\n * @param {Number} [timeFromNow] schedule a stopping time\n */\n p5.SoundLoop.prototype.stop = function(timeFromNow) {\n var t = timeFromNow || 0;\n var now = p5sound.audiocontext.currentTime;\n if (this.isPlaying) {\n this.clock.stop(now + t);\n this.isPlaying = false;\n }\n };\n /**\n * Pause the loop\n * @method pause\n * @for p5.SoundLoop\n * @param {Number} [timeFromNow] schedule a pausing time\n */\n p5.SoundLoop.prototype.pause = function(timeFromNow) {\n var t = timeFromNow || 0;\n var now = p5sound.audiocontext.currentTime;\n if (this.isPlaying) {\n this.clock.pause(now + t);\n this.isPlaying = false;\n }\n };\n\n\n /**\n * Synchronize loops. Use this method to start two more more loops in synchronization\n * or to start a loop in synchronization with a loop that is already playing\n * This method will schedule the implicit loop in sync with the explicit master loop\n * i.e. loopToStart.syncedStart(loopToSyncWith)\n *\n * @method syncedStart\n * @for p5.SoundLoop\n * @param {Object} otherLoop a p5.SoundLoop to sync with\n * @param {Number} [timeFromNow] Start the loops in sync after timeFromNow seconds\n */\n p5.SoundLoop.prototype.syncedStart = function(otherLoop, timeFromNow) {\n var t = timeFromNow || 0;\n var now = p5sound.audiocontext.currentTime;\n\n if (!otherLoop.isPlaying) {\n otherLoop.clock.start(now + t);\n otherLoop.isPlaying = true;\n this.clock.start(now + t);\n this.isPlaying = true;\n } else if (otherLoop.isPlaying) {\n var time = otherLoop.clock._nextTick - p5sound.audiocontext.currentTime;\n this.clock.start(now + time);\n this.isPlaying = true;\n }\n };\n\n\n /**\n * Updates frequency value, reflected in next callback\n * @private\n * @for p5.SoundLoop\n * @method _update\n */\n p5.SoundLoop.prototype._update = function() {\n this.clock.frequency.value = this._calcFreq();\n };\n\n /**\n * Calculate the frequency of the clock's callback based on bpm, interval, and timesignature\n * @private\n * @for p5.SoundLoop\n * @method _calcFreq\n * @return {Number} new clock frequency value\n */\n p5.SoundLoop.prototype._calcFreq = function() {\n //Seconds mode, bpm / timesignature has no effect\n if (typeof this._interval === 'number') {\n this.musicalTimeMode = false;\n return 1 / this._interval;\n }\n //Musical timing mode, calculate interval based bpm, interval,and time signature\n else if (typeof this._interval === 'string') {\n this.musicalTimeMode = true;\n return this._bpm / 60 / this._convertNotation(this._interval) * (this._timeSignature / 4);\n }\n };\n\n /**\n * Convert notation from musical time format to seconds\n * Uses Tone.Time convention\n * @private\n * @for p5.SoundLoop\n * @method _convertNotation\n * @param {String} value value to be converted\n * @return {Number} converted value in seconds\n */\n p5.SoundLoop.prototype._convertNotation = function(value) {\n var type = value.slice(-1);\n value = Number(value.slice(0,-1));\n switch (type) {\n case 'm':\n return this._measure(value);\n case 'n':\n return this._note(value);\n default:\n console.warn('Specified interval is not formatted correctly. See Tone.js '+\n 'timing reference for more info: https://github.com/Tonejs/Tone.js/wiki/Time');\n }\n };\n\n /**\n * Helper conversion methods of measure and note\n * @private\n * @for p5.SoundLoop\n * @method _measure\n */\n p5.SoundLoop.prototype._measure = function(value) {\n return value * this._timeSignature;\n };\n\n /**\n * @private\n * @method _note\n * @for p5.SoundLoop\n */\n p5.SoundLoop.prototype._note = function(value) {\n return this._timeSignature / value ;\n };\n\n\n /**\n * Getters and Setters, setting any paramter will result in a change in the clock's\n * frequency, that will be reflected after the next callback\n * beats per minute (defaults to 60)\n * @property {Number} bpm\n * @for p5.SoundLoop\n */\n Object.defineProperty(p5.SoundLoop.prototype, 'bpm', {\n get : function() {\n return this._bpm;\n },\n set : function(bpm) {\n if (!this.musicalTimeMode) {\n console.warn('Changing the BPM in \"seconds\" mode has no effect. '+\n 'BPM is only relevant in musicalTimeMode '+\n 'when the interval is specified as a string '+\n '(\"2n\", \"4n\", \"1m\"...etc)');\n }\n this._bpm = bpm;\n this._update();\n }\n });\n\n /**\n * number of quarter notes in a measure (defaults to 4)\n * @property {Number} timeSignature\n * @for p5.SoundLoop\n */\n Object.defineProperty(p5.SoundLoop.prototype, 'timeSignature', {\n get : function() {\n return this._timeSignature;\n },\n set : function(timeSig) {\n if (!this.musicalTimeMode) {\n console.warn('Changing the timeSignature in \"seconds\" mode has no effect. '+\n 'BPM is only relevant in musicalTimeMode '+\n 'when the interval is specified as a string '+\n '(\"2n\", \"4n\", \"1m\"...etc)');\n }\n this._timeSignature = timeSig;\n this._update();\n }\n });\n\n /**\n * length of the loops interval\n * @property {Number|String} interval\n * @for p5.SoundLoop\n */\n Object.defineProperty(p5.SoundLoop.prototype, 'interval', {\n get : function() {\n return this._interval;\n },\n set : function(interval) {\n this.musicalTimeMode = typeof interval === 'Number'? false : true;\n this._interval = interval;\n this._update();\n }\n });\n\n /**\n * how many times the callback has been called so far\n * @property {Number} iterations\n * @for p5.SoundLoop\n * @readonly\n */\n Object.defineProperty(p5.SoundLoop.prototype, 'iterations', {\n get : function() {\n return this.clock.ticks;\n }\n });\n\n return p5.SoundLoop;\n});\n","define(function (require) {\n\t'use strict';\n\n\tvar p5sound = require('master');\n\tvar Effect = require('effect');\n var CustomError = require('errorHandler');\n\n /**\n * Compressor is an audio effect class that performs dynamics compression\n * on an audio input source. This is a very commonly used technique in music\n * and sound production. Compression creates an overall louder, richer,\n * and fuller sound by lowering the volume of louds and raising that of softs.\n * Compression can be used to avoid clipping (sound distortion due to\n * peaks in volume) and is especially useful when many sounds are played\n * at once. Compression can be used on indivudal sound sources in addition\n * to the master output.\n *\n * This class extends p5.Effect.\n * Methods amp(), chain(),\n * drywet(), connect(), and\n * disconnect() are available.\n *\n * @class p5.Compressor\n * @constructor\n * @extends p5.Effect\n *\n *\n */\n\tp5.Compressor = function() {\n\t\tEffect.call(this);\n\n /**\n * The p5.Compressor is built with a Web Audio Dynamics Compressor Node\n * \n * @property {AudioNode} compressor\n */\n\n\n\t\tthis.compressor = this.ac.createDynamicsCompressor();\n\n this.input.connect(this.compressor);\n this.compressor.connect(this.wet);\n\t};\n\n\tp5.Compressor.prototype = Object.create(Effect.prototype);\n\n /**\n * Performs the same function as .connect, but also accepts\n * optional parameters to set compressor's audioParams\n * @method process\n * @for p5.Compressor\n *\n * @param {Object} src Sound source to be connected\n *\n * @param {Number} [attack] The amount of time (in seconds) to reduce the gain by 10dB,\n * default = .003, range 0 - 1\n * @param {Number} [knee] A decibel value representing the range above the\n * threshold where the curve smoothly transitions to the \"ratio\" portion.\n * default = 30, range 0 - 40\n * @param {Number} [ratio] The amount of dB change in input for a 1 dB change in output\n * default = 12, range 1 - 20\n * @param {Number} [threshold] The decibel value above which the compression will start taking effect\n * default = -24, range -100 - 0\n * @param {Number} [release] The amount of time (in seconds) to increase the gain by 10dB\n * default = .25, range 0 - 1\n */\n\tp5.Compressor.prototype.process = function(src, attack, knee,\n ratio, threshold, release) {\n\t\tsrc.connect(this.input);\n\t\tthis.set(attack, knee, ratio, threshold, release);\n\t};\n\n /**\n * Set the paramters of a compressor.\n * @method set\n * @for p5.Compressor\n * @param {Number} attack The amount of time (in seconds) to reduce the gain by 10dB,\n * default = .003, range 0 - 1\n * @param {Number} knee A decibel value representing the range above the\n * threshold where the curve smoothly transitions to the \"ratio\" portion.\n * default = 30, range 0 - 40\n * @param {Number} ratio The amount of dB change in input for a 1 dB change in output\n * default = 12, range 1 - 20\n * @param {Number} threshold The decibel value above which the compression will start taking effect\n * default = -24, range -100 - 0\n * @param {Number} release The amount of time (in seconds) to increase the gain by 10dB\n * default = .25, range 0 - 1\n */\n p5.Compressor.prototype.set = function (attack, knee,\n ratio, threshold, release) {\n\n if (typeof attack !== 'undefined') {this.attack(attack);}\n if (typeof knee !== 'undefined') {this.knee(knee);}\n if (typeof ratio !== 'undefined') {this.ratio(ratio);}\n if (typeof threshold !== 'undefined') {this.threshold(threshold);}\n if (typeof release !== 'undefined') {this.release(release);}\n };\n\n\n /**\n * Get current attack or set value w/ time ramp\n *\n *\n * @method attack\n * @for p5.Compressor\n * @param {Number} [attack] Attack is the amount of time (in seconds) to reduce the gain by 10dB,\n * default = .003, range 0 - 1\n * @param {Number} [time] Assign time value to schedule the change in value\n */\n p5.Compressor.prototype.attack = function (attack, time){\n var t = time || 0;\n if (typeof attack == 'number'){\n this.compressor.attack.value = attack;\n this.compressor.attack.cancelScheduledValues(this.ac.currentTime + 0.01 + t);\n this.compressor.attack.linearRampToValueAtTime(attack, this.ac.currentTime + 0.02 + t);\n } else if (typeof attack !== 'undefined') {\n attack.connect(this.compressor.attack);\n }\n return this.compressor.attack.value;\n };\n\n\n /**\n * Get current knee or set value w/ time ramp\n *\n * @method knee\n * @for p5.Compressor\n * @param {Number} [knee] A decibel value representing the range above the\n * threshold where the curve smoothly transitions to the \"ratio\" portion.\n * default = 30, range 0 - 40\n * @param {Number} [time] Assign time value to schedule the change in value\n */\n p5.Compressor.prototype.knee = function (knee, time){\n var t = time || 0;\n if (typeof knee == 'number'){\n this.compressor.knee.value = knee;\n this.compressor.knee.cancelScheduledValues(this.ac.currentTime + 0.01 + t);\n this.compressor.knee.linearRampToValueAtTime(knee, this.ac.currentTime + 0.02 + t);\n } else if (typeof knee !== 'undefined') {\n knee.connect(this.compressor.knee);\n }\n return this.compressor.knee.value;\n };\n\n\n /**\n * Get current ratio or set value w/ time ramp\n * @method ratio\n * @for p5.Compressor\n * @param {Number} [ratio] The amount of dB change in input for a 1 dB change in output\n * default = 12, range 1 - 20\n * @param {Number} [time] Assign time value to schedule the change in value\n */\n p5.Compressor.prototype.ratio = function (ratio, time){\n var t = time || 0;\n if (typeof ratio == 'number'){\n this.compressor.ratio.value = ratio;\n this.compressor.ratio.cancelScheduledValues(this.ac.currentTime + 0.01 + t);\n this.compressor.ratio.linearRampToValueAtTime(ratio, this.ac.currentTime + 0.02 + t);\n } else if (typeof ratio !== 'undefined') {\n ratio.connect(this.compressor.ratio);\n }\n return this.compressor.ratio.value;\n };\n\n\n /**\n * Get current threshold or set value w/ time ramp\n * @method threshold\n * @for p5.Compressor\n * @param {Number} threshold The decibel value above which the compression will start taking effect\n * default = -24, range -100 - 0\n * @param {Number} [time] Assign time value to schedule the change in value\n */\n p5.Compressor.prototype.threshold = function (threshold, time){\n var t = time || 0;\n if (typeof threshold == 'number'){\n this.compressor.threshold.value = threshold;\n this.compressor.threshold.cancelScheduledValues(this.ac.currentTime + 0.01 + t);\n this.compressor.threshold.linearRampToValueAtTime(threshold, this.ac.currentTime + 0.02 + t);\n } else if (typeof threshold !== 'undefined') {\n threshold.connect(this.compressor.threshold);\n }\n return this.compressor.threshold.value;\n };\n\n\n /**\n * Get current release or set value w/ time ramp\n * @method release\n * @for p5.Compressor\n * @param {Number} release The amount of time (in seconds) to increase the gain by 10dB\n * default = .25, range 0 - 1\n *\n * @param {Number} [time] Assign time value to schedule the change in value\n */\n p5.Compressor.prototype.release = function (release, time){\n var t = time || 0;\n if (typeof release == 'number'){\n this.compressor.release.value = release;\n this.compressor.release.cancelScheduledValues(this.ac.currentTime + 0.01 + t);\n this.compressor.release.linearRampToValueAtTime(release, this.ac.currentTime + 0.02 + t);\n } else if (typeof number !== 'undefined') {\n release.connect(this.compressor.release);\n }\n return this.compressor.release.value;\n };\n\n /**\n * Return the current reduction value\n *\n * @method reduction\n * @for p5.Compressor\n * @return {Number} Value of the amount of gain reduction that is applied to the signal\n */\n p5.Compressor.prototype.reduction =function() {\n return this.compressor.reduction.value;\n };\n\n\n\tp5.Compressor.prototype.dispose = function() {\n Effect.prototype.dispose.apply(this);\n if (this.compressor) {\n this.compressor.disconnect();\n delete this.compressor;\n }\n\t};\n\n return p5.Compressor;\n});\n","'use strict';\n\ndefine(function (require) {\n\n // inspiration: recorder.js, Tone.js & typedarray.org\n\n var p5sound = require('master');\n var convertToWav = require('helpers').convertToWav;\n var processorNames = require('./audioWorklet/processorNames');\n var ac = p5sound.audiocontext;\n\n /**\n *
Record sounds for playback and/or to save as a .wav file.\n * The p5.SoundRecorder records all sound output from your sketch,\n * or can be assigned a specific source with setInput().
\n *
The record() method accepts a p5.SoundFile as a parameter.\n * When playback is stopped (either after the given amount of time,\n * or with the stop() method), the p5.SoundRecorder will send its\n * recording to that p5.SoundFile for playback.
\n * var mic, recorder, soundFile;\n * var state = 0;\n *\n * function setup() {\n * background(200);\n * // create an audio in\n * mic = new p5.AudioIn();\n *\n * // prompts user to enable their browser mic\n * mic.start();\n *\n * // create a sound recorder\n * recorder = new p5.SoundRecorder();\n *\n * // connect the mic to the recorder\n * recorder.setInput(mic);\n *\n * // this sound file will be used to\n * // playback & save the recording\n * soundFile = new p5.SoundFile();\n *\n * text('keyPress to record', 20, 20);\n * }\n *\n * function keyPressed() {\n * // make sure user enabled the mic\n * if (state === 0 && mic.enabled) {\n *\n * // record to our p5.SoundFile\n * recorder.record(soundFile);\n *\n * background(255,0,0);\n * text('Recording!', 20, 20);\n * state++;\n * }\n * else if (state === 1) {\n * background(0,255,0);\n *\n * // stop recorder and\n * // send result to soundFile\n * recorder.stop();\n *\n * text('Stopped', 20, 20);\n * state++;\n * }\n *\n * else if (state === 2) {\n * soundFile.play(); // play the result!\n * save(soundFile, 'mySound.wav');\n * state++;\n * }\n * }\n *
\n */\n p5.SoundRecorder = function() {\n this.input = ac.createGain();\n this.output = ac.createGain();\n\n this._inputChannels = 2;\n this._outputChannels = 2; // stereo output, even if input is mono\n\n this._workletNode = new AudioWorkletNode(ac, processorNames.recorderProcessor, {\n outputChannelCount: [this._outputChannels],\n processorOptions: { numInputChannels: this._inputChannels }\n });\n\n this._workletNode.port.onmessage = function(event) {\n if (event.data.name === 'buffers') {\n const buffers = [\n new Float32Array(event.data.leftBuffer),\n new Float32Array(event.data.rightBuffer)\n ];\n this._callback(buffers);\n }\n }.bind(this);\n\n /**\n * callback invoked when the recording is over\n * @private\n * @type Function(Float32Array)\n */\n this._callback = function() {};\n\n // connections\n this._workletNode.connect(p5.soundOut._silentNode);\n this.setInput();\n\n // add this p5.SoundFile to the soundArray\n p5sound.soundArray.push(this);\n };\n\n /**\n * Connect a specific device to the p5.SoundRecorder.\n * If no parameter is given, p5.SoundRecorer will record\n * all audible p5.sound from your sketch.\n *\n * @method setInput\n * @for p5.SoundRecorder\n * @param {Object} [unit] p5.sound object or a web audio unit\n * that outputs sound\n */\n p5.SoundRecorder.prototype.setInput = function(unit) {\n this.input.disconnect();\n this.input = null;\n this.input = ac.createGain();\n this.input.connect(this._workletNode);\n this.input.connect(this.output);\n if (unit) {\n unit.connect(this.input);\n } else {\n p5.soundOut.output.connect(this.input);\n }\n };\n\n /**\n * Start recording. To access the recording, provide\n * a p5.SoundFile as the first parameter. The p5.SoundRecorder\n * will send its recording to that p5.SoundFile for playback once\n * recording is complete. Optional parameters include duration\n * (in seconds) of the recording, and a callback function that\n * will be called once the complete recording has been\n * transfered to the p5.SoundFile.\n *\n * @method record\n * @for p5.SoundRecorder\n * @param {p5.SoundFile} soundFile p5.SoundFile\n * @param {Number} [duration] Time (in seconds)\n * @param {Function} [callback] The name of a function that will be\n * called once the recording completes\n */\n p5.SoundRecorder.prototype.record = function(sFile, duration, callback) {\n this._workletNode.port.postMessage({ name: 'start', duration: duration });\n\n if (sFile && callback) {\n this._callback = function(buffer) {\n sFile.setBuffer(buffer);\n callback();\n };\n }\n else if (sFile) {\n this._callback = function(buffer) {\n sFile.setBuffer(buffer);\n };\n }\n };\n\n /**\n * Stop the recording. Once the recording is stopped,\n * the results will be sent to the p5.SoundFile that\n * was given on .record(), and if a callback function\n * was provided on record, that function will be called.\n *\n * @method stop\n * @for p5.SoundRecorder\n */\n p5.SoundRecorder.prototype.stop = function() {\n this._workletNode.port.postMessage({ name: 'stop' });\n };\n\n p5.SoundRecorder.prototype.dispose = function() {\n // remove reference from soundArray\n var index = p5sound.soundArray.indexOf(this);\n p5sound.soundArray.splice(index, 1);\n\n this._callback = function() {};\n if (this.input) {\n this.input.disconnect();\n }\n this.input = null;\n this._workletNode = null;\n };\n\n\n /**\n * Save a p5.SoundFile as a .wav file. The browser will prompt the user\n * to download the file to their device.\n * For uploading audio to a server, use\n * `p5.SoundFile.saveBlob`.\n *\n * @for p5\n * @method saveSound\n * @param {p5.SoundFile} soundFile p5.SoundFile that you wish to save\n * @param {String} fileName name of the resulting .wav file.\n */\n // add to p5.prototype as this is used by the p5 `save()` method.\n p5.prototype.saveSound = function (soundFile, fileName) {\n const dataView = convertToWav(soundFile.buffer);\n p5.prototype.writeFile([dataView], fileName, 'wav');\n };\n});\n","'use strict';\n\ndefine(function () {\n /**\n *
PeakDetect works in conjunction with p5.FFT to\n * look for onsets in some or all of the frequency spectrum.\n *
\n *
\n * To use p5.PeakDetect, call update in the draw loop\n * and pass in a p5.FFT object.\n *
\n *
\n * You can listen for a specific part of the frequency spectrum by\n * setting the range between freq1 and freq2.\n *
\n *\n *
threshold is the threshold for detecting a peak,\n * scaled between 0 and 1. It is logarithmic, so 0.1 is half as loud\n * as 1.0.
\n *\n *
\n * The update method is meant to be run in the draw loop, and\n * frames determines how many loops must pass before\n * another peak can be detected.\n * For example, if the frameRate() = 60, you could detect the beat of a\n * 120 beat-per-minute song with this equation:\n * framesPerPeak = 60 / (estimatedBPM / 60 );\n *
\n *\n *
\n * Based on example contribtued by @b2renger, and a simple beat detection\n * explanation by Felix Turner.\n *
\n *\n * @class p5.PeakDetect\n * @constructor\n * @param {Number} [freq1] lowFrequency - defaults to 20Hz\n * @param {Number} [freq2] highFrequency - defaults to 20000 Hz\n * @param {Number} [threshold] Threshold for detecting a beat between 0 and 1\n * scaled logarithmically where 0.1 is 1/2 the loudness\n * of 1.0. Defaults to 0.35.\n * @param {Number} [framesPerPeak] Defaults to 20.\n * @example\n *
\n */\n p5.PeakDetect = function(freq1, freq2, threshold, _framesPerPeak) {\n // framesPerPeak determines how often to look for a beat.\n // If a beat is provided, try to look for a beat based on bpm\n this.framesPerPeak = _framesPerPeak || 20;\n this.framesSinceLastPeak = 0;\n this.decayRate = 0.95;\n\n this.threshold = threshold || 0.35;\n this.cutoff = 0;\n\n // how much to increase the cutoff\n // TO DO: document this / figure out how to make it accessible\n this.cutoffMult = 1.5;\n\n this.energy = 0;\n this.penergy = 0;\n\n // TO DO: document this property / figure out how to make it accessible\n this.currentValue = 0;\n\n /**\n * isDetected is set to true when a peak is detected.\n *\n * @attribute isDetected {Boolean}\n * @default false\n */\n this.isDetected = false;\n\n this.f1 = freq1 || 40;\n this.f2 = freq2 || 20000;\n\n // function to call when a peak is detected\n this._onPeak = function() {};\n };\n\n\n /**\n * The update method is run in the draw loop.\n *\n * Accepts an FFT object. You must call .analyze()\n * on the FFT object prior to updating the peakDetect\n * because it relies on a completed FFT analysis.\n *\n * @method update\n * @param {p5.FFT} fftObject A p5.FFT object\n */\n p5.PeakDetect.prototype.update = function(fftObject) {\n var nrg = this.energy = fftObject.getEnergy(this.f1,this.f2)/255;\n if (nrg > this.cutoff && nrg > this.threshold && nrg-this.penergy > 0) {\n\n // trigger callback\n this._onPeak();\n this.isDetected = true;\n\n // debounce\n this.cutoff = nrg * this.cutoffMult;\n this.framesSinceLastPeak = 0;\n } else {\n this.isDetected = false;\n if (this.framesSinceLastPeak <= this.framesPerPeak) {\n this.framesSinceLastPeak++;\n } else {\n this.cutoff *= this.decayRate;\n this.cutoff = Math.max(this.cutoff, this.threshold);\n }\n }\n\n this.currentValue = nrg;\n this.penergy = nrg;\n };\n\n /**\n * onPeak accepts two arguments: a function to call when\n * a peak is detected. The value of the peak,\n * between 0.0 and 1.0, is passed to the callback.\n *\n * @method onPeak\n * @param {Function} callback Name of a function that will\n * be called when a peak is\n * detected.\n * @param {Object} [val] Optional value to pass\n * into the function when\n * a peak is detected.\n * @example\n *
\n * var cnv, soundFile, fft, peakDetect;\n * var ellipseWidth = 0;\n *\n * function preload() {\n * soundFile = loadSound('assets/beat.mp3');\n * }\n *\n * function setup() {\n * cnv = createCanvas(100,100);\n * textAlign(CENTER);\n *\n * fft = new p5.FFT();\n * peakDetect = new p5.PeakDetect();\n *\n * setupSound();\n *\n * // when a beat is detected, call triggerBeat()\n * peakDetect.onPeak(triggerBeat);\n * }\n *\n * function draw() {\n * background(0);\n * fill(255);\n * text('click to play', width/2, height/2);\n *\n * fft.analyze();\n * peakDetect.update(fft);\n *\n * ellipseWidth *= 0.95;\n * ellipse(width/2, height/2, ellipseWidth, ellipseWidth);\n * }\n *\n * // this function is called by peakDetect.onPeak\n * function triggerBeat() {\n * ellipseWidth = 50;\n * }\n *\n * // mouseclick starts/stops sound\n * function setupSound() {\n * cnv.mouseClicked( function() {\n * if (soundFile.isPlaying() ) {\n * soundFile.stop();\n * } else {\n * soundFile.play();\n * }\n * });\n * }\n *
\n */\n p5.PeakDetect.prototype.onPeak = function(callback, val) {\n var self = this;\n\n self._onPeak = function() {\n callback(self.energy, val);\n };\n };\n\n});\n","'use strict';\n\ndefine(function (require) {\n var p5sound = require('master');\n\n /**\n * A gain node is usefull to set the relative volume of sound.\n * It's typically used to build mixers.\n *\n * @class p5.Gain\n * @constructor\n * @example\n *
\n *\n * // load two soundfile and crossfade beetween them\n * var sound1,sound2;\n * var gain1, gain2, gain3;\n *\n * function preload(){\n * soundFormats('ogg', 'mp3');\n * sound1 = loadSound('assets/Damscray_-_Dancing_Tiger_01');\n * sound2 = loadSound('assets/beat.mp3');\n * }\n *\n * function setup() {\n * createCanvas(400,200);\n *\n * // create a 'master' gain to which we will connect both soundfiles\n * gain3 = new p5.Gain();\n * gain3.connect();\n *\n * // setup first sound for playing\n * sound1.rate(1);\n * sound1.loop();\n * sound1.disconnect(); // diconnect from p5 output\n *\n * gain1 = new p5.Gain(); // setup a gain node\n * gain1.setInput(sound1); // connect the first sound to its input\n * gain1.connect(gain3); // connect its output to the 'master'\n *\n * sound2.rate(1);\n * sound2.disconnect();\n * sound2.loop();\n *\n * gain2 = new p5.Gain();\n * gain2.setInput(sound2);\n * gain2.connect(gain3);\n *\n * }\n *\n * function draw(){\n * background(180);\n *\n * // calculate the horizontal distance beetween the mouse and the right of the screen\n * var d = dist(mouseX,0,width,0);\n *\n * // map the horizontal position of the mouse to values useable for volume control of sound1\n * var vol1 = map(mouseX,0,width,0,1);\n * var vol2 = 1-vol1; // when sound1 is loud, sound2 is quiet and vice versa\n *\n * gain1.amp(vol1,0.5,0);\n * gain2.amp(vol2,0.5,0);\n *\n * // map the vertical position of the mouse to values useable for 'master volume control'\n * var vol3 = map(mouseY,0,height,0,1);\n * gain3.amp(vol3,0.5,0);\n * }\n *
\n *\n */\n\n p5.Gain = function() {\n this.ac = p5sound.audiocontext;\n\n this.input = this.ac.createGain();\n this.output = this.ac.createGain();\n\n // otherwise, Safari distorts\n this.input.gain.value = 0.5;\n this.input.connect(this.output);\n\n // add to the soundArray\n p5sound.soundArray.push(this);\n };\n\n /**\n * Connect a source to the gain node.\n *\n * @method setInput\n * @for p5.Gain\n * @param {Object} src p5.sound / Web Audio object with a sound\n * output.\n */\n\n\n p5.Gain.prototype.setInput = function(src) {\n src.connect(this.input);\n };\n\n /**\n * Send output to a p5.sound or web audio object\n *\n * @method connect\n * @for p5.Gain\n * @param {Object} unit\n */\n p5.Gain.prototype.connect = function(unit) {\n var u = unit || p5.soundOut.input;\n this.output.connect(u.input ? u.input : u);\n };\n\n /**\n * Disconnect all output.\n *\n * @method disconnect\n * @for p5.Gain\n */\n p5.Gain.prototype.disconnect = function() {\n if (this.output) {\n this.output.disconnect();\n }\n };\n\n /**\n * Set the output level of the gain node.\n *\n * @method amp\n * @for p5.Gain\n * @param {Number} volume amplitude between 0 and 1.0\n * @param {Number} [rampTime] create a fade that lasts rampTime\n * @param {Number} [timeFromNow] schedule this event to happen\n * seconds from now\n */\n p5.Gain.prototype.amp = function(vol, rampTime, tFromNow) {\n var rampTime = rampTime || 0;\n var tFromNow = tFromNow || 0;\n var now = p5sound.audiocontext.currentTime;\n var currentVol = this.output.gain.value;\n this.output.gain.cancelScheduledValues(now);\n this.output.gain.linearRampToValueAtTime(currentVol, now + tFromNow);\n this.output.gain.linearRampToValueAtTime(vol, now + tFromNow + rampTime);\n };\n\n p5.Gain.prototype.dispose = function() {\n // remove reference from soundArray\n var index = p5sound.soundArray.indexOf(this);\n p5sound.soundArray.splice(index, 1);\n if (this.output) {\n this.output.disconnect();\n delete this.output;\n }\n if (this.input) {\n this.input.disconnect();\n delete this.input;\n }\n };\n\n});\n","'use strict';\n\ndefine(function (require) {\n\n var Effect = require('effect');\n\n /*\n * Adapted from [Kevin Ennis on StackOverflow](http://stackoverflow.com/questions/22312841/waveshaper-node-in-webaudio-how-to-emulate-distortion)\n */\n function makeDistortionCurve(amount) {\n var k = typeof amount === 'number' ? amount : 50;\n var numSamples = 44100;\n var curve = new Float32Array(numSamples);\n var deg = Math.PI / 180;\n var i = 0;\n var x;\n for ( ; i < numSamples; ++i ) {\n x = i * 2 / numSamples - 1;\n curve[i] = ( 3 + k ) * x * 20 * deg / ( Math.PI + k * Math.abs(x) );\n }\n return curve;\n }\n\n /**\n * A Distortion effect created with a Waveshaper Node,\n * with an approach adapted from\n * [Kevin Ennis](http://stackoverflow.com/questions/22312841/waveshaper-node-in-webaudio-how-to-emulate-distortion)\n *\n * This class extends p5.Effect.\n * Methods amp(), chain(),\n * drywet(), connect(), and\n * disconnect() are available.\n *\n * @class p5.Distortion\n * @extends p5.Effect\n * @constructor\n * @param {Number} [amount=0.25] Unbounded distortion amount.\n * Normal values range from 0-1.\n * @param {String} [oversample='none'] 'none', '2x', or '4x'.\n *\n */\n p5.Distortion = function(amount, oversample) {\n Effect.call(this);\n\n if (typeof amount === 'undefined') {\n amount = 0.25;\n } if (typeof amount !== 'number') {\n throw new Error('amount must be a number');\n } if (typeof oversample === 'undefined') {\n oversample = '2x';\n } if (typeof oversample !== 'string') {\n throw new Error('oversample must be a String');\n }\n\n var curveAmount = p5.prototype.map(amount, 0.0, 1.0, 0, 2000);\n\n /**\n * The p5.Distortion is built with a\n * \n * Web Audio WaveShaper Node.\n *\n * @property {AudioNode} WaveShaperNode\n */\n this.waveShaperNode = this.ac.createWaveShaper();\n\n this.amount = curveAmount;\n this.waveShaperNode.curve = makeDistortionCurve(curveAmount);\n this.waveShaperNode.oversample = oversample;\n\n this.input.connect(this.waveShaperNode);\n\n this.waveShaperNode.connect(this.wet);\n };\n\n p5.Distortion.prototype = Object.create(Effect.prototype);\n\n\n /**\n * Process a sound source, optionally specify amount and oversample values.\n *\n * @method process\n * @for p5.Distortion\n * @param {Number} [amount=0.25] Unbounded distortion amount.\n * Normal values range from 0-1.\n * @param {String} [oversample='none'] 'none', '2x', or '4x'.\n */\n p5.Distortion.prototype.process = function(src, amount, oversample) {\n src.connect(this.input);\n this.set(amount, oversample);\n };\n\n /**\n * Set the amount and oversample of the waveshaper distortion.\n *\n * @method set\n * @for p5.Distortion\n * @param {Number} [amount=0.25] Unbounded distortion amount.\n * Normal values range from 0-1.\n * @param {String} [oversample='none'] 'none', '2x', or '4x'.\n */\n p5.Distortion.prototype.set = function(amount, oversample) {\n if (amount) {\n var curveAmount = p5.prototype.map(amount, 0.0, 1.0, 0, 2000);\n this.amount = curveAmount;\n this.waveShaperNode.curve = makeDistortionCurve(curveAmount);\n }\n if (oversample) {\n this.waveShaperNode.oversample = oversample;\n }\n };\n\n /**\n * Return the distortion amount, typically between 0-1.\n *\n * @method getAmount\n * @for p5.Distortion\n * @return {Number} Unbounded distortion amount.\n * Normal values range from 0-1.\n */\n p5.Distortion.prototype.getAmount = function() {\n return this.amount;\n };\n\n /**\n * Return the oversampling.\n *\n * @method getOversample\n * @for p5.Distortion\n * @return {String} Oversample can either be 'none', '2x', or '4x'.\n */\n p5.Distortion.prototype.getOversample = function() {\n return this.waveShaperNode.oversample;\n };\n\n\n p5.Distortion.prototype.dispose = function() {\n Effect.prototype.dispose.apply(this);\n if (this.waveShaperNode) {\n this.waveShaperNode.disconnect();\n this.waveShaperNode = null;\n }\n };\n});\n"],"sourceRoot":""}
\ No newline at end of file
+{"version":3,"sources":["webpack:///webpack/bootstrap","webpack:///../node_modules/tone/Tone/core/Tone.js","webpack:///./master.js","webpack:///../node_modules/tone/Tone/signal/Signal.js","webpack:///../node_modules/tone/Tone/signal/Multiply.js","webpack:///./effect.js","webpack:///../node_modules/tone/Tone/signal/WaveShaper.js","webpack:///./helpers.js","webpack:///../node_modules/tone/Tone/signal/Add.js","webpack:///../node_modules/tone/Tone/type/Type.js","webpack:///../node_modules/tone/Tone/core/Gain.js","webpack:///./errorHandler.js","webpack:///../node_modules/tone/Tone/core/Context.js","webpack:///./audioWorklet/processorNames.js","webpack:///../node_modules/tone/Tone/signal/Scale.js","webpack:///../node_modules/tone/Tone/signal/TimelineSignal.js","webpack:///./filter.js","webpack:///../node_modules/tone/Tone/signal/Subtract.js","webpack:///./audiocontext.js","webpack:///../node_modules/tone/Tone/core/Emitter.js","webpack:///../node_modules/tone/Tone/signal/SignalBase.js","webpack:///../node_modules/tone/Tone/type/Time.js","webpack:///../node_modules/tone/Tone/type/TimeBase.js","webpack:///../node_modules/tone/Tone/core/Param.js","webpack:///./oscillator.js","webpack:///../node_modules/tone/Tone/core/Timeline.js","webpack:///../node_modules/tone/Tone/signal/Negate.js","webpack:///../node_modules/tone/Tone/signal/GreaterThanZero.js","webpack:///../node_modules/tone/Tone/core/Clock.js","webpack:///./monosynth.js","webpack:///./audioVoice.js","webpack:///./polysynth.js","webpack:///./app.js","webpack:///../node_modules/audioworklet-polyfill/dist/audioworklet-polyfill.js","webpack:///./shims.js","webpack:///../node_modules/webpack/buildin/global.js","webpack:///../node_modules/startaudiocontext/StartAudioContext.js","webpack:///./audioWorklet/index.js","webpack:///./audioWorklet/recorderProcessor.js","webpack:///./audioWorklet/soundFileProcessor.js","webpack:///./audioWorklet/amplitudeProcessor.js","webpack:///./panner.js","webpack:///./soundfile.js","webpack:///./amplitude.js","webpack:///./fft.js","webpack:///./signal.js","webpack:///../node_modules/tone/Tone/type/Frequency.js","webpack:///../node_modules/tone/Tone/type/TransportTime.js","webpack:///./envelope.js","webpack:///./pulse.js","webpack:///./noise.js","webpack:///./audioin.js","webpack:///../node_modules/tone/Tone/component/CrossFade.js","webpack:///../node_modules/tone/Tone/signal/Expr.js","webpack:///../node_modules/tone/Tone/signal/GreaterThan.js","webpack:///../node_modules/tone/Tone/signal/Abs.js","webpack:///../node_modules/tone/Tone/signal/Modulo.js","webpack:///../node_modules/tone/Tone/signal/Pow.js","webpack:///../node_modules/tone/Tone/signal/AudioToGain.js","webpack:///../node_modules/tone/Tone/signal/EqualPowerGain.js","webpack:///./eq.js","webpack:///./eqFilter.js","webpack:///./panner3d.js","webpack:///./listener3d.js","webpack:///./delay.js","webpack:///./reverb.js","webpack:///./metro.js","webpack:///../node_modules/tone/Tone/core/TimelineState.js","webpack:///./looper.js","webpack:///./soundLoop.js","webpack:///./compressor.js","webpack:///./soundRecorder.js","webpack:///./peakDetect.js","webpack:///./gain.js","webpack:///./distortion.js"],"names":["installedModules","__webpack_require__","moduleId","exports","module","i","l","modules","call","m","c","d","name","getter","o","Object","defineProperty","enumerable","get","r","Symbol","toStringTag","value","t","mode","__esModule","ns","create","key","bind","n","object","property","prototype","hasOwnProperty","p","s","define","Tone","inputs","outputs","this","isUndef","input","context","createGain","Array","output","audioContext","set","params","rampTime","isObject","isString","tmpObj","paramLoop","attr","parent","indexOf","attrSplit","split","length","splice","innerParam","join","param","Signal","Param","rampTo","AudioParam","_collectDefaults","constructor","ret","subRet","j","subAttr","isFunction","constr","defaults","keys","_super","superDefs","push","toString","className","isLetter","match","sameConstructor","isArray","dispose","AudioNode","disconnect","connect","unit","outputNum","inputNum","defaultArg","destination","isNumber","apply","arguments","connectSeries","currentUnit","toUnit","chain","fan","given","fallback","givenProp","fallbackProp","optionsObject","values","options","val","arg","isBoolean","noOp","_readOnly","writable","_writable","State","Started","Stopped","Paused","equalPowerScale","percent","piFactor","Math","PI","sin","dbToGain","db","pow","gainToDb","gain","log","LN10","intervalToFrequencyRatio","interval","now","extend","child","TempConstructor","Context","emit","setContext","ctx","sampleRate","hasAudioContext","window","hasPromises","hasWorkers","version","TONE_SILENCE_VERSION_LOGGING","__WEBPACK_AMD_DEFINE_ARRAY__","__WEBPACK_AMD_DEFINE_RESULT__","undefined","audiocontext","p5sound","limiter","createDynamicsCompressor","threshold","ratio","knee","meter","fftMeter","soundArray","parts","extensions","p5","getMasterVolume","masterVolume","vol","tFromNow","currentTime","currentVol","cancelScheduledValues","linearRampToValueAtTime","soundOut","_silentNode","_gain","_param","getConstant","units","Type","Default","convert","SignalBase","Multiply","createInsOuts","_mult","Gain","require","CrossFade","Effect","ac","_drywet","wet","a","b","amp","drywet","fade","u","index","WaveShaper","mapping","bufferLen","_shaper","createWaveShaper","_curve","curve","isFinite","Float32Array","setMap","len","normalized","oversample","oversampling","RangeError","freqToMidi","f","mathlog2","round","midiToFreq","writeUTFBytes","view","offset","string","lng","setUint8","charCodeAt","soundFormats","toLowerCase","disposeSound","registerMethod","_checkFileFormats","paths","path","extTest","pop","isFileSupported","pathSplit","pathCore","extension","_typeof","_mathChain","math","thisChain","nextChain","type","mathOps","convertToWav","audioBuffer","leftChannel","interleaved","rightChannel","result","inputIndex","interleave","getChannelData","numberOfChannels","buffer","ArrayBuffer","DataView","setUint32","setUint16","setInt16","noteToFreq","note","A","B","C","D","E","F","G","toUpperCase","slice","Add","_sum","Time","Frequency","TransportTime","Ticks","NormalRange","AudioRange","Decibels","Interval","BPM","Positive","Cents","Degrees","MIDI","BarsBeatsSixteenths","Samples","Hertz","Note","Milliseconds","Seconds","Notation","toSeconds","time","TimeBase","toFrequency","freq","valueOf","toTicks","Transport","ticks","GainNode","AudioContext","createGainNode","_gainNode","errorTrace","failedPath","tempStack","splitStack","err","Error","originalStack","stack","filter","ln","toneConnect","outNum","inNum","nativeConnect","e","nativeDisconnect","webkitAudioContext","prop","Emitter","_context","_defineProperty","_latencyHint","_lookAhead","_updateInterval","_computedUpdateInterval","_worker","_createWorker","_constants","mixin","URL","webkitURL","blob","Blob","toFixed","blobUrl","createObjectURL","worker","Worker","addEventListener","_lastUpdate","diff","max","createBuffer","arr","constant","createBufferSource","channelCount","channelCountMode","loop","start","lA","blockTime","postMessage","hint","lookAhead","latencyHint","updateInterval","supported","recorderProcessor","soundFileProcessor","amplitudeProcessor","Scale","outputMin","outputMax","_outputMin","_outputMax","_scale","_add","_setRange","min","TimelineSignal","_events","Timeline","_initial","_fromUnits","Linear","Exponential","Target","Curve","Set","getValueAtTime","_toUnits","convertedVal","setValueAtTime","startTime","add","endTime","exponentialRampToValueAtTime","beforeEvent","_searchBefore","_minOutput","setValue","sampleTime","setTargetAtTime","timeConstant","setValueCurveAtTime","duration","scaling","floats","segmentTime","after","cancel","setRampPoint","before","_searchAfter","linearRampToValueBetween","finish","exponentialRampToValueBetween","getAfter","previouVal","previous","getBefore","_exponentialApproach","_curveInterpolate","_linearInterpolate","_exponentialInterpolate","t0","v0","v1","exp","t1","progress","lowerIndex","floor","upperIndex","ceil","lowerVal","upperVal","Filter","biquad","createBiquadFilter","setType","_on","_untoggledType","process","src","res","frequency","Q","toggle","LowPass","HighPass","BandPass","Subtract","_neg","Negate","global","StartAudioContext","getAudioContext","userStartAudio","elements","callback","elt","Element","map","on","event","events","eventName","off","ev","eventList","args","functions","func","emitterFunc","node","outputNumber","inputNumber","overridden","_plusNow","_unaryExpressions","quantize","regexp","method","rh","nextSubdivision","lh","subdiv","_expr","expr","subdivision","addNow","_defaultExpr","_noOp","copy","toNotation","retNotation","_toNotationHelper","retTripletNotation","testNotations","_notationToUnits","notationTime","multiple","notation","primaryExprs","_primaryExpressions","notationExprs","toBarsBeatsSixteenths","quarterTime","_beatsToUnits","quarters","measures","_timeSignature","sixteenths","parseFloat","PPQ","toSamples","toMilliseconds","_defaultUnits","exprString","_parseExprString","clone","instance","parseInt","_ticksToUnits","hz","_frequencyToUnits","tr","q","total","_secondsToUnits","samples","default","_binaryExpressions","+","precedence","-","*","/","neg","_syntaxGlue","(",")","_tokenize","position","tokens","token","getNextToken","trim","substr","expressions","group","opName","op","reg","SyntaxError","next","peek","_matchGroup","prec","test","_parseBinary","lexer","_parseUnary","_parsePrimary","matching","beats","bpm","seconds","timeSignature","_pushExpr","sub","mult","div","_lfo","lfo","LFO","currentVal","exponentialRampToValue","linearRampToValue","Mult","Oscillator","started","phaseAmount","oscillator","createOscillator","_freqMods","panPosition","connection","panner","Panner","stop","abs","freqNode","getAmp","isNaN","phase","getFreq","getType","oscMods","pan","pval","getPan","osc2","delayAmt","dNode","createDelay","delayTime","sigChain","mathObj","chainSource","num","scale","inMin","inMax","outMin","outMax","mapOutMin","mapOutMax","SinOsc","TriOsc","SawOsc","SqrOsc","_timeline","_toRemove","_iterating","memory","Infinity","_search","remove","shift","cancelBefore","beginning","end","midPoint","nextEvent","_iterate","lowerBound","upperBound","forEach","forEachBefore","forEachAfter","forEachFrom","forEachAtTime","_multiply","GreaterThanZero","_thresh","Clock","_nextTick","_lastState","_state","TimelineState","_boundLoop","_loop","state","setStateAtTime","pause","loopInterval","lag","currentState","tickTime","getStateAtTime","AudioVoice","MonoSynth","env","Envelope","setRange","setExp","setADSR","setInput","play","velocity","secondsFromNow","susTime","triggerAttack","triggerRelease","vel","ramp","attack","decay","sustain","release","defineProperties","aTime","dTime","sPercent","rTime","sustime","PolySynth","audioVoice","maxVoices","audiovoices","notes","_newest","_oldest","_voicesInUse","_allocateVoices","noteAttack","noteRelease","noteADSR","timeFromNow","voice","_note","_velocity","currentVoice","acTime","oldestNote","previousVal","_updateAfter","maxRange","nextTime","p5SOUND","parameters","bufferSize","fill","processor","realm","exec","inputBuffer","outputBuffer","$$processors","$$context","AudioWorkletNode","self","createScriptProcessor","outputChannelCount","Map","properties","defaultValue","MessageChannel","port2","Processor","port","port1","onaudioprocess","$$audioWorklet","AudioWorklet","addModule","fetch","then","ok","status","text","AudioWorkletProcessor","registerProcessor","parameterDescriptors","document","createElement","style","cssText","appendChild","contentWindow","createTextNode","body","$hook","console","documentElement","transpile","String","fixSetTarget","setTargetValueAtTime","createDelayNode","createJavaScriptNode","createPeriodicWave","createWaveTable","internal_createGain","internal_createDelay","maxDelayTime","internal_createBufferSource","internal_start","when","noteGrainOn","noteOn","internal_stop","noteOff","playbackRate","internal_createDynamicsCompressor","reduction","internal_createBiquadFilter","detune","internal_createOscillator","setPeriodicWave","setWaveTable","OfflineAudioContext","webkitOfflineAudioContext","navigator","getUserMedia","webkitGetUserMedia","mozGetUserMedia","msGetUserMedia","el","isSupported","canPlayType","g","Function","__WEBPACK_AMD_DEFINE_FACTORY__","TapListener","element","_dragged","_element","_bindedMove","_moved","_bindedEnd","_ended","isStarted","source","resume","startContext","removeEventListener","promise","Promise","success","checkLoop","requestAnimationFrame","onStarted","tapListeners","bindTapListener","NodeList","querySelectorAll","jquery","toArray","tap","moduleSources","preload","_preloadCount","onWorkletModulesLoad","_decrementPreload","all","moduleSrc","objectURL","audioWorklet","__webpack_exports__","createStereoPanner","stereoPanner","inputChannels","obj","numInputChannels","left","right","channelInterpretation","splitter","createChannelSplitter","createChannelMerger","v","rightVal","cos","leftVal","numChannels","CustomError","processorNames","SoundFile","onload","onerror","whileLoading","url","File","FileReader","FileList","file","_onended","_looping","_playing","_paused","_pauseTime","_cues","_cueIDCounter","_lastPos","_counterNode","_workletNode","bufferSourceNodes","bufferSourceNode","reversed","pauseTime","startMillis","load","_whileLoading","_clearOnEnd","thisBufferSourceNode","target","soundFile","registerPreloadMethod","loadSound","location","origin","cordova","alert","errorCallback","request","XMLHttpRequest","evt","_updateProgress","open","responseType","decodeAudioData","response","buff","msg","statusText","message","send","reader","readAsArrayBuffer","lengthComputable","percentComplete","loaded","isLoaded","rate","_cueStart","cueStart","cueEnd","setVolume","isPlaying","_initSourceNode","_initCounterNode","_arrayIndex","loopStart","loopEnd","playMode","str","pTime","setLoop","bool","isLooping","isPaused","stopAll","_time","_rampTime","_tFromNow","getVolume","reverse","reverseBuffer","setPitch","newPlaybackRate","getPlaybackRate","jump","cueTime","cTime","dur","channels","frames","getPeaks","width","sampleSize","sampleStep","peaks","chan","currentPos","curVol","onended","getLevel","setPath","setBuffer","buf","size","newBuffer","channelNum","_this","cNode","onmessage","data","_onTimeUpdate","audioBuf","arrayBuffer","_createCounterBuffer","processPeaks","_initThreshold","_minThreshold","_minPeaks","bufLen","allPeaks","minThreshold","minPeaks","offlineContext","startRendering","oncomplete","filteredBuffer","renderedBuffer","bufferData","getPeaksAtThreshold","topTempos","intervalCounts","tempoCounts","intervalCount","theoreticalTempo","mapTempo","some","tempoCount","tempo","count","groupNeighborsByTempo","peaksObj","peaksArray","sort","startPeak","endPeak","startPos","sampleIndex","intervals","countIntervalsBetweenNearbyPeaks","intA","intB","tempoPeaks","bpmVariance","peaksAtTopTempo","peak","intervalBPM","peakTime","getPeaksAtTopTempo","Peak","amplitude","tempos","Cue","id","addCue","cue","removeCue","cueLength","clearCues","playbackTime","callbackTime","_prevTime","save","fileName","dataView","saveSound","getBlob","Amplitude","smoothing","processorOptions","normalize","volume","volNorm","stereoVol","stereoVolNorm","channel","toggleNormalize","smooth","FFT","bins","analyser","createAnalyser","fftSize","configurable","smoothingTimeConstant","freqDomain","Uint8Array","frequencyBinCount","timeDomain","bass","lowMid","mid","highMid","treble","waveform","_isSafari","timeToFloat","getFloatTimeDomainData","timeToInt","getByteTimeDomainData","normalArray","scaled","analyze","freqToFloat","getFloatFrequencyData","freqToInt","getByteFrequencyData","getEnergy","frequency1","frequency2","nyquist","swap","lowIndex","highIndex","numFrequencies","freq1","freq2","getCentroid","cumulative_sum","centroid_normalization","mean_freq_index","linAverages","N","spectrum","spectrumLength","spectrumStep","linearAverages","groupIndex","specIndex","logAverages","octaveBands","octaveIndex","hi","getOctaveBands","fCtr0","lastFrequencyBand","lo","ctr","newFrequencyBand","fft","_input","midi","midiToFrequency","pitch","octave","noteNumber","noteToScaleIndex","transpose","harmonize","toMidi","frequencyToMidi","toNote","A4","LN2","scaleIndexToNote","cbb","cb","c#","cx","dbb","d#","dx","ebb","eb","e#","ex","fbb","fb","f#","fx","gbb","gb","g#","gx","abb","ab","a#","ax","bbb","bb","b#","bx","_secondsToTicks","l1","t2","l2","t3","l3","aLevel","dLevel","rLevel","_rampHighPercentage","_rampLowPercentage","control","_init","isExponential","sourceToClear","wasTriggered","_setRampAD","_rampAttackTime","checkExpInput","_rampDecayTime","TCDenominator","_rampAttackTC","_rampDecayTC","setRampPercentages","p1","p2","isExp","lastAttack","valToSet","v2","destination1","destination2","AudioIn","Reverb","Noise","Delay","Env","createDCOffset","bufferSource","Pulse","w","dcOffset","dcGain","mW","sig","SignalAdd","mods","currentFreq","freqMod","assignType","_brownNoise","_pinkNoise","_whiteNoise","whiteBuffer","noiseData","random","b0","b1","b2","b3","b4","b5","b6","pinkBuffer","white","brownBuffer","lastOut","noise","inputSources","stream","mediaStream","currentSource","enabled","MediaStreamTrack","mediaDevices","successCallback","audioSource","constraints","audio","echoCancellation","deviceId","createMediaStreamSource","getTracks","track","getSources","onSuccess","onError","resolve","reject","enumerateDevices","devices","device","kind","error","setSource","active","initialFade","_equalPowerA","EqualPowerGain","_equalPowerB","_invert","Expr","applyBinary","Constructor","_eval","applyUnary","getNumber","literalNumber","_replacements","inputCount","_parseInputs","_nodes","tree","_parseTree","_disposeNodes","_Expressions","signal","glue",",","Abs","mod","modulus","Modulo","Pow","a2g","AudioToGain","binary","unary","!","NOT","inputArray","inputMax","replace","matchSyntax","syn","matchGroup","groupName","parseExpression","parseUnary","operator","parsePrimary","GreaterThan","_gtz","_abs","_subtract","_modSignal","_setWaveShaper","_exp","_expScaler","_expFunc","_norm","x","_eqPower","EQFilter","EQ","_eqsize","factor","bands","_newBand","Panner3D","createPanner","panningModel","distanceModel","xVal","yVal","zVal","positionX","positionY","positionZ","orient","orientX","orientY","orientZ","orientationX","orientationY","orientationZ","setFalloff","maxDistance","rolloffFactor","maxDist","rolloff","Listener3D","listener","xValF","yValF","zValF","xValU","yValU","zValU","orientForward","orientUp","forwardX","forwardY","forwardZ","upX","upY","upZ","_split","_merge","_leftGain","_rightGain","leftDelay","rightDelay","_leftFilter","_rightFilter","_maxDelay","maxValue","feedback","_delayTime","_feedback","_filter","_initConvolverNode","_seconds","_decay","_reverse","_buildImpulse","convolverNode","createConvolver","_teardownConvolverNode","_setBuffer","decayRate","rebuild","impulse","impulseL","impulseR","Convolver","impulses","_loadBuffer","cReverb","chunks","addImpulse","resetImpulse","toggleImpulse","Metro","clock","ontick","syncedParts","prevTick","tatumTime","tickCallback","elapsedTime","thisPart","incrementStep","phrases","thisPhrase","phraseArray","sequence","bNum","metroTicks","looping","setBPM","beatTime","tatums","getBPM","getRate","resetSync","part","pushSync","beatLength","initial","playNextPart","aScore","currentPart","scoreStep","Phrase","phraseStep","Part","steps","bLength","partStep","noLoop","metro","addPhrase","array","removePhrase","getPhrase","replaceSequence","onStep","Score","thisScore","nextPart","resetPart","resetParts","SoundLoop","musicalTimeMode","_interval","_bpm","maxIterations","iterations","_calcFreq","syncedStart","otherLoop","_update","_convertNotation","Number","_measure","timeSig","Compressor","compressor","number","SoundRecorder","_inputChannels","_outputChannels","buffers","leftBuffer","rightBuffer","_callback","record","sFile","writeFile","PeakDetect","_framesPerPeak","framesPerPeak","framesSinceLastPeak","cutoff","cutoffMult","energy","penergy","currentValue","isDetected","f1","f2","_onPeak","update","fftObject","nrg","onPeak","makeDistortionCurve","amount","k","deg","Distortion","curveAmount","waveShaperNode","getAmount","getOversample"],"mappings":"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","file":"p5.sound.min.js","sourcesContent":[" \t// The module cache\n \tvar installedModules = {};\n\n \t// The require function\n \tfunction __webpack_require__(moduleId) {\n\n \t\t// Check if module is in cache\n \t\tif(installedModules[moduleId]) {\n \t\t\treturn installedModules[moduleId].exports;\n \t\t}\n \t\t// Create a new module (and put it into the cache)\n \t\tvar module = installedModules[moduleId] = {\n \t\t\ti: moduleId,\n \t\t\tl: false,\n \t\t\texports: {}\n \t\t};\n\n \t\t// Execute the module function\n \t\tmodules[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n\n \t\t// Flag the module as loaded\n \t\tmodule.l = true;\n\n \t\t// Return the exports of the module\n \t\treturn module.exports;\n \t}\n\n\n \t// expose the modules object (__webpack_modules__)\n \t__webpack_require__.m = modules;\n\n \t// expose the module cache\n \t__webpack_require__.c = installedModules;\n\n \t// define getter function for harmony exports\n \t__webpack_require__.d = function(exports, name, getter) {\n \t\tif(!__webpack_require__.o(exports, name)) {\n \t\t\tObject.defineProperty(exports, name, { enumerable: true, get: getter });\n \t\t}\n \t};\n\n \t// define __esModule on exports\n \t__webpack_require__.r = function(exports) {\n \t\tif(typeof Symbol !== 'undefined' && Symbol.toStringTag) {\n \t\t\tObject.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });\n \t\t}\n \t\tObject.defineProperty(exports, '__esModule', { value: true });\n \t};\n\n \t// create a fake namespace object\n \t// mode & 1: value is a module id, require it\n \t// mode & 2: merge all properties of value into the ns\n \t// mode & 4: return value when already ns object\n \t// mode & 8|1: behave like require\n \t__webpack_require__.t = function(value, mode) {\n \t\tif(mode & 1) value = __webpack_require__(value);\n \t\tif(mode & 8) return value;\n \t\tif((mode & 4) && typeof value === 'object' && value && value.__esModule) return value;\n \t\tvar ns = Object.create(null);\n \t\t__webpack_require__.r(ns);\n \t\tObject.defineProperty(ns, 'default', { enumerable: true, value: value });\n \t\tif(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key));\n \t\treturn ns;\n \t};\n\n \t// getDefaultExport function for compatibility with non-harmony modules\n \t__webpack_require__.n = function(module) {\n \t\tvar getter = module && module.__esModule ?\n \t\t\tfunction getDefault() { return module['default']; } :\n \t\t\tfunction getModuleExports() { return module; };\n \t\t__webpack_require__.d(getter, 'a', getter);\n \t\treturn getter;\n \t};\n\n \t// Object.prototype.hasOwnProperty.call\n \t__webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };\n\n \t// __webpack_public_path__\n \t__webpack_require__.p = \"\";\n\n\n \t// Load entry module and return exports\n \treturn __webpack_require__(__webpack_require__.s = 31);\n","/**\n * Tone.js\n * @author Yotam Mann\n * @license http://opensource.org/licenses/MIT MIT License\n * @copyright 2014-2017 Yotam Mann\n */\ndefine(function(){\n\n\t\"use strict\";\n\n\t///////////////////////////////////////////////////////////////////////////\n\t//\tTONE\n\t///////////////////////////////////////////////////////////////////////////\n\n\t/**\n\t * @class Tone is the base class of all other classes. It provides \n\t * a lot of methods and functionality to all classes that extend\n\t * it. \n\t * \n\t * @constructor\n\t * @alias Tone\n\t * @param {number} [inputs=1] the number of input nodes\n\t * @param {number} [outputs=1] the number of output nodes\n\t */\n\tvar Tone = function(inputs, outputs){\n\n\t\t/**\n\t\t * the input node(s)\n\t\t * @type {GainNode|Array}\n\t\t */\n\t\tif (this.isUndef(inputs) || inputs === 1){\n\t\t\tthis.input = this.context.createGain();\n\t\t} else if (inputs > 1){\n\t\t\tthis.input = new Array(inputs);\n\t\t}\n\n\t\t/**\n\t\t * the output node(s)\n\t\t * @type {GainNode|Array}\n\t\t */\n\t\tif (this.isUndef(outputs) || outputs === 1){\n\t\t\tthis.output = this.context.createGain();\n\t\t} else if (outputs > 1){\n\t\t\tthis.output = new Array(inputs);\n\t\t}\n\t};\n\n\t/**\n\t * Set the parameters at once. Either pass in an\n\t * object mapping parameters to values, or to set a\n\t * single parameter, by passing in a string and value.\n\t * The last argument is an optional ramp time which \n\t * will ramp any signal values to their destination value\n\t * over the duration of the rampTime.\n\t * @param {Object|string} params\n\t * @param {number=} value\n\t * @param {Time=} rampTime\n\t * @returns {Tone} this\n\t * @example\n\t * //set values using an object\n\t * filter.set({\n\t * \t\"frequency\" : 300,\n\t * \t\"type\" : highpass\n\t * });\n\t * @example\n\t * filter.set(\"type\", \"highpass\");\n\t * @example\n\t * //ramp to the value 220 over 3 seconds. \n\t * oscillator.set({\n\t * \t\"frequency\" : 220\n\t * }, 3);\n\t */\n\tTone.prototype.set = function(params, value, rampTime){\n\t\tif (this.isObject(params)){\n\t\t\trampTime = value;\n\t\t} else if (this.isString(params)){\n\t\t\tvar tmpObj = {};\n\t\t\ttmpObj[params] = value;\n\t\t\tparams = tmpObj;\n\t\t}\n\n\t\tparamLoop:\n\t\tfor (var attr in params){\n\t\t\tvalue = params[attr];\n\t\t\tvar parent = this;\n\t\t\tif (attr.indexOf(\".\") !== -1){\n\t\t\t\tvar attrSplit = attr.split(\".\");\n\t\t\t\tfor (var i = 0; i < attrSplit.length - 1; i++){\n\t\t\t\t\tparent = parent[attrSplit[i]];\n\t\t\t\t\tif (parent instanceof Tone) {\n\t\t\t\t\t\tattrSplit.splice(0,i+1);\n\t\t\t\t\t\tvar innerParam = attrSplit.join(\".\");\n\t\t\t\t\t\tparent.set(innerParam, value);\n\t\t\t\t\t\tcontinue paramLoop;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tattr = attrSplit[attrSplit.length - 1];\n\t\t\t}\n\t\t\tvar param = parent[attr];\n\t\t\tif (this.isUndef(param)){\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tif ((Tone.Signal && param instanceof Tone.Signal) || \n\t\t\t\t\t(Tone.Param && param instanceof Tone.Param)){\n\t\t\t\tif (param.value !== value){\n\t\t\t\t\tif (this.isUndef(rampTime)){\n\t\t\t\t\t\tparam.value = value;\n\t\t\t\t\t} else {\n\t\t\t\t\t\tparam.rampTo(value, rampTime);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} else if (param instanceof AudioParam){\n\t\t\t\tif (param.value !== value){\n\t\t\t\t\tparam.value = value;\n\t\t\t\t}\t\t\t\t\n\t\t\t} else if (param instanceof Tone){\n\t\t\t\tparam.set(value);\n\t\t\t} else if (param !== value){\n\t\t\t\tparent[attr] = value;\n\t\t\t}\n\t\t}\n\t\treturn this;\n\t};\n\n\t/**\n\t * Get the object's attributes. Given no arguments get\n\t * will return all available object properties and their corresponding\n\t * values. Pass in a single attribute to retrieve or an array\n\t * of attributes. The attribute strings can also include a \".\"\n\t * to access deeper properties.\n\t * @example\n\t * osc.get();\n\t * //returns {\"type\" : \"sine\", \"frequency\" : 440, ...etc}\n\t * @example\n\t * osc.get(\"type\");\n\t * //returns { \"type\" : \"sine\"}\n\t * @example\n\t * //use dot notation to access deep properties\n\t * synth.get([\"envelope.attack\", \"envelope.release\"]);\n\t * //returns {\"envelope\" : {\"attack\" : 0.2, \"release\" : 0.4}}\n\t * @param {Array=|string|undefined} params the parameters to get, otherwise will return \n\t * \t\t\t\t\t all available.\n\t * @returns {Object}\n\t */\n\tTone.prototype.get = function(params){\n\t\tif (this.isUndef(params)){\n\t\t\tparams = this._collectDefaults(this.constructor);\n\t\t} else if (this.isString(params)){\n\t\t\tparams = [params];\n\t\t} \n\t\tvar ret = {};\n\t\tfor (var i = 0; i < params.length; i++){\n\t\t\tvar attr = params[i];\n\t\t\tvar parent = this;\n\t\t\tvar subRet = ret;\n\t\t\tif (attr.indexOf(\".\") !== -1){\n\t\t\t\tvar attrSplit = attr.split(\".\");\n\t\t\t\tfor (var j = 0; j < attrSplit.length - 1; j++){\n\t\t\t\t\tvar subAttr = attrSplit[j];\n\t\t\t\t\tsubRet[subAttr] = subRet[subAttr] || {};\n\t\t\t\t\tsubRet = subRet[subAttr];\n\t\t\t\t\tparent = parent[subAttr];\n\t\t\t\t}\n\t\t\t\tattr = attrSplit[attrSplit.length - 1];\n\t\t\t}\n\t\t\tvar param = parent[attr];\n\t\t\tif (this.isObject(params[attr])){\n\t\t\t\tsubRet[attr] = param.get();\n\t\t\t} else if (Tone.Signal && param instanceof Tone.Signal){\n\t\t\t\tsubRet[attr] = param.value;\n\t\t\t} else if (Tone.Param && param instanceof Tone.Param){\n\t\t\t\tsubRet[attr] = param.value;\n\t\t\t} else if (param instanceof AudioParam){\n\t\t\t\tsubRet[attr] = param.value;\n\t\t\t} else if (param instanceof Tone){\n\t\t\t\tsubRet[attr] = param.get();\n\t\t\t} else if (!this.isFunction(param) && !this.isUndef(param)){\n\t\t\t\tsubRet[attr] = param;\n\t\t\t} \n\t\t}\n\t\treturn ret;\n\t};\n\n\t/**\n\t * collect all of the default attributes in one\n\t * @private\n\t * @param {function} constr the constructor to find the defaults from\n\t * @return {Array} all of the attributes which belong to the class\n\t */\n\tTone.prototype._collectDefaults = function(constr){\n\t\tvar ret = [];\n\t\tif (!this.isUndef(constr.defaults)){\n\t\t\tret = Object.keys(constr.defaults);\n\t\t}\n\t\tif (!this.isUndef(constr._super)){\n\t\t\tvar superDefs = this._collectDefaults(constr._super);\n\t\t\t//filter out repeats\n\t\t\tfor (var i = 0; i < superDefs.length; i++){\n\t\t\t\tif (ret.indexOf(superDefs[i]) === -1){\n\t\t\t\t\tret.push(superDefs[i]);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\treturn ret;\n\t};\n\n\t/**\n\t * @returns {string} returns the name of the class as a string\n\t */\n\tTone.prototype.toString = function(){\n\t\tfor (var className in Tone){\n\t\t\tvar isLetter = className[0].match(/^[A-Z]$/);\n\t\t\tvar sameConstructor = Tone[className] === this.constructor;\n\t\t\tif (this.isFunction(Tone[className]) && isLetter && sameConstructor){\n\t\t\t\treturn className;\n\t\t\t}\n\t\t}\n\t\treturn \"Tone\";\n\t};\n\n\t///////////////////////////////////////////////////////////////////////////\n\t//\tCLASS VARS\n\t///////////////////////////////////////////////////////////////////////////\n\n\t/**\n\t * The number of inputs feeding into the AudioNode. \n\t * For source nodes, this will be 0.\n\t * @memberOf Tone#\n\t * @name numberOfInputs\n\t * @readOnly\n\t */\n\tObject.defineProperty(Tone.prototype, \"numberOfInputs\", {\n\t\tget : function(){\n\t\t\tif (this.input){\n\t\t\t\tif (this.isArray(this.input)){\n\t\t\t\t\treturn this.input.length;\n\t\t\t\t} else {\n\t\t\t\t\treturn 1;\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\treturn 0;\n\t\t\t}\n\t\t}\n\t});\n\n\t/**\n\t * The number of outputs coming out of the AudioNode. \n\t * For source nodes, this will be 0.\n\t * @memberOf Tone#\n\t * @name numberOfInputs\n\t * @readOnly\n\t */\n\tObject.defineProperty(Tone.prototype, \"numberOfOutputs\", {\n\t\tget : function(){\n\t\t\tif (this.output){\n\t\t\t\tif (this.isArray(this.output)){\n\t\t\t\t\treturn this.output.length;\n\t\t\t\t} else {\n\t\t\t\t\treturn 1;\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\treturn 0;\n\t\t\t}\n\t\t}\n\t});\n\t\n\t///////////////////////////////////////////////////////////////////////////\n\t//\tCONNECTIONS\n\t///////////////////////////////////////////////////////////////////////////\n\n\t/**\n\t * disconnect and dispose\n\t * @returns {Tone} this\n\t */\n\tTone.prototype.dispose = function(){\n\t\tif (!this.isUndef(this.input)){\n\t\t\tif (this.input instanceof AudioNode){\n\t\t\t\tthis.input.disconnect();\n\t\t\t} \n\t\t\tthis.input = null;\n\t\t}\n\t\tif (!this.isUndef(this.output)){\n\t\t\tif (this.output instanceof AudioNode){\n\t\t\t\tthis.output.disconnect();\n\t\t\t} \n\t\t\tthis.output = null;\n\t\t}\n\t\treturn this;\n\t};\n\n\t/**\n\t * connect the output of a ToneNode to an AudioParam, AudioNode, or ToneNode\n\t * @param {Tone | AudioParam | AudioNode} unit \n\t * @param {number} [outputNum=0] optionally which output to connect from\n\t * @param {number} [inputNum=0] optionally which input to connect to\n\t * @returns {Tone} this\n\t */\n\tTone.prototype.connect = function(unit, outputNum, inputNum){\n\t\tif (Array.isArray(this.output)){\n\t\t\toutputNum = this.defaultArg(outputNum, 0);\n\t\t\tthis.output[outputNum].connect(unit, 0, inputNum);\n\t\t} else {\n\t\t\tthis.output.connect(unit, outputNum, inputNum);\n\t\t}\n\t\treturn this;\n\t};\n\n\t/**\n\t * disconnect the output\n\t * @param {Number|AudioNode} output Either the output index to disconnect\n\t * if the output is an array, or the\n\t * node to disconnect from.\n\t * @returns {Tone} this\n\t */\n\tTone.prototype.disconnect = function(destination, outputNum, inputNum){\n\t\tif (this.isArray(this.output)){\n\t\t\tif (this.isNumber(destination)){\n\t\t\t\tthis.output[destination].disconnect();\n\t\t\t} else {\n\t\t\t\toutputNum = this.defaultArg(outputNum, 0);\n\t\t\t\tthis.output[outputNum].disconnect(destination, 0, inputNum);\n\t\t\t}\n\t\t} else {\n\t\t\tthis.output.disconnect.apply(this.output, arguments);\n\t\t}\n\t};\n\n\t/**\n\t * connect together all of the arguments in series\n\t * @param {...AudioParam|Tone|AudioNode} nodes\n\t * @returns {Tone} this\n\t */\n\tTone.prototype.connectSeries = function(){\n\t\tif (arguments.length > 1){\n\t\t\tvar currentUnit = arguments[0];\n\t\t\tfor (var i = 1; i < arguments.length; i++){\n\t\t\t\tvar toUnit = arguments[i];\n\t\t\t\tcurrentUnit.connect(toUnit);\n\t\t\t\tcurrentUnit = toUnit;\n\t\t\t}\n\t\t}\n\t\treturn this;\n\t};\n\n\t/**\n\t * Connect the output of this node to the rest of the nodes in series.\n\t * @example\n\t * //connect a node to an effect, panVol and then to the master output\n\t * node.chain(effect, panVol, Tone.Master);\n\t * @param {...AudioParam|Tone|AudioNode} nodes\n\t * @returns {Tone} this\n\t */\n\tTone.prototype.chain = function(){\n\t\tif (arguments.length > 0){\n\t\t\tvar currentUnit = this;\n\t\t\tfor (var i = 0; i < arguments.length; i++){\n\t\t\t\tvar toUnit = arguments[i];\n\t\t\t\tcurrentUnit.connect(toUnit);\n\t\t\t\tcurrentUnit = toUnit;\n\t\t\t}\n\t\t}\n\t\treturn this;\n\t};\n\n\t/**\n\t * connect the output of this node to the rest of the nodes in parallel.\n\t * @param {...AudioParam|Tone|AudioNode} nodes\n\t * @returns {Tone} this\n\t */\n\tTone.prototype.fan = function(){\n\t\tif (arguments.length > 0){\n\t\t\tfor (var i = 0; i < arguments.length; i++){\n\t\t\t\tthis.connect(arguments[i]);\n\t\t\t}\n\t\t}\n\t\treturn this;\n\t};\n\n\t//give native nodes chain and fan methods\n\tAudioNode.prototype.chain = Tone.prototype.chain;\n\tAudioNode.prototype.fan = Tone.prototype.fan;\n\n\t///////////////////////////////////////////////////////////////////////////\n\t//\tUTILITIES / HELPERS / MATHS\n\t///////////////////////////////////////////////////////////////////////////\n\n\t/**\n\t * If the `given` parameter is undefined, use the `fallback`. \n\t * If both `given` and `fallback` are object literals, it will\n\t * return a deep copy which includes all of the parameters from both \n\t * objects. If a parameter is undefined in given, it will return\n\t * the fallback property. \n\t *
\n\t * WARNING: if object is self referential, it will go into an an \n\t * infinite recursive loop.\n\t * \n\t * @param {*} given \n\t * @param {*} fallback \n\t * @return {*} \n\t */\n\tTone.prototype.defaultArg = function(given, fallback){\n\t\tif (this.isObject(given) && this.isObject(fallback)){\n\t\t\tvar ret = {};\n\t\t\t//make a deep copy of the given object\n\t\t\tfor (var givenProp in given) {\n\t\t\t\tret[givenProp] = this.defaultArg(fallback[givenProp], given[givenProp]);\n\t\t\t}\n\t\t\tfor (var fallbackProp in fallback) {\n\t\t\t\tret[fallbackProp] = this.defaultArg(given[fallbackProp], fallback[fallbackProp]);\n\t\t\t}\n\t\t\treturn ret;\n\t\t} else {\n\t\t\treturn this.isUndef(given) ? fallback : given;\n\t\t}\n\t};\n\n\t/**\n\t * returns the args as an options object with given arguments\n\t * mapped to the names provided. \n\t *\n\t * if the args given is an array containing only one object, it is assumed\n\t * that that's already the options object and will just return it. \n\t * \n\t * @param {Array} values the 'arguments' object of the function\n\t * @param {Array} keys the names of the arguments as they\n\t * should appear in the options object\n\t * @param {Object=} defaults optional defaults to mixin to the returned \n\t * options object \n\t * @return {Object} the options object with the names mapped to the arguments\n\t */\n\tTone.prototype.optionsObject = function(values, keys, defaults){\n\t\tvar options = {};\n\t\tif (values.length === 1 && this.isObject(values[0])){\n\t\t\toptions = values[0];\n\t\t} else {\n\t\t\tfor (var i = 0; i < keys.length; i++){\n\t\t\t\toptions[keys[i]] = values[i];\n\t\t\t}\n\t\t}\n\t\tif (!this.isUndef(defaults)){\n\t\t\treturn this.defaultArg(options, defaults);\n\t\t} else {\n\t\t\treturn options;\n\t\t}\n\t};\n\n\t///////////////////////////////////////////////////////////////////////////\n\t// TYPE CHECKING\n\t///////////////////////////////////////////////////////////////////////////\n\n\t/**\n\t * test if the arg is undefined\n\t * @param {*} arg the argument to test\n\t * @returns {boolean} true if the arg is undefined\n\t * @function\n\t */\n\tTone.prototype.isUndef = function(val){\n\t\treturn typeof val === \"undefined\";\n\t};\n\n\t/**\n\t * test if the arg is a function\n\t * @param {*} arg the argument to test\n\t * @returns {boolean} true if the arg is a function\n\t * @function\n\t */\n\tTone.prototype.isFunction = function(val){\n\t\treturn typeof val === \"function\";\n\t};\n\n\t/**\n\t * Test if the argument is a number.\n\t * @param {*} arg the argument to test\n\t * @returns {boolean} true if the arg is a number\n\t */\n\tTone.prototype.isNumber = function(arg){\n\t\treturn (typeof arg === \"number\");\n\t};\n\n\t/**\n\t * Test if the given argument is an object literal (i.e. `{}`);\n\t * @param {*} arg the argument to test\n\t * @returns {boolean} true if the arg is an object literal.\n\t */\n\tTone.prototype.isObject = function(arg){\n\t\treturn (Object.prototype.toString.call(arg) === \"[object Object]\" && arg.constructor === Object);\n\t};\n\n\t/**\n\t * Test if the argument is a boolean.\n\t * @param {*} arg the argument to test\n\t * @returns {boolean} true if the arg is a boolean\n\t */\n\tTone.prototype.isBoolean = function(arg){\n\t\treturn (typeof arg === \"boolean\");\n\t};\n\n\t/**\n\t * Test if the argument is an Array\n\t * @param {*} arg the argument to test\n\t * @returns {boolean} true if the arg is an array\n\t */\n\tTone.prototype.isArray = function(arg){\n\t\treturn (Array.isArray(arg));\n\t};\n\n\t/**\n\t * Test if the argument is a string.\n\t * @param {*} arg the argument to test\n\t * @returns {boolean} true if the arg is a string\n\t */\n\tTone.prototype.isString = function(arg){\n\t\treturn (typeof arg === \"string\");\n\t};\n\n \t/**\n\t * An empty function.\n\t * @static\n\t */\n\tTone.noOp = function(){};\n\n\t/**\n\t * Make the property not writable. Internal use only. \n\t * @private\n\t * @param {string} property the property to make not writable\n\t */\n\tTone.prototype._readOnly = function(property){\n\t\tif (Array.isArray(property)){\n\t\t\tfor (var i = 0; i < property.length; i++){\n\t\t\t\tthis._readOnly(property[i]);\n\t\t\t}\n\t\t} else {\n\t\t\tObject.defineProperty(this, property, { \n\t\t\t\twritable: false,\n\t\t\t\tenumerable : true,\n\t\t\t});\n\t\t}\n\t};\n\n\t/**\n\t * Make an attribute writeable. Interal use only. \n\t * @private\n\t * @param {string} property the property to make writable\n\t */\n\tTone.prototype._writable = function(property){\n\t\tif (Array.isArray(property)){\n\t\t\tfor (var i = 0; i < property.length; i++){\n\t\t\t\tthis._writable(property[i]);\n\t\t\t}\n\t\t} else {\n\t\t\tObject.defineProperty(this, property, { \n\t\t\t\twritable: true,\n\t\t\t});\n\t\t}\n\t};\n\n\t/**\n\t * Possible play states. \n\t * @enum {string}\n\t */\n\tTone.State = {\n\t\tStarted : \"started\",\n\t\tStopped : \"stopped\",\n\t\tPaused : \"paused\",\n \t};\n\n\t///////////////////////////////////////////////////////////////////////////\n\t// CONVERSIONS\n\t///////////////////////////////////////////////////////////////////////////\n\n\t/**\n\t * Equal power gain scale. Good for cross-fading.\n\t * @param {NormalRange} percent (0-1)\n\t * @return {Number} output gain (0-1)\n\t */\n\tTone.prototype.equalPowerScale = function(percent){\n\t\tvar piFactor = 0.5 * Math.PI;\n\t\treturn Math.sin(percent * piFactor);\n\t};\n\n\t/**\n\t * Convert decibels into gain.\n\t * @param {Decibels} db\n\t * @return {Number} \n\t */\n\tTone.prototype.dbToGain = function(db) {\n\t\treturn Math.pow(2, db / 6);\n\t};\n\n\t/**\n\t * Convert gain to decibels.\n\t * @param {Number} gain (0-1)\n\t * @return {Decibels} \n\t */\n\tTone.prototype.gainToDb = function(gain) {\n\t\treturn 20 * (Math.log(gain) / Math.LN10);\n\t};\n\n\t/**\n\t * Convert an interval (in semitones) to a frequency ratio.\n\t * @param {Interval} interval the number of semitones above the base note\n\t * @return {number} the frequency ratio\n\t * @example\n\t * tone.intervalToFrequencyRatio(0); // 1\n\t * tone.intervalToFrequencyRatio(12); // 2\n\t * tone.intervalToFrequencyRatio(-12); // 0.5\n\t */\n\tTone.prototype.intervalToFrequencyRatio = function(interval){\n\t\treturn Math.pow(2,(interval/12));\n\t};\n\n\t///////////////////////////////////////////////////////////////////////////\n\t//\tTIMING\n\t///////////////////////////////////////////////////////////////////////////\n\n\t/**\n\t * Return the current time of the AudioContext clock.\n\t * @return {Number} the currentTime from the AudioContext\n\t */\n\tTone.prototype.now = function(){\n\t\treturn Tone.context.now();\n\t};\n\n\t/**\n\t * Return the current time of the AudioContext clock.\n\t * @return {Number} the currentTime from the AudioContext\n\t * @static\n\t */\n\tTone.now = function(){\n\t\treturn Tone.context.now();\n\t};\n\n\t///////////////////////////////////////////////////////////////////////////\n\t//\tINHERITANCE\n\t///////////////////////////////////////////////////////////////////////////\n\n\t/**\n\t * have a child inherit all of Tone's (or a parent's) prototype\n\t * to inherit the parent's properties, make sure to call \n\t * Parent.call(this) in the child's constructor\n\t *\n\t * based on closure library's inherit function\n\t *\n\t * @static\n\t * @param {function} \tchild \n\t * @param {function=} parent (optional) parent to inherit from\n\t * if no parent is supplied, the child\n\t * will inherit from Tone\n\t */\n\tTone.extend = function(child, parent){\n\t\tif (Tone.prototype.isUndef(parent)){\n\t\t\tparent = Tone;\n\t\t}\n\t\tfunction TempConstructor(){}\n\t\tTempConstructor.prototype = parent.prototype;\n\t\tchild.prototype = new TempConstructor();\n\t\t/** @override */\n\t\tchild.prototype.constructor = child;\n\t\tchild._super = parent;\n\t};\n\n\t///////////////////////////////////////////////////////////////////////////\n\t//\tCONTEXT\n\t///////////////////////////////////////////////////////////////////////////\n\n\t/**\n\t * The private audio context shared by all Tone Nodes. \n\t * @private\n\t * @type {Tone.Context|undefined}\n\t */\n\tvar audioContext;\n\n\t/**\n\t * A static pointer to the audio context accessible as Tone.context. \n\t * @type {Tone.Context}\n\t * @name context\n\t * @memberOf Tone\n\t */\n\tObject.defineProperty(Tone, \"context\", {\n\t\tget : function(){\n\t\t\treturn audioContext;\n\t\t},\n\t\tset : function(context){\n\t\t\tif (Tone.Context && context instanceof Tone.Context){\n\t\t\t\taudioContext = context;\n\t\t\t} else {\n\t\t\t\taudioContext = new Tone.Context(context);\n\t\t\t}\n\t\t\t//initialize the new audio context\n\t\t\tif (Tone.Context){\n\t\t\t\tTone.Context.emit(\"init\", audioContext);\n\t\t\t}\n\t\t}\n\t});\n\n\t/**\n\t * The AudioContext\n\t * @type {Tone.Context}\n\t * @name context\n\t * @memberOf Tone#\n\t * @readOnly\n\t */\n\tObject.defineProperty(Tone.prototype, \"context\", {\n\t\tget : function(){\n\t\t\treturn Tone.context;\n\t\t}\n\t});\n\n\t/**\n\t * Tone automatically creates a context on init, but if you are working\n\t * with other libraries which also create an AudioContext, it can be\n\t * useful to set your own. If you are going to set your own context, \n\t * be sure to do it at the start of your code, before creating any objects.\n\t * @static\n\t * @param {AudioContext} ctx The new audio context to set\n\t */\n\tTone.setContext = function(ctx){\n\t\tTone.context = ctx;\n\t};\n\n\t/**\n\t * The number of seconds of 1 processing block (128 samples)\n\t * @type {Number}\n\t * @name blockTime\n\t * @memberOf Tone#\n\t * @readOnly\n\t */\n\tObject.defineProperty(Tone.prototype, \"blockTime\", {\n\t\tget : function(){\n\t\t\treturn 128 / this.context.sampleRate;\n\t\t}\n\t});\n\n\t/**\n\t * The duration in seconds of one sample.\n\t * @type {Number}\n\t * @name sampleTime\n\t * @memberOf Tone#\n\t * @readOnly\n\t */\n\tObject.defineProperty(Tone.prototype, \"sampleTime\", {\n\t\tget : function(){\n\t\t\treturn 1 / this.context.sampleRate;\n\t\t}\n\t});\n\n\t/**\n\t * Whether or not all the technologies that Tone.js relies on are supported by the current browser. \n\t * @type {Boolean}\n\t * @name supported\n\t * @memberOf Tone\n\t * @readOnly\n\t */\n\tObject.defineProperty(Tone, \"supported\", {\n\t\tget : function(){\n\t\t\tvar hasAudioContext = window.hasOwnProperty(\"AudioContext\") || window.hasOwnProperty(\"webkitAudioContext\");\n\t\t\tvar hasPromises = window.hasOwnProperty(\"Promise\");\n\t\t\tvar hasWorkers = window.hasOwnProperty(\"Worker\");\n\t\t\treturn hasAudioContext && hasPromises && hasWorkers;\n\t\t}\n\t});\n\n\tTone.version = \"r10\";\n\n\t// allow optional silencing of this log\n\tif (!window.TONE_SILENCE_VERSION_LOGGING) {\n\t\tconsole.log(\"%c * Tone.js \" + Tone.version + \" * \", \"background: #000; color: #fff\");\n\t}\n\n\treturn Tone;\n});\n","'use strict';\n\n\ndefine(['audiocontext'], function (audiocontext) {\n /**\n * Master contains AudioContext and the master sound output.\n * @for p5\n */\n var Master = function() {\n this.input = audiocontext.createGain();\n this.output = audiocontext.createGain();\n\n //put a hard limiter on the output\n this.limiter = audiocontext.createDynamicsCompressor();\n this.limiter.threshold.value = -3;\n this.limiter.ratio.value = 20;\n this.limiter.knee.value = 1;\n\n this.audiocontext = audiocontext;\n\n this.output.disconnect();\n\n // connect input to limiter\n this.input.connect(this.limiter);\n\n // connect limiter to output\n this.limiter.connect(this.output);\n\n // meter is just for global Amplitude / FFT analysis\n this.meter = audiocontext.createGain();\n this.fftMeter = audiocontext.createGain();\n this.output.connect(this.meter);\n this.output.connect(this.fftMeter);\n\n // connect output to destination\n this.output.connect(this.audiocontext.destination);\n\n // an array of all sounds in the sketch\n this.soundArray = [];\n // an array of all musical parts in the sketch\n this.parts = [];\n\n // file extensions to search for\n this.extensions = [];\n };\n\n // create a single instance of the p5Sound / master output for use within this sketch\n var p5sound = new Master();\n\n /**\n * Returns a number representing the master amplitude (volume) for sound\n * in this sketch.\n *\n * @method getMasterVolume\n * @return {Number} Master amplitude (volume) for sound in this sketch.\n * Should be between 0.0 (silence) and 1.0.\n */\n p5.prototype.getMasterVolume = function() {\n return p5sound.output.gain.value;\n };\n\n /**\n *
Scale the output of all sound in this sketch
\n * Scaled between 0.0 (silence) and 1.0 (full volume).\n * 1.0 is the maximum amplitude of a digital sound, so multiplying\n * by greater than 1.0 may cause digital distortion. To\n * fade, provide a rampTime parameter. For more\n * complex fades, see the Envelope class.\n *\n * Alternately, you can pass in a signal source such as an\n * oscillator to modulate the amplitude with an audio signal.\n *\n *
How This Works: When you load the p5.sound module, it\n * creates a single instance of p5sound. All sound objects in this\n * module output to p5sound before reaching your computer's output.\n * So if you change the amplitude of p5sound, it impacts all of the\n * sound in this module.
\n *\n *
If no value is provided, returns a Web Audio API Gain Node
\n *\n * @method masterVolume\n * @param {Number|Object} volume Volume (amplitude) between 0.0\n * and 1.0 or modulating signal/oscillator\n * @param {Number} [rampTime] Fade for t seconds\n * @param {Number} [timeFromNow] Schedule this event to happen at\n * t seconds in the future\n */\n p5.prototype.masterVolume = function(vol, rampTime, tFromNow) {\n if (typeof vol === 'number') {\n var rampTime = rampTime || 0;\n var tFromNow = tFromNow || 0;\n var now = p5sound.audiocontext.currentTime;\n var currentVol = p5sound.output.gain.value;\n p5sound.output.gain.cancelScheduledValues(now + tFromNow);\n p5sound.output.gain.linearRampToValueAtTime(currentVol, now + tFromNow);\n p5sound.output.gain.linearRampToValueAtTime(vol, now + tFromNow + rampTime);\n }\n else if (vol) {\n vol.connect(p5sound.output.gain);\n } else {\n // return the Gain Node\n return p5sound.output.gain;\n }\n };\n\n /**\n * `p5.soundOut` is the p5.sound master output. It sends output to\n * the destination of this window's web audio context. It contains\n * Web Audio API nodes including a dyanmicsCompressor (.limiter),\n * and Gain Nodes for .input and .output.\n *\n * @property {Object} soundOut\n */\n p5.prototype.soundOut = p5.soundOut = p5sound;\n\n /**\n * a silent connection to the DesinationNode\n * which will ensure that anything connected to it\n * will not be garbage collected\n *\n * @private\n */\n p5.soundOut._silentNode = p5sound.audiocontext.createGain();\n p5.soundOut._silentNode.gain.value = 0;\n p5.soundOut._silentNode.connect(p5sound.audiocontext.destination);\n\n\n return p5sound;\n});\n","define([\"Tone/core/Tone\", \"Tone/signal/WaveShaper\", \"Tone/type/Type\", \"Tone/core/Param\", \"Tone/core/Gain\"], function(Tone){\n\n\t\"use strict\";\n\n\t/**\n\t * @class A signal is an audio-rate value. Tone.Signal is a core component of the library.\n\t * Unlike a number, Signals can be scheduled with sample-level accuracy. Tone.Signal\n\t * has all of the methods available to native Web Audio \n\t * [AudioParam](http://webaudio.github.io/web-audio-api/#the-audioparam-interface)\n\t * as well as additional conveniences. Read more about working with signals \n\t * [here](https://github.com/Tonejs/Tone.js/wiki/Signals).\n\t *\n\t * @constructor\n\t * @extends {Tone.Param}\n\t * @param {Number|AudioParam} [value] Initial value of the signal. If an AudioParam\n\t * is passed in, that parameter will be wrapped\n\t * and controlled by the Signal. \n\t * @param {string} [units=Number] unit The units the signal is in. \n\t * @example\n\t * var signal = new Tone.Signal(10);\n\t */\n\tTone.Signal = function(){\n\n\t\tvar options = this.optionsObject(arguments, [\"value\", \"units\"], Tone.Signal.defaults);\n\n\t\t/**\n\t\t * The node where the constant signal value is scaled.\n\t\t * @type {GainNode}\n\t\t * @private\n\t\t */\n\t\tthis.output = this._gain = this.context.createGain();\n\n\t\toptions.param = this._gain.gain;\n\t\tTone.Param.call(this, options);\n\n\t\t/**\n\t\t * The node where the value is set.\n\t\t * @type {Tone.Param}\n\t\t * @private\n\t\t */\n\t\tthis.input = this._param = this._gain.gain;\n\n\t\t//connect the const output to the node output\n\t\tthis.context.getConstant(1).chain(this._gain);\n\t};\n\n\tTone.extend(Tone.Signal, Tone.Param);\n\n\t/**\n\t * The default values\n\t * @type {Object}\n\t * @static\n\t * @const\n\t */\n\tTone.Signal.defaults = {\n\t\t\"value\" : 0,\n\t\t\"units\" : Tone.Type.Default,\n\t\t\"convert\" : true,\n\t};\n\n\t/**\n\t * When signals connect to other signals or AudioParams, \n\t * they take over the output value of that signal or AudioParam. \n\t * For all other nodes, the behavior is the same as a default connect. \n\t *\n\t * @override\n\t * @param {AudioParam|AudioNode|Tone.Signal|Tone} node \n\t * @param {number} [outputNumber=0] The output number to connect from.\n\t * @param {number} [inputNumber=0] The input number to connect to.\n\t * @returns {Tone.SignalBase} this\n\t * @method\n\t */\n\tTone.Signal.prototype.connect = Tone.SignalBase.prototype.connect;\n\n\t/**\n\t * dispose and disconnect\n\t * @returns {Tone.Signal} this\n\t */\n\tTone.Signal.prototype.dispose = function(){\n\t\tTone.Param.prototype.dispose.call(this);\n\t\tthis._param = null;\n\t\tthis._gain.disconnect();\n\t\tthis._gain = null;\n\t\treturn this;\n\t};\n\n\treturn Tone.Signal;\n});","define([\"Tone/core/Tone\", \"Tone/signal/Signal\", \"Tone/core/Gain\"], function(Tone){\n\n\t\"use strict\";\n\n\t/**\n\t * @class Multiply two incoming signals. Or, if a number is given in the constructor, \n\t * multiplies the incoming signal by that value. \n\t *\n\t * @constructor\n\t * @extends {Tone.Signal}\n\t * @param {number=} value Constant value to multiple. If no value is provided,\n\t * it will return the product of the first and second inputs\n\t * @example\n\t * var mult = new Tone.Multiply();\n\t * var sigA = new Tone.Signal(3);\n\t * var sigB = new Tone.Signal(4);\n\t * sigA.connect(mult, 0, 0);\n\t * sigB.connect(mult, 0, 1);\n\t * //output of mult is 12.\n\t * @example\n\t * var mult = new Tone.Multiply(10);\n\t * var sig = new Tone.Signal(2).connect(mult);\n\t * //the output of mult is 20. \n\t */\n\tTone.Multiply = function(value){\n\n\t\tthis.createInsOuts(2, 0);\n\n\t\t/**\n\t\t * the input node is the same as the output node\n\t\t * it is also the GainNode which handles the scaling of incoming signal\n\t\t * \n\t\t * @type {GainNode}\n\t\t * @private\n\t\t */\n\t\tthis._mult = this.input[0] = this.output = new Tone.Gain();\n\n\t\t/**\n\t\t * the scaling parameter\n\t\t * @type {AudioParam}\n\t\t * @private\n\t\t */\n\t\tthis._param = this.input[1] = this.output.gain;\n\t\t\n\t\tthis._param.value = this.defaultArg(value, 0);\n\t};\n\n\tTone.extend(Tone.Multiply, Tone.Signal);\n\n\t/**\n\t * clean up\n\t * @returns {Tone.Multiply} this\n\t */\n\tTone.Multiply.prototype.dispose = function(){\n\t\tTone.prototype.dispose.call(this);\n\t\tthis._mult.dispose();\n\t\tthis._mult = null;\n\t\tthis._param = null;\n\t\treturn this;\n\t}; \n\n\treturn Tone.Multiply;\n});\n","'use strict';\ndefine(function (require) {\n\n var p5sound = require('master');\n var CrossFade = require('Tone/component/CrossFade');\n\n /**\n * Effect is a base class for audio effects in p5. \n * This module handles the nodes and methods that are\n * common and useful for current and future effects.\n *\n *\n * This class is extended by p5.Distortion,\n * p5.Compressor,\n * p5.Delay,\n * p5.Filter,\n * p5.Reverb.\n *\n * @class p5.Effect\n * @constructor\n *\n * @param {Object} [ac] Reference to the audio context of the p5 object\n * @param {AudioNode} [input] Gain Node effect wrapper\n * @param {AudioNode} [output] Gain Node effect wrapper\n * @param {Object} [_drywet] Tone.JS CrossFade node (defaults to value: 1)\n * @param {AudioNode} [wet] Effects that extend this class should connect\n * to the wet signal to this gain node, so that dry and wet\n * signals are mixed properly.\n */\n p5.Effect = function() {\n this.ac = p5sound.audiocontext;\n\n this.input = this.ac.createGain();\n this.output = this.ac.createGain();\n\n /**\n *\tThe p5.Effect class is built\n * \tusing Tone.js CrossFade\n * \t@private\n */\n\n this._drywet = new CrossFade(1);\n\n /**\n *\tIn classes that extend\n *\tp5.Effect, connect effect nodes\n *\tto the wet parameter\n */\n this.wet = this.ac.createGain();\n\n this.input.connect(this._drywet.a);\n this.wet.connect(this._drywet.b);\n this._drywet.connect(this.output);\n\n this.connect();\n\n //Add to the soundArray\n p5sound.soundArray.push(this);\n };\n\n /**\n * Set the output volume of the filter.\n *\n * @method amp\n * @for p5.Effect\n * @param {Number} [vol] amplitude between 0 and 1.0\n * @param {Number} [rampTime] create a fade that lasts until rampTime\n * @param {Number} [tFromNow] schedule this event to happen in tFromNow seconds\n */\n p5.Effect.prototype.amp = function(vol, rampTime, tFromNow){\n var rampTime = rampTime || 0;\n var tFromNow = tFromNow || 0;\n var now = p5sound.audiocontext.currentTime;\n var currentVol = this.output.gain.value;\n this.output.gain.cancelScheduledValues(now);\n this.output.gain.linearRampToValueAtTime(currentVol, now + tFromNow + .001);\n this.output.gain.linearRampToValueAtTime(vol, now + tFromNow + rampTime + .001);\n };\n\n /**\n * Link effects together in a chain\n * Example usage: filter.chain(reverb, delay, panner);\n * May be used with an open-ended number of arguments\n *\n * @method chain\n * @for p5.Effect\n * @param {Object} [arguments] Chain together multiple sound objects\n */\n p5.Effect.prototype.chain = function(){\n if (arguments.length>0){\n this.connect(arguments[0]);\n for(var i=1;i\n * var notes = [60, 64, 67, 72];\n * var i = 0;\n *\n * function setup() {\n * osc = new p5.Oscillator('Triangle');\n * osc.start();\n * frameRate(1);\n * }\n *\n * function draw() {\n * var freq = midiToFreq(notes[i]);\n * osc.freq(freq);\n * i++;\n * if (i >= notes.length){\n * i = 0;\n * }\n * }\n * \n */\n var midiToFreq = p5.prototype.midiToFreq = function(m) {\n return 440 * Math.pow(2, (m-69)/12.0);\n };\n\n // This method converts ANSI notes specified as a string \"C4\", \"Eb3\" to a frequency\n var noteToFreq = function(note) {\n if (typeof note !== 'string') {\n return note;\n }\n var wholeNotes = {A:21, B:23, C:24, D:26, E:28, F:29, G:31};\n var value = wholeNotes[ note[0].toUpperCase() ];\n var octave = ~~note.slice(-1);\n value += 12 * (octave -1);\n\n switch(note[1]) {\n case '#':\n value += 1;\n break;\n case 'b':\n value -= 1;\n break;\n default:\n break;\n }\n return midiToFreq(value);\n };\n\n /**\n * List the SoundFile formats that you will include. LoadSound\n * will search your directory for these extensions, and will pick\n * a format that is compatable with the client's web browser.\n * Here is a free online file\n * converter.\n *\n * @method soundFormats\n * @param {String} [...formats] i.e. 'mp3', 'wav', 'ogg'\n * @example\n *
\n * function preload() {\n * // set the global sound formats\n * soundFormats('mp3', 'ogg');\n *\n * // load either beatbox.mp3, or .ogg, depending on browser\n * mySound = loadSound('assets/beatbox.mp3');\n * }\n *\n * function setup() {\n * mySound.play();\n * }\n *
\n */\n p5.prototype.soundFormats = function() {\n // reset extensions array\n p5sound.extensions = [];\n // add extensions\n for (var i = 0; i < arguments.length; i++) {\n arguments[i] = arguments[i].toLowerCase();\n if (['mp3','wav','ogg', 'm4a', 'aac'].indexOf(arguments[i]) > -1) {\n p5sound.extensions.push(arguments[i]);\n } else {\n throw arguments[i] + ' is not a valid sound format!';\n }\n }\n };\n\n p5.prototype.disposeSound = function() {\n for (var i = 0; i < p5sound.soundArray.length; i++) {\n p5sound.soundArray[i].dispose();\n }\n };\n\n // register removeSound to dispose of p5sound SoundFiles, Convolvers,\n // Oscillators etc when sketch ends\n p5.prototype.registerMethod('remove', p5.prototype.disposeSound);\n\n p5.prototype._checkFileFormats = function(paths) {\n var path;\n // if path is a single string, check to see if extension is provided\n if (typeof paths === 'string') {\n path = paths;\n // see if extension is provided\n var extTest = path.split('.').pop();\n // if an extension is provided...\n if (['mp3','wav','ogg', 'm4a', 'aac'].indexOf(extTest) > -1) {\n if (p5.prototype.isFileSupported(extTest)) {\n path = path;\n }\n else {\n var pathSplit = path.split('.');\n var pathCore = pathSplit[pathSplit.length - 1];\n for (var i = 0; i 1) {\n rightChannel = audioBuffer.getChannelData(1);\n } else {\n rightChannel = leftChannel;\n }\n\n var interleaved = interleave(leftChannel, rightChannel);\n\n // create the buffer and view to create the .WAV file\n var buffer = new window.ArrayBuffer(44 + interleaved.length * 2);\n var view = new window.DataView(buffer);\n\n // write the WAV container,\n // check spec at: https://web.archive.org/web/20171215131933/http://tiny.systems/software/soundProgrammer/WavFormatDocs.pdf\n\n // RIFF chunk descriptor\n writeUTFBytes(view, 0, 'RIFF');\n view.setUint32(4, 36 + interleaved.length * 2, true);\n writeUTFBytes(view, 8, 'WAVE');\n // FMT sub-chunk\n writeUTFBytes(view, 12, 'fmt ');\n view.setUint32(16, 16, true);\n view.setUint16(20, 1, true);\n // stereo (2 channels)\n view.setUint16(22, 2, true);\n view.setUint32(24, p5sound.audiocontext.sampleRate, true);\n view.setUint32(28, p5sound.audiocontext.sampleRate * 4, true);\n view.setUint16(32, 4, true);\n view.setUint16(34, 16, true);\n // data sub-chunk\n writeUTFBytes(view, 36, 'data');\n view.setUint32(40, interleaved.length * 2, true);\n\n // write the PCM samples\n var lng = interleaved.length;\n var index = 44;\n var volume = 1;\n for (var i = 0; i < lng; i++) {\n view.setInt16(index, interleaved[i] * (0x7FFF * volume), true);\n index += 2;\n }\n\n return view;\n }\n\n // helper methods to save waves\n function interleave(leftChannel, rightChannel) {\n var length = leftChannel.length + rightChannel.length;\n var result = new Float32Array(length);\n\n var inputIndex = 0;\n\n for (var index = 0; index < length;) {\n result[index++] = leftChannel[inputIndex];\n result[index++] = rightChannel[inputIndex];\n inputIndex++;\n }\n return result;\n }\n\n function writeUTFBytes(view, offset, string) {\n var lng = string.length;\n for (var i = 0; i < lng; i++) {\n view.setUint8(offset + i, string.charCodeAt(i));\n }\n }\n\n return {\n convertToWav: convertToWav,\n midiToFreq: midiToFreq,\n noteToFreq: noteToFreq\n };\n\n});\n","define([\"Tone/core/Tone\", \"Tone/signal/Signal\", \"Tone/core/Gain\"], function(Tone){\n\n\t\"use strict\";\n\n\t/**\n\t * @class Add a signal and a number or two signals. When no value is\n\t * passed into the constructor, Tone.Add will sum input[0]\n\t * and input[1]. If a value is passed into the constructor, \n\t * the it will be added to the input.\n\t * \n\t * @constructor\n\t * @extends {Tone.Signal}\n\t * @param {number=} value If no value is provided, Tone.Add will sum the first\n\t * and second inputs. \n\t * @example\n\t * var signal = new Tone.Signal(2);\n\t * var add = new Tone.Add(2);\n\t * signal.connect(add);\n\t * //the output of add equals 4\n\t * @example\n\t * //if constructed with no arguments\n\t * //it will add the first and second inputs\n\t * var add = new Tone.Add();\n\t * var sig0 = new Tone.Signal(3).connect(add, 0, 0);\n\t * var sig1 = new Tone.Signal(4).connect(add, 0, 1);\n\t * //the output of add equals 7. \n\t */\n\tTone.Add = function(value){\n\n\t\tthis.createInsOuts(2, 0);\n\n\t\t/**\n\t\t * the summing node\n\t\t * @type {GainNode}\n\t\t * @private\n\t\t */\n\t\tthis._sum = this.input[0] = this.input[1] = this.output = new Tone.Gain();\n\n\t\t/**\n\t\t * @private\n\t\t * @type {Tone.Signal}\n\t\t */\n\t\tthis._param = this.input[1] = new Tone.Signal(value);\n\n\t\tthis._param.connect(this._sum);\n\t};\n\n\tTone.extend(Tone.Add, Tone.Signal);\n\t\n\t/**\n\t * Clean up.\n\t * @returns {Tone.Add} this\n\t */\n\tTone.Add.prototype.dispose = function(){\n\t\tTone.prototype.dispose.call(this);\n\t\tthis._sum.dispose();\n\t\tthis._sum = null;\n\t\tthis._param.dispose();\n\t\tthis._param = null;\n\t\treturn this;\n\t}; \n\n\treturn Tone.Add;\n});","define([\"Tone/core/Tone\", \"Tone/type/Time\", \"Tone/type/Frequency\", \"Tone/type/TransportTime\", \"Tone/core/Context\"],\nfunction (Tone) {\t\n\n\t///////////////////////////////////////////////////////////////////////////\n\t//\tTYPES\n\t///////////////////////////////////////////////////////////////////////////\n\n\t/**\n\t * Units which a value can take on.\n\t * @enum {String}\n\t */\n\tTone.Type = {\n\t\t/** \n\t\t * Default units\n\t\t * @typedef {Default}\n\t\t */\n\t\tDefault : \"number\",\n\t\t/**\n\t\t * Time can be described in a number of ways. Read more [Time](https://github.com/Tonejs/Tone.js/wiki/Time).\n\t\t *\n\t\t *
\n\t\t *
Numbers, which will be taken literally as the time (in seconds).
\n\t\t *
Notation, (\"4n\", \"8t\") describes time in BPM and time signature relative values.
\n\t\t *
TransportTime, (\"4:3:2\") will also provide tempo and time signature relative times \n\t\t * in the form BARS:QUARTERS:SIXTEENTHS.
\n\t\t *
Frequency, (\"8hz\") is converted to the length of the cycle in seconds.
\n\t\t *
Now-Relative, (\"+1\") prefix any of the above with \"+\" and it will be interpreted as \n\t\t * \"the current time plus whatever expression follows\".
\n\t\t *
Expressions, (\"3:0 + 2 - (1m / 7)\") any of the above can also be combined \n\t\t * into a mathematical expression which will be evaluated to compute the desired time.
\n\t\t *
No Argument, for methods which accept time, no argument will be interpreted as \n\t\t * \"now\" (i.e. the currentTime).
\n\t\t *
\n\t\t * \n\t\t * @typedef {Time}\n\t\t */\n\t\tTime : \"time\",\n\t\t/**\n\t\t * Frequency can be described similar to time, except ultimately the\n\t\t * values are converted to frequency instead of seconds. A number\n\t\t * is taken literally as the value in hertz. Additionally any of the \n\t\t * Time encodings can be used. Note names in the form\n\t\t * of NOTE OCTAVE (i.e. C4) are also accepted and converted to their\n\t\t * frequency value. \n\t\t * @typedef {Frequency}\n\t\t */\n\t\tFrequency : \"frequency\",\n\t\t/**\n\t\t * TransportTime describes a position along the Transport's timeline. It is\n\t\t * similar to Time in that it uses all the same encodings, but TransportTime specifically\n\t\t * pertains to the Transport's timeline, which is startable, stoppable, loopable, and seekable. \n\t\t * [Read more](https://github.com/Tonejs/Tone.js/wiki/TransportTime)\n\t\t * @typedef {TransportTime}\n\t\t */\n\t\tTransportTime : \"transportTime\",\n\t\t/** \n\t\t * Ticks are the basic subunit of the Transport. They are\n\t\t * the smallest unit of time that the Transport supports.\n\t\t * @typedef {Ticks}\n\t\t */\n\t\tTicks : \"ticks\",\n\t\t/** \n\t\t * Normal values are within the range [0, 1].\n\t\t * @typedef {NormalRange}\n\t\t */\n\t\tNormalRange : \"normalRange\",\n\t\t/** \n\t\t * AudioRange values are between [-1, 1].\n\t\t * @typedef {AudioRange}\n\t\t */\n\t\tAudioRange : \"audioRange\",\n\t\t/** \n\t\t * Decibels are a logarithmic unit of measurement which is useful for volume\n\t\t * because of the logarithmic way that we perceive loudness. 0 decibels \n\t\t * means no change in volume. -10db is approximately half as loud and 10db \n\t\t * is twice is loud. \n\t\t * @typedef {Decibels}\n\t\t */\n\t\tDecibels : \"db\",\n\t\t/** \n\t\t * Half-step note increments, i.e. 12 is an octave above the root. and 1 is a half-step up.\n\t\t * @typedef {Interval}\n\t\t */\n\t\tInterval : \"interval\",\n\t\t/** \n\t\t * Beats per minute. \n\t\t * @typedef {BPM}\n\t\t */\n\t\tBPM : \"bpm\",\n\t\t/** \n\t\t * The value must be greater than or equal to 0.\n\t\t * @typedef {Positive}\n\t\t */\n\t\tPositive : \"positive\",\n\t\t/** \n\t\t * A cent is a hundredth of a semitone. \n\t\t * @typedef {Cents}\n\t\t */\n\t\tCents : \"cents\",\n\t\t/** \n\t\t * Angle between 0 and 360. \n\t\t * @typedef {Degrees}\n\t\t */\n\t\tDegrees : \"degrees\",\n\t\t/** \n\t\t * A number representing a midi note.\n\t\t * @typedef {MIDI}\n\t\t */\n\t\tMIDI : \"midi\",\n\t\t/** \n\t\t * A colon-separated representation of time in the form of\n\t\t * Bars:Beats:Sixteenths. \n\t\t * @typedef {BarsBeatsSixteenths}\n\t\t */\n\t\tBarsBeatsSixteenths : \"barsBeatsSixteenths\",\n\t\t/** \n\t\t * Sampling is the reduction of a continuous signal to a discrete signal.\n\t\t * Audio is typically sampled 44100 times per second. \n\t\t * @typedef {Samples}\n\t\t */\n\t\tSamples : \"samples\",\n\t\t/** \n\t\t * Hertz are a frequency representation defined as one cycle per second.\n\t\t * @typedef {Hertz}\n\t\t */\n\t\tHertz : \"hertz\",\n\t\t/** \n\t\t * A frequency represented by a letter name, \n\t\t * accidental and octave. This system is known as\n\t\t * [Scientific Pitch Notation](https://en.wikipedia.org/wiki/Scientific_pitch_notation).\n\t\t * @typedef {Note}\n\t\t */\n\t\tNote : \"note\",\n\t\t/** \n\t\t * One millisecond is a thousandth of a second. \n\t\t * @typedef {Milliseconds}\n\t\t */\n\t\tMilliseconds : \"milliseconds\",\n\t\t/** \n\t\t * Seconds are the time unit of the AudioContext. In the end, \n\t\t * all values need to be evaluated to seconds. \n\t\t * @typedef {Seconds}\n\t\t */\n\t\tSeconds : \"seconds\",\n\t\t/** \n\t\t * A string representing a duration relative to a measure. \n\t\t *
\n\t\t * \t
\"4n\" = quarter note
\n\t\t * \t
\"2m\" = two measures
\n\t\t * \t
\"8t\" = eighth-note triplet
\n\t\t *
\n\t\t * @typedef {Notation}\n\t\t */\n\t\tNotation : \"notation\",\n\t};\n\n\t///////////////////////////////////////////////////////////////////////////\n\t// AUGMENT TONE's PROTOTYPE\n\t///////////////////////////////////////////////////////////////////////////\n\n\t/**\n\t * Convert Time into seconds.\n\t * \n\t * Unlike the method which it overrides, this takes into account \n\t * transporttime and musical notation.\n\t *\n\t * Time : 1.40\n\t * Notation: 4n|1m|2t\n\t * Now Relative: +3n\n\t * Math: 3n+16n or even complicated expressions ((3n*2)/6 + 1)\n\t *\n\t * @param {Time} time \n\t * @return {Seconds} \n\t */\n\tTone.prototype.toSeconds = function(time){\n\t\tif (this.isNumber(time)){\n\t\t\treturn time;\n\t\t} else if (this.isUndef(time)){\n\t\t\treturn this.now();\t\t\t\n\t\t} else if (this.isString(time)){\n\t\t\treturn (new Tone.Time(time)).toSeconds();\n\t\t} else if (time instanceof Tone.TimeBase){\n\t\t\treturn time.toSeconds();\n\t\t}\n\t};\n\n\t/**\n\t * Convert a frequency representation into a number.\n\t * @param {Frequency} freq \n\t * @return {Hertz} the frequency in hertz\n\t */\n\tTone.prototype.toFrequency = function(freq){\n\t\tif (this.isNumber(freq)){\n\t\t\treturn freq;\n\t\t} else if (this.isString(freq) || this.isUndef(freq)){\n\t\t\treturn (new Tone.Frequency(freq)).valueOf();\n\t\t} else if (freq instanceof Tone.TimeBase){\n\t\t\treturn freq.toFrequency();\n\t\t}\n\t};\n\n\t/**\n\t * Convert a time representation into ticks.\n\t * @param {Time} time\n\t * @return {Ticks} the time in ticks\n\t */\n\tTone.prototype.toTicks = function(time){\n\t\tif (this.isNumber(time) || this.isString(time)){\n\t\t\treturn (new Tone.TransportTime(time)).toTicks();\n\t\t} else if (this.isUndef(time)){\n\t\t\treturn Tone.Transport.ticks;\t\t\t\n\t\t} else if (time instanceof Tone.TimeBase){\n\t\t\treturn time.toTicks();\n\t\t}\n\t};\n\n\treturn Tone;\n});","define([\"Tone/core/Tone\", \"Tone/core/Param\", \"Tone/type/Type\"], function (Tone) {\n\n\t\"use strict\";\n\n\t/**\n\t * createGain shim\n\t * @private\n\t */\n\tif (window.GainNode && !AudioContext.prototype.createGain){\n\t\tAudioContext.prototype.createGain = AudioContext.prototype.createGainNode;\n\t}\n\n\t/**\n\t * @class A thin wrapper around the Native Web Audio GainNode.\n\t * The GainNode is a basic building block of the Web Audio\n\t * API and is useful for routing audio and adjusting gains. \n\t * @extends {Tone}\n\t * @param {Number=} gain The initial gain of the GainNode\n\t * @param {Tone.Type=} units The units of the gain parameter. \n\t */\n\tTone.Gain = function(){\n\n\t\tvar options = this.optionsObject(arguments, [\"gain\", \"units\"], Tone.Gain.defaults);\n\n\t\t/**\n\t\t * The GainNode\n\t\t * @type {GainNode}\n\t\t * @private\n\t\t */\n\t\tthis.input = this.output = this._gainNode = this.context.createGain();\n\n\t\t/**\n\t\t * The gain parameter of the gain node.\n\t\t * @type {Tone.Param}\n\t\t * @signal\n\t\t */\n\t\tthis.gain = new Tone.Param({\n\t\t\t\"param\" : this._gainNode.gain, \n\t\t\t\"units\" : options.units,\n\t\t\t\"value\" : options.gain,\n\t\t\t\"convert\" : options.convert\n\t\t});\n\t\tthis._readOnly(\"gain\");\n\t};\n\n\tTone.extend(Tone.Gain);\n\n\t/**\n\t * The defaults\n\t * @const\n\t * @type {Object}\n\t */\n\tTone.Gain.defaults = {\n\t\t\"gain\" : 1,\n\t\t\"convert\" : true,\n\t};\n\n\t/**\n\t * Clean up.\n\t * @return {Tone.Gain} this\n\t */\n\tTone.Gain.prototype.dispose = function(){\n\t\tTone.Param.prototype.dispose.call(this);\n\t\tthis._gainNode.disconnect();\n\t\tthis._gainNode = null;\n\t\tthis._writable(\"gain\");\n\t\tthis.gain.dispose();\n\t\tthis.gain = null;\n\t};\n\n\t//STATIC///////////////////////////////////////////////////////////////////\n\n\t/**\n\t * Create input and outputs for this object.\n\t * @param {Number} input The number of inputs\n\t * @param {Number=} outputs The number of outputs\n\t * @return {Tone} this\n\t * @internal\n\t */\n\tTone.prototype.createInsOuts = function(inputs, outputs){\n\n\t\tif (inputs === 1){\n\t\t\tthis.input = new Tone.Gain();\n\t\t} else if (inputs > 1){\n\t\t\tthis.input = new Array(inputs);\n\t\t}\n\n\t\tif (outputs === 1){\n\t\t\tthis.output = new Tone.Gain();\n\t\t} else if (outputs > 1){\n\t\t\tthis.output = new Array(inputs);\n\t\t}\n\t};\n\n\t///////////////////////////////////////////////////////////////////////////\n\n\treturn Tone.Gain;\n});","'use strict';\n\ndefine(function () {\n /*\n Helper function to generate an error\n with a custom stack trace that points to the sketch\n and removes other parts of the stack trace.\n\n @private\n @class customError\n @constructor\n @param {String} name custom error name\n @param {String} errorTrace custom error trace\n @param {String} failedPath path to the file that failed to load\n @property {String} name custom error name\n @property {String} message custom error message\n @property {String} stack trace the error back to a line in the user's sketch.\n Note: this edits out stack trace within p5.js and p5.sound.\n @property {String} originalStack unedited, original stack trace\n @property {String} failedPath path to the file that failed to load\n @return {Error} returns a custom Error object\n */\n var CustomError = function(name, errorTrace, failedPath) {\n var err = new Error();\n var tempStack, splitStack;\n\n err.name = name;\n err.originalStack = err.stack + errorTrace;\n tempStack = err.stack + errorTrace;\n err.failedPath = failedPath;\n\n // only print the part of the stack trace that refers to the user code:\n var splitStack = tempStack.split('\\n');\n splitStack = splitStack.filter(function(ln) {\n return !ln.match(/(p5.|native code|globalInit)/g);\n });\n err.stack = splitStack.join('\\n');\n\n return err; // TODO: is this really a constructor?\n };\n\n return CustomError;\n});\n","define([\"Tone/core/Tone\", \"Tone/core/Emitter\"], function (Tone) {\n\n\t/**\n\t * shim\n\t * @private\n\t */\n\tif (!window.hasOwnProperty(\"AudioContext\") && window.hasOwnProperty(\"webkitAudioContext\")){\n\t\twindow.AudioContext = window.webkitAudioContext;\n\t}\n\n\t/**\n\t * @class Wrapper around the native AudioContext.\n\t * @extends {Tone.Emitter}\n\t * @param {AudioContext=} context optionally pass in a context\n\t */\n\tTone.Context = function(context){\n\n\t\tTone.Emitter.call(this);\n\n\t\tif (!context){\n\t\t\tcontext = new window.AudioContext();\n\t\t}\n\t\tthis._context = context;\n\t\t// extend all of the methods\n\t\tfor (var prop in this._context){\n\t\t\tthis._defineProperty(this._context, prop);\n\t\t}\n\n\t\t///////////////////////////////////////////////////////////////////////\n\t\t// WORKER\n\t\t///////////////////////////////////////////////////////////////////////\n\n\t\t/**\n\t\t * The default latency hint\n\t\t * @type {String}\n\t\t * @private\n\t\t */\n\t\tthis._latencyHint = \"interactive\";\n\n\t\t/**\n\t\t * The amount of time events are scheduled\n\t\t * into the future\n\t\t * @type {Number}\n\t\t * @private\n\t\t */\n\t\tthis._lookAhead = 0.1;\n\n\t\t/**\n\t\t * How often the update look runs\n\t\t * @type {Number}\n\t\t * @private\n\t\t */\n\t\tthis._updateInterval = this._lookAhead/3;\n\n\t\t/**\n\t\t * A reference to the actual computed update interval\n\t\t * @type {Number}\n\t\t * @private\n\t\t */\n\t\tthis._computedUpdateInterval = 0;\n\n\t\t/**\n\t\t * The web worker which is used to update Tone.Clock\n\t\t * @private\n\t\t * @type {WebWorker}\n\t\t */\n\t\tthis._worker = this._createWorker();\n\n\t\t/**\n\t\t * An object containing all of the constants AudioBufferSourceNodes\n\t\t * @type {Object}\n\t\t * @private\n\t\t */\n\t\tthis._constants = {};\n\n\t};\n\n\tTone.extend(Tone.Context, Tone.Emitter);\n\tTone.Emitter.mixin(Tone.Context);\n\n\t/**\n\t * Define a property on this Tone.Context. \n\t * This is used to extend the native AudioContext\n\t * @param {AudioContext} context\n\t * @param {String} prop \n\t * @private\n\t */\n\tTone.Context.prototype._defineProperty = function(context, prop){\n\t\tif (this.isUndef(this[prop])){\n\t\t\tObject.defineProperty(this, prop, {\n\t\t\t\tget : function(){\n\t\t\t\t\tif (typeof context[prop] === \"function\"){\n\t\t\t\t\t\treturn context[prop].bind(context);\n\t\t\t\t\t} else {\n\t\t\t\t\t\treturn context[prop];\n\t\t\t\t\t}\n\t\t\t\t},\n\t\t\t\tset : function(val){\n\t\t\t\t\tcontext[prop] = val;\n\t\t\t\t}\n\t\t\t});\n\t\t}\n\t};\n\n\t/**\n\t * The current audio context time\n\t * @return {Number}\n\t */\n\tTone.Context.prototype.now = function(){\n\t\treturn this._context.currentTime;\n\t};\n\n\t/**\n\t * Generate a web worker\n\t * @return {WebWorker}\n\t * @private\n\t */\n\tTone.Context.prototype._createWorker = function(){\n\t\t\n\t\t//URL Shim\n\t\twindow.URL = window.URL || window.webkitURL;\n\n\t\tvar blob = new Blob([\n\t\t\t//the initial timeout time\n\t\t\t\"var timeoutTime = \"+(this._updateInterval * 1000).toFixed(1)+\";\" +\n\t\t\t//onmessage callback\n\t\t\t\"self.onmessage = function(msg){\" +\n\t\t\t\"\ttimeoutTime = parseInt(msg.data);\" + \n\t\t\t\"};\" + \n\t\t\t//the tick function which posts a message\n\t\t\t//and schedules a new tick\n\t\t\t\"function tick(){\" +\n\t\t\t\"\tsetTimeout(tick, timeoutTime);\" +\n\t\t\t\"\tself.postMessage('tick');\" +\n\t\t\t\"}\" +\n\t\t\t//call tick initially\n\t\t\t\"tick();\"\n\t\t]);\n\t\tvar blobUrl = URL.createObjectURL(blob);\n\t\tvar worker = new Worker(blobUrl);\n\n\t\tworker.addEventListener(\"message\", function(){\n\t\t\t// tick the clock\n\t\t\tthis.emit(\"tick\");\n\t\t}.bind(this));\n\n\t\t//lag compensation\n\t\tworker.addEventListener(\"message\", function(){\n\t\t\tvar now = this.now();\n\t\t\tif (this.isNumber(this._lastUpdate)){\n\t\t\t\tvar diff = now - this._lastUpdate;\n\t\t\t\tthis._computedUpdateInterval = Math.max(diff, this._computedUpdateInterval * 0.97);\n\t\t\t}\n\t\t\tthis._lastUpdate = now;\n\t\t}.bind(this));\n\n\t\treturn worker;\n\t};\n\n\t/**\n\t * Generate a looped buffer at some constant value.\n\t * @param {Number} val\n\t * @return {BufferSourceNode}\n\t */\n\tTone.Context.prototype.getConstant = function(val){\n\t\tif (this._constants[val]){\n\t\t\treturn this._constants[val];\n\t\t} else {\n\t\t\tvar buffer = this._context.createBuffer(1, 128, this._context.sampleRate);\n\t\t\tvar arr = buffer.getChannelData(0);\n\t\t\tfor (var i = 0; i < arr.length; i++){\n\t\t\t\tarr[i] = val;\n\t\t\t}\n\t\t\tvar constant = this._context.createBufferSource();\n\t\t\tconstant.channelCount = 1;\n\t\t\tconstant.channelCountMode = \"explicit\";\n\t\t\tconstant.buffer = buffer;\n\t\t\tconstant.loop = true;\n\t\t\tconstant.start(0);\n\t\t\tthis._constants[val] = constant;\n\t\t\treturn constant;\n\t\t}\n\t};\n\n\t/**\n\t * This is the time that the clock is falling behind\n\t * the scheduled update interval. The Context automatically\n\t * adjusts for the lag and schedules further in advance.\n\t * @type {Number}\n\t * @memberOf Tone.Context\n\t * @name lag\n\t * @static\n\t * @readOnly\n\t */\n\tObject.defineProperty(Tone.Context.prototype, \"lag\", {\n\t\tget : function(){\n\t\t\tvar diff = this._computedUpdateInterval - this._updateInterval;\n\t\t\tdiff = Math.max(diff, 0);\n\t\t\treturn diff;\n\t\t}\n\t});\n\n\t/**\n\t * The amount of time in advance that events are scheduled.\n\t * The lookAhead will adjust slightly in response to the \n\t * measured update time to try to avoid clicks.\n\t * @type {Number}\n\t * @memberOf Tone.Context\n\t * @name lookAhead\n\t * @static\n\t */\n\tObject.defineProperty(Tone.Context.prototype, \"lookAhead\", {\n\t\tget : function(){\n\t\t\treturn this._lookAhead;\n\t\t},\n\t\tset : function(lA){\n\t\t\tthis._lookAhead = lA;\n\t\t}\n\t});\n\n\t/**\n\t * How often the Web Worker callback is invoked.\n\t * This number corresponds to how responsive the scheduling\n\t * can be. Context.updateInterval + Context.lookAhead gives you the\n\t * total latency between scheduling an event and hearing it.\n\t * @type {Number}\n\t * @memberOf Tone.Context\n\t * @name updateInterval\n\t * @static\n\t */\n\tObject.defineProperty(Tone.Context.prototype, \"updateInterval\", {\n\t\tget : function(){\n\t\t\treturn this._updateInterval;\n\t\t},\n\t\tset : function(interval){\n\t\t\tthis._updateInterval = Math.max(interval, Tone.prototype.blockTime);\n\t\t\tthis._worker.postMessage(Math.max(interval * 1000, 1));\n\t\t}\n\t});\n\n\t/**\n\t * The type of playback, which affects tradeoffs between audio \n\t * output latency and responsiveness. \n\t * \n\t * In addition to setting the value in seconds, the latencyHint also\n\t * accepts the strings \"interactive\" (prioritizes low latency), \n\t * \"playback\" (prioritizes sustained playback), \"balanced\" (balances\n\t * latency and performance), and \"fastest\" (lowest latency, might glitch more often). \n\t * @type {String|Seconds}\n\t * @memberOf Tone.Context#\n\t * @name latencyHint\n\t * @static\n\t * @example\n\t * //set the lookAhead to 0.3 seconds\n\t * Tone.context.latencyHint = 0.3;\n\t */\n\tObject.defineProperty(Tone.Context.prototype, \"latencyHint\", {\n\t\tget : function(){\n\t\t\treturn this._latencyHint;\n\t\t},\n\t\tset : function(hint){\n\t\t\tvar lookAhead = hint;\n\t\t\tthis._latencyHint = hint;\n\t\t\tif (this.isString(hint)){\n\t\t\t\tswitch(hint){\n\t\t\t\t\tcase \"interactive\" :\n\t\t\t\t\t\tlookAhead = 0.1;\n\t\t\t\t\t\tthis._context.latencyHint = hint;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase \"playback\" :\n\t\t\t\t\t\tlookAhead = 0.8;\n\t\t\t\t\t\tthis._context.latencyHint = hint;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase \"balanced\" :\n\t\t\t\t\t\tlookAhead = 0.25;\n\t\t\t\t\t\tthis._context.latencyHint = hint;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase \"fastest\" :\n\t\t\t\t\t\tlookAhead = 0.01;\n\t\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t\tthis.lookAhead = lookAhead;\n\t\t\tthis.updateInterval = lookAhead/3;\n\t\t}\n\t});\n\n\t/**\n\t * Shim all connect/disconnect and some deprecated methods which are still in\n\t * some older implementations.\n\t * @private\n\t */\n\tfunction shimConnect(){\n\n\t\tvar nativeConnect = AudioNode.prototype.connect;\n\t\tvar nativeDisconnect = AudioNode.prototype.disconnect;\n\n\t\t//replace the old connect method\n\t\tfunction toneConnect(B, outNum, inNum){\n\t\t\tif (B.input){\n\t\t\t\tif (Array.isArray(B.input)){\n\t\t\t\t\tif (Tone.prototype.isUndef(inNum)){\n\t\t\t\t\t\tinNum = 0;\n\t\t\t\t\t}\n\t\t\t\t\tthis.connect(B.input[inNum]);\n\t\t\t\t} else {\n\t\t\t\t\tthis.connect(B.input, outNum, inNum);\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\ttry {\n\t\t\t\t\tif (B instanceof AudioNode){\n\t\t\t\t\t\tnativeConnect.call(this, B, outNum, inNum);\n\t\t\t\t\t} else {\n\t\t\t\t\t\tnativeConnect.call(this, B, outNum);\n\t\t\t\t\t}\n\t\t\t\t} catch (e) {\n\t\t\t\t\tthrow new Error(\"error connecting to node: \"+B+\"\\n\"+e);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t//replace the old disconnect method\n\t\tfunction toneDisconnect(B, outNum, inNum){\n\t\t\tif (B && B.input && Array.isArray(B.input)){\n\t\t\t\tif (Tone.prototype.isUndef(inNum)){\n\t\t\t\t\tinNum = 0;\n\t\t\t\t}\n\t\t\t\tthis.disconnect(B.input[inNum], outNum, inNum);\n\t\t\t} else if (B && B.input){\n\t\t\t\tthis.disconnect(B.input, outNum, inNum);\n\t\t\t} else {\n\t\t\t\ttry {\n\t\t\t\t\tnativeDisconnect.apply(this, arguments);\n\t\t\t\t} catch (e) {\n\t\t\t\t\tthrow new Error(\"error disconnecting node: \"+B+\"\\n\"+e);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tif (AudioNode.prototype.connect !== toneConnect){\n\t\t\tAudioNode.prototype.connect = toneConnect;\n\t\t\tAudioNode.prototype.disconnect = toneDisconnect;\n\t\t}\n\t}\n\n\t// set the audio context initially\n\tif (Tone.supported){\n\t\tshimConnect();\n\t\tTone.context = new Tone.Context();\n\t} else {\n\t\tconsole.warn(\"This browser does not support Tone.js\");\n\t}\n\n\treturn Tone.Context;\n});","module.exports = {\n recorderProcessor: 'recorder-processor',\n soundFileProcessor: 'sound-file-processor',\n amplitudeProcessor: 'amplitude-processor'\n};\n","define([\"Tone/core/Tone\", \"Tone/signal/Add\", \"Tone/signal/Multiply\", \"Tone/signal/Signal\"], function(Tone){\n\n\t\"use strict\";\n\t\n\t/**\n\t * @class Performs a linear scaling on an input signal.\n\t * Scales a NormalRange input to between\n\t * outputMin and outputMax.\n\t *\n\t * @constructor\n\t * @extends {Tone.SignalBase}\n\t * @param {number} [outputMin=0] The output value when the input is 0. \n\t * @param {number} [outputMax=1]\tThe output value when the input is 1. \n\t * @example\n\t * var scale = new Tone.Scale(50, 100);\n\t * var signal = new Tone.Signal(0.5).connect(scale);\n\t * //the output of scale equals 75\n\t */\n\tTone.Scale = function(outputMin, outputMax){\n\n\t\t/** \n\t\t * @private\n\t\t * @type {number}\n\t\t */\n\t\tthis._outputMin = this.defaultArg(outputMin, 0);\n\n\t\t/** \n\t\t * @private\n\t\t * @type {number}\n\t\t */\n\t\tthis._outputMax = this.defaultArg(outputMax, 1);\n\n\n\t\t/** \n\t\t * @private\n\t\t * @type {Tone.Multiply}\n\t\t * @private\n\t\t */\n\t\tthis._scale = this.input = new Tone.Multiply(1);\n\t\t\n\t\t/** \n\t\t * @private\n\t\t * @type {Tone.Add}\n\t\t * @private\n\t\t */\n\t\tthis._add = this.output = new Tone.Add(0);\n\n\t\tthis._scale.connect(this._add);\n\t\tthis._setRange();\n\t};\n\n\tTone.extend(Tone.Scale, Tone.SignalBase);\n\n\t/**\n\t * The minimum output value. This number is output when \n\t * the value input value is 0. \n\t * @memberOf Tone.Scale#\n\t * @type {number}\n\t * @name min\n\t */\n\tObject.defineProperty(Tone.Scale.prototype, \"min\", {\n\t\tget : function(){\n\t\t\treturn this._outputMin;\n\t\t},\n\t\tset : function(min){\n\t\t\tthis._outputMin = min;\n\t\t\tthis._setRange();\n\t\t}\n\t});\n\n\t/**\n\t * The maximum output value. This number is output when \n\t * the value input value is 1. \n\t * @memberOf Tone.Scale#\n\t * @type {number}\n\t * @name max\n\t */\n\tObject.defineProperty(Tone.Scale.prototype, \"max\", {\n\t\tget : function(){\n\t\t\treturn this._outputMax;\n\t\t},\n\t\tset : function(max){\n\t\t\tthis._outputMax = max;\n\t\t\tthis._setRange();\n\t\t}\n\t});\n\n\t/**\n\t * set the values\n\t * @private\n\t */\n\tTone.Scale.prototype._setRange = function() {\n\t\tthis._add.value = this._outputMin;\n\t\tthis._scale.value = this._outputMax - this._outputMin;\n\t};\n\n\t/**\n\t * Clean up.\n\t * @returns {Tone.Scale} this\n\t */\n\tTone.Scale.prototype.dispose = function(){\n\t\tTone.prototype.dispose.call(this);\n\t\tthis._add.dispose();\n\t\tthis._add = null;\n\t\tthis._scale.dispose();\n\t\tthis._scale = null;\n\t\treturn this;\n\t}; \n\n\treturn Tone.Scale;\n});\n","define([\"Tone/core/Tone\", \"Tone/signal/Signal\", \"Tone/core/Timeline\"], function (Tone) {\n\n\t\"use strict\";\n\n\t/**\n\t * @class A signal which adds the method getValueAtTime. \n\t * Code and inspiration from https://github.com/jsantell/web-audio-automation-timeline\n\t * @extends {Tone.Param}\n\t * @param {Number=} value The initial value of the signal\n\t * @param {String=} units The conversion units of the signal.\n\t */\n\tTone.TimelineSignal = function(){\n\n\t\tvar options = this.optionsObject(arguments, [\"value\", \"units\"], Tone.Signal.defaults);\n\t\t\n\t\t/**\n\t\t * The scheduled events\n\t\t * @type {Tone.Timeline}\n\t\t * @private\n\t\t */\n\t\tthis._events = new Tone.Timeline(10);\n\n\t\t//constructors\n\t\tTone.Signal.apply(this, options);\n\t\toptions.param = this._param;\n\t\tTone.Param.call(this, options);\n\n\t\t/**\n\t\t * The initial scheduled value\n\t\t * @type {Number}\n\t\t * @private\n\t\t */\n\t\tthis._initial = this._fromUnits(this._param.value);\n\t};\n\n\tTone.extend(Tone.TimelineSignal, Tone.Param);\n\n\t/**\n\t * The event types of a schedulable signal.\n\t * @enum {String}\n\t * @private\n\t */\n\tTone.TimelineSignal.Type = {\n\t\tLinear : \"linear\",\n\t\tExponential : \"exponential\",\n\t\tTarget : \"target\",\n\t\tCurve : \"curve\",\n\t\tSet : \"set\"\n\t};\n\n\t/**\n\t * The current value of the signal. \n\t * @memberOf Tone.TimelineSignal#\n\t * @type {Number}\n\t * @name value\n\t */\n\tObject.defineProperty(Tone.TimelineSignal.prototype, \"value\", {\n\t\tget : function(){\n\t\t\tvar now = this.now();\n\t\t\tvar val = this.getValueAtTime(now);\n\t\t\treturn this._toUnits(val);\n\t\t},\n\t\tset : function(value){\n\t\t\tvar convertedVal = this._fromUnits(value);\n\t\t\tthis._initial = convertedVal;\n\t\t\tthis.cancelScheduledValues();\n\t\t\tthis._param.value = convertedVal;\n\t\t}\n\t});\n\n\t///////////////////////////////////////////////////////////////////////////\n\t//\tSCHEDULING\n\t///////////////////////////////////////////////////////////////////////////\n\n\t/**\n\t * Schedules a parameter value change at the given time.\n\t * @param {*}\tvalue The value to set the signal.\n\t * @param {Time} time The time when the change should occur.\n\t * @returns {Tone.TimelineSignal} this\n\t * @example\n\t * //set the frequency to \"G4\" in exactly 1 second from now. \n\t * freq.setValueAtTime(\"G4\", \"+1\");\n\t */\n\tTone.TimelineSignal.prototype.setValueAtTime = function (value, startTime) {\n\t\tvalue = this._fromUnits(value);\n\t\tstartTime = this.toSeconds(startTime);\n\t\tthis._events.add({\n\t\t\t\"type\" : Tone.TimelineSignal.Type.Set,\n\t\t\t\"value\" : value,\n\t\t\t\"time\" : startTime\n\t\t});\n\t\t//invoke the original event\n\t\tthis._param.setValueAtTime(value, startTime);\n\t\treturn this;\n\t};\n\n\t/**\n\t * Schedules a linear continuous change in parameter value from the \n\t * previous scheduled parameter value to the given value.\n\t * \n\t * @param {number} value \n\t * @param {Time} endTime \n\t * @returns {Tone.TimelineSignal} this\n\t */\n\tTone.TimelineSignal.prototype.linearRampToValueAtTime = function (value, endTime) {\n\t\tvalue = this._fromUnits(value);\n\t\tendTime = this.toSeconds(endTime);\n\t\tthis._events.add({\n\t\t\t\"type\" : Tone.TimelineSignal.Type.Linear,\n\t\t\t\"value\" : value,\n\t\t\t\"time\" : endTime\n\t\t});\n\t\tthis._param.linearRampToValueAtTime(value, endTime);\n\t\treturn this;\n\t};\n\n\t/**\n\t * Schedules an exponential continuous change in parameter value from \n\t * the previous scheduled parameter value to the given value.\n\t * \n\t * @param {number} value \n\t * @param {Time} endTime \n\t * @returns {Tone.TimelineSignal} this\n\t */\n\tTone.TimelineSignal.prototype.exponentialRampToValueAtTime = function (value, endTime) {\n\t\t//get the previous event and make sure it's not starting from 0\n\t\tendTime = this.toSeconds(endTime);\n\t\tvar beforeEvent = this._searchBefore(endTime);\n\t\tif (beforeEvent && beforeEvent.value === 0){\n\t\t\t//reschedule that event\n\t\t\tthis.setValueAtTime(this._minOutput, beforeEvent.time);\n\t\t}\n\t\tvalue = this._fromUnits(value);\n\t\tvar setValue = Math.max(value, this._minOutput);\n\t\tthis._events.add({\n\t\t\t\"type\" : Tone.TimelineSignal.Type.Exponential,\n\t\t\t\"value\" : setValue,\n\t\t\t\"time\" : endTime\n\t\t});\n\t\t//if the ramped to value is 0, make it go to the min output, and then set to 0.\n\t\tif (value < this._minOutput){\n\t\t\tthis._param.exponentialRampToValueAtTime(this._minOutput, endTime - this.sampleTime);\n\t\t\tthis.setValueAtTime(0, endTime);\n\t\t} else {\n\t\t\tthis._param.exponentialRampToValueAtTime(value, endTime);\n\t\t}\n\t\treturn this;\n\t};\n\n\t/**\n\t * Start exponentially approaching the target value at the given time with\n\t * a rate having the given time constant.\n\t * @param {number} value \n\t * @param {Time} startTime \n\t * @param {number} timeConstant \n\t * @returns {Tone.TimelineSignal} this \n\t */\n\tTone.TimelineSignal.prototype.setTargetAtTime = function (value, startTime, timeConstant) {\n\t\tvalue = this._fromUnits(value);\n\t\tvalue = Math.max(this._minOutput, value);\n\t\ttimeConstant = Math.max(this._minOutput, timeConstant);\n\t\tstartTime = this.toSeconds(startTime);\n\t\tthis._events.add({\n\t\t\t\"type\" : Tone.TimelineSignal.Type.Target,\n\t\t\t\"value\" : value,\n\t\t\t\"time\" : startTime,\n\t\t\t\"constant\" : timeConstant\n\t\t});\n\t\tthis._param.setTargetAtTime(value, startTime, timeConstant);\n\t\treturn this;\n\t};\n\n\t/**\n\t * Set an array of arbitrary values starting at the given time for the given duration.\n\t * @param {Float32Array} values \n\t * @param {Time} startTime \n\t * @param {Time} duration\n\t * @param {NormalRange} [scaling=1] If the values in the curve should be scaled by some value\n\t * @returns {Tone.TimelineSignal} this \n\t */\n\tTone.TimelineSignal.prototype.setValueCurveAtTime = function (values, startTime, duration, scaling) {\n\t\tscaling = this.defaultArg(scaling, 1);\n\t\t//copy the array\n\t\tvar floats = new Array(values.length);\n\t\tfor (var i = 0; i < floats.length; i++){\n\t\t\tfloats[i] = this._fromUnits(values[i]) * scaling;\n\t\t}\n\t\tstartTime = this.toSeconds(startTime);\n\t\tduration = this.toSeconds(duration);\n\t\tthis._events.add({\n\t\t\t\"type\" : Tone.TimelineSignal.Type.Curve,\n\t\t\t\"value\" : floats,\n\t\t\t\"time\" : startTime,\n\t\t\t\"duration\" : duration\n\t\t});\n\t\t//set the first value\n\t\tthis._param.setValueAtTime(floats[0], startTime);\n\t\t//schedule a lienar ramp for each of the segments\n\t\tfor (var j = 1; j < floats.length; j++){\n\t\t\tvar segmentTime = startTime + (j / (floats.length - 1) * duration);\n\t\t\tthis._param.linearRampToValueAtTime(floats[j], segmentTime);\n\t\t}\n\t\treturn this;\n\t};\n\n\t/**\n\t * Cancels all scheduled parameter changes with times greater than or \n\t * equal to startTime.\n\t * \n\t * @param {Time} startTime\n\t * @returns {Tone.TimelineSignal} this\n\t */\n\tTone.TimelineSignal.prototype.cancelScheduledValues = function (after) {\n\t\tafter = this.toSeconds(after);\n\t\tthis._events.cancel(after);\n\t\tthis._param.cancelScheduledValues(after);\n\t\treturn this;\n\t};\n\n\t/**\n\t * Sets the computed value at the given time. This provides\n\t * a point from which a linear or exponential curve\n\t * can be scheduled after. Will cancel events after \n\t * the given time and shorten the currently scheduled\n\t * linear or exponential ramp so that it ends at `time` .\n\t * This is to avoid discontinuities and clicks in envelopes. \n\t * @param {Time} time When to set the ramp point\n\t * @returns {Tone.TimelineSignal} this\n\t */\n\tTone.TimelineSignal.prototype.setRampPoint = function (time) {\n\t\ttime = this.toSeconds(time);\n\t\t//get the value at the given time\n\t\tvar val = this._toUnits(this.getValueAtTime(time));\n\t\t//if there is an event at the given time\n\t\t//and that even is not a \"set\"\n\t\tvar before = this._searchBefore(time);\n\t\tif (before && before.time === time){\n\t\t\t//remove everything after\n\t\t\tthis.cancelScheduledValues(time + this.sampleTime);\n\t\t} else if (before && \n\t\t\t\t before.type === Tone.TimelineSignal.Type.Curve &&\n\t\t\t\t before.time + before.duration > time){\n\t\t\t//if the curve is still playing\n\t\t\t//cancel the curve\n\t\t\tthis.cancelScheduledValues(time);\n\t\t\tthis.linearRampToValueAtTime(val, time);\n\t\t} else {\n\t\t\t//reschedule the next event to end at the given time\n\t\t\tvar after = this._searchAfter(time);\n\t\t\tif (after){\n\t\t\t\t//cancel the next event(s)\n\t\t\t\tthis.cancelScheduledValues(time);\n\t\t\t\tif (after.type === Tone.TimelineSignal.Type.Linear){\n\t\t\t\t\tthis.linearRampToValueAtTime(val, time);\n\t\t\t\t} else if (after.type === Tone.TimelineSignal.Type.Exponential){\n\t\t\t\t\tthis.exponentialRampToValueAtTime(val, time);\n\t\t\t\t}\n\t\t\t}\n\t\t\tthis.setValueAtTime(val, time);\n\t\t}\n\t\treturn this;\n\t};\n\n\t/**\n\t * Do a linear ramp to the given value between the start and finish times.\n\t * @param {Number} value The value to ramp to.\n\t * @param {Time} start The beginning anchor point to do the linear ramp\n\t * @param {Time} finish The ending anchor point by which the value of\n\t * the signal will equal the given value.\n\t * @returns {Tone.TimelineSignal} this\n\t */\n\tTone.TimelineSignal.prototype.linearRampToValueBetween = function (value, start, finish) {\n\t\tthis.setRampPoint(start);\n\t\tthis.linearRampToValueAtTime(value, finish);\n\t\treturn this;\n\t};\n\n\t/**\n\t * Do a exponential ramp to the given value between the start and finish times.\n\t * @param {Number} value The value to ramp to.\n\t * @param {Time} start The beginning anchor point to do the exponential ramp\n\t * @param {Time} finish The ending anchor point by which the value of\n\t * the signal will equal the given value.\n\t * @returns {Tone.TimelineSignal} this\n\t */\n\tTone.TimelineSignal.prototype.exponentialRampToValueBetween = function (value, start, finish) {\n\t\tthis.setRampPoint(start);\n\t\tthis.exponentialRampToValueAtTime(value, finish);\n\t\treturn this;\n\t};\n\n\t///////////////////////////////////////////////////////////////////////////\n\t//\tGETTING SCHEDULED VALUES\n\t///////////////////////////////////////////////////////////////////////////\n\n\t/**\n\t * Returns the value before or equal to the given time\n\t * @param {Number} time The time to query\n\t * @return {Object} The event at or before the given time.\n\t * @private\n\t */\n\tTone.TimelineSignal.prototype._searchBefore = function(time){\n\t\treturn this._events.get(time);\n\t};\n\n\t/**\n\t * The event after the given time\n\t * @param {Number} time The time to query.\n\t * @return {Object} The next event after the given time\n\t * @private\n\t */\n\tTone.TimelineSignal.prototype._searchAfter = function(time){\n\t\treturn this._events.getAfter(time);\n\t};\n\n\t/**\n\t * Get the scheduled value at the given time. This will\n\t * return the unconverted (raw) value.\n\t * @param {Number} time The time in seconds.\n\t * @return {Number} The scheduled value at the given time.\n\t */\n\tTone.TimelineSignal.prototype.getValueAtTime = function(time){\n\t\ttime = this.toSeconds(time);\n\t\tvar after = this._searchAfter(time);\n\t\tvar before = this._searchBefore(time);\n\t\tvar value = this._initial;\n\t\t//if it was set by\n\t\tif (before === null){\n\t\t\tvalue = this._initial;\n\t\t} else if (before.type === Tone.TimelineSignal.Type.Target){\n\t\t\tvar previous = this._events.getBefore(before.time);\n\t\t\tvar previouVal;\n\t\t\tif (previous === null){\n\t\t\t\tpreviouVal = this._initial;\n\t\t\t} else {\n\t\t\t\tpreviouVal = previous.value;\n\t\t\t}\n\t\t\tvalue = this._exponentialApproach(before.time, previouVal, before.value, before.constant, time);\n\t\t} else if (before.type === Tone.TimelineSignal.Type.Curve){\n\t\t\tvalue = this._curveInterpolate(before.time, before.value, before.duration, time);\n\t\t} else if (after === null){\n\t\t\tvalue = before.value;\n\t\t} else if (after.type === Tone.TimelineSignal.Type.Linear){\n\t\t\tvalue = this._linearInterpolate(before.time, before.value, after.time, after.value, time);\n\t\t} else if (after.type === Tone.TimelineSignal.Type.Exponential){\n\t\t\tvalue = this._exponentialInterpolate(before.time, before.value, after.time, after.value, time);\n\t\t} else {\n\t\t\tvalue = before.value;\n\t\t}\n\t\treturn value;\n\t};\n\n\t/**\n\t * When signals connect to other signals or AudioParams, \n\t * they take over the output value of that signal or AudioParam. \n\t * For all other nodes, the behavior is the same as a default connect. \n\t *\n\t * @override\n\t * @param {AudioParam|AudioNode|Tone.Signal|Tone} node \n\t * @param {number} [outputNumber=0] The output number to connect from.\n\t * @param {number} [inputNumber=0] The input number to connect to.\n\t * @returns {Tone.TimelineSignal} this\n\t * @method\n\t */\n\tTone.TimelineSignal.prototype.connect = Tone.SignalBase.prototype.connect;\n\n\n\t///////////////////////////////////////////////////////////////////////////\n\t//\tAUTOMATION CURVE CALCULATIONS\n\t//\tMIT License, copyright (c) 2014 Jordan Santell\n\t///////////////////////////////////////////////////////////////////////////\n\n\t/**\n\t * Calculates the the value along the curve produced by setTargetAtTime\n\t * @private\n\t */\n\tTone.TimelineSignal.prototype._exponentialApproach = function (t0, v0, v1, timeConstant, t) {\n\t\treturn v1 + (v0 - v1) * Math.exp(-(t - t0) / timeConstant);\n\t};\n\n\t/**\n\t * Calculates the the value along the curve produced by linearRampToValueAtTime\n\t * @private\n\t */\n\tTone.TimelineSignal.prototype._linearInterpolate = function (t0, v0, t1, v1, t) {\n\t\treturn v0 + (v1 - v0) * ((t - t0) / (t1 - t0));\n\t};\n\n\t/**\n\t * Calculates the the value along the curve produced by exponentialRampToValueAtTime\n\t * @private\n\t */\n\tTone.TimelineSignal.prototype._exponentialInterpolate = function (t0, v0, t1, v1, t) {\n\t\tv0 = Math.max(this._minOutput, v0);\n\t\treturn v0 * Math.pow(v1 / v0, (t - t0) / (t1 - t0));\n\t};\n\n\t/**\n\t * Calculates the the value along the curve produced by setValueCurveAtTime\n\t * @private\n\t */\n\tTone.TimelineSignal.prototype._curveInterpolate = function (start, curve, duration, time) {\n\t\tvar len = curve.length;\n\t\t// If time is after duration, return the last curve value\n\t\tif (time >= start + duration) {\n\t\t\treturn curve[len - 1];\n\t\t} else if (time <= start){\n\t\t\treturn curve[0];\n\t\t} else {\n\t\t\tvar progress = (time - start) / duration;\n\t\t\tvar lowerIndex = Math.floor((len - 1) * progress);\n\t\t\tvar upperIndex = Math.ceil((len - 1) * progress);\n\t\t\tvar lowerVal = curve[lowerIndex];\n\t\t\tvar upperVal = curve[upperIndex];\n\t\t\tif (upperIndex === lowerIndex){\n\t\t\t\treturn lowerVal;\n\t\t\t} else {\n\t\t\t\treturn this._linearInterpolate(lowerIndex, lowerVal, upperIndex, upperVal, progress * (len - 1));\n\t\t\t}\n\t\t}\n\t};\n\n\t/**\n\t * Clean up.\n\t * @return {Tone.TimelineSignal} this\n\t */\n\tTone.TimelineSignal.prototype.dispose = function(){\n\t\tTone.Signal.prototype.dispose.call(this);\n\t\tTone.Param.prototype.dispose.call(this);\n\t\tthis._events.dispose();\n\t\tthis._events = null;\n\t};\n\n\treturn Tone.TimelineSignal;\n});","'use strict';\n\ndefine(function (require) {\n var Effect = require('effect');\n\n /**\n *
A p5.Filter uses a Web Audio Biquad Filter to filter\n * the frequency response of an input source. Subclasses\n * include:
\n * p5.LowPass:\n * Allows frequencies below the cutoff frequency to pass through,\n * and attenuates frequencies above the cutoff. \n * p5.HighPass:\n * The opposite of a lowpass filter. \n * p5.BandPass:\n * Allows a range of frequencies to pass through and attenuates\n * the frequencies below and above this frequency range. \n *\n * The .res() method controls either width of the\n * bandpass, or resonance of the low/highpass cutoff frequency.\n *\n * This class extends p5.Effect.\n * Methods amp(), chain(),\n * drywet(), connect(), and\n * disconnect() are available.\n *\n * @class p5.Filter\n * @extends p5.Effect\n * @constructor\n * @param {String} [type] 'lowpass' (default), 'highpass', 'bandpass'\n * @example\n *
\n * var fft, noise, filter;\n *\n * function setup() {\n * fill(255, 40, 255);\n *\n * filter = new p5.BandPass();\n *\n * noise = new p5.Noise();\n * // disconnect unfiltered noise,\n * // and connect to filter\n * noise.disconnect();\n * noise.connect(filter);\n * noise.start();\n *\n * fft = new p5.FFT();\n * }\n *\n * function draw() {\n * background(30);\n *\n * // set the BandPass frequency based on mouseX\n * var freq = map(mouseX, 0, width, 20, 10000);\n * filter.freq(freq);\n * // give the filter a narrow band (lower res = wider bandpass)\n * filter.res(50);\n *\n * // draw filtered spectrum\n * var spectrum = fft.analyze();\n * noStroke();\n * for (var i = 0; i < spectrum.length; i++) {\n * var x = map(i, 0, spectrum.length, 0, width);\n * var h = -height + map(spectrum[i], 0, 255, height, 0);\n * rect(x, height, width/spectrum.length, h);\n * }\n *\n * isMouseOverCanvas();\n * }\n *\n * function isMouseOverCanvas() {\n * var mX = mouseX, mY = mouseY;\n * if (mX > 0 && mX < width && mY < height && mY > 0) {\n * noise.amp(0.5, 0.2);\n * } else {\n * noise.amp(0, 0.2);\n * }\n * }\n *
\n */\n p5.Filter = function (type) {\n\n Effect.call(this);\n //add extend Effect by adding a Biquad Filter\n\n /**\n * The p5.Filter is built with a\n * \n * Web Audio BiquadFilter Node.\n *\n * @property {DelayNode} biquadFilter\n\t */\n\n this.biquad = this.ac.createBiquadFilter();\n\n this.input.connect(this.biquad);\n\n this.biquad.connect(this.wet);\n\n if (type) {\n this.setType(type);\n }\n\n //Properties useful for the toggle method.\n this._on = true;\n this._untoggledType = this.biquad.type;\n };\n p5.Filter.prototype = Object.create(Effect.prototype);\n\n\n /**\n * Filter an audio signal according to a set\n * of filter parameters.\n *\n * @method process\n * @param {Object} Signal An object that outputs audio\n * @param {Number} [freq] Frequency in Hz, from 10 to 22050\n * @param {Number} [res] Resonance/Width of the filter frequency\n * from 0.001 to 1000\n */\n p5.Filter.prototype.process = function(src, freq, res, time) {\n src.connect(this.input);\n this.set(freq, res, time);\n };\n\n\n /**\n * Set the frequency and the resonance of the filter.\n *\n * @method set\n * @param {Number} [freq] Frequency in Hz, from 10 to 22050\n * @param {Number} [res] Resonance (Q) from 0.001 to 1000\n * @param {Number} [timeFromNow] schedule this event to happen\n * seconds from now\n */\n p5.Filter.prototype.set = function(freq, res, time) {\n if (freq) {\n this.freq(freq, time);\n }\n if (res) {\n this.res(res, time);\n }\n };\n\n /**\n * Set the filter frequency, in Hz, from 10 to 22050 (the range of\n * human hearing, although in reality most people hear in a narrower\n * range).\n *\n * @method freq\n * @param {Number} freq Filter Frequency\n * @param {Number} [timeFromNow] schedule this event to happen\n * seconds from now\n * @return {Number} value Returns the current frequency value\n */\n p5.Filter.prototype.freq = function(freq, time) {\n var t = time || 0;\n if (freq <= 0) {\n freq = 1;\n }\n if (typeof freq === 'number') {\n this.biquad.frequency.cancelScheduledValues(this.ac.currentTime + 0.01 + t);\n this.biquad.frequency.exponentialRampToValueAtTime(freq, this.ac.currentTime + 0.02 + t);\n } else if (freq) {\n freq.connect(this.biquad.frequency);\n }\n return this.biquad.frequency.value;\n };\n\n /**\n * Controls either width of a bandpass frequency,\n * or the resonance of a low/highpass cutoff frequency.\n *\n * @method res\n * @param {Number} res Resonance/Width of filter freq\n * from 0.001 to 1000\n * @param {Number} [timeFromNow] schedule this event to happen\n * seconds from now\n * @return {Number} value Returns the current res value\n */\n p5.Filter.prototype.res = function(res, time) {\n var t = time || 0;\n if (typeof res === 'number') {\n this.biquad.Q.value = res;\n this.biquad.Q.cancelScheduledValues(this.ac.currentTime + 0.01 + t);\n this.biquad.Q.linearRampToValueAtTime(res, this.ac.currentTime + 0.02 + t);\n } else if (res) {\n res.connect(this.biquad.Q);\n }\n return this.biquad.Q.value;\n };\n\n /**\n * Controls the gain attribute of a Biquad Filter.\n * This is distinctly different from .amp() which is inherited from p5.Effect\n * .amp() controls the volume via the output gain node\n * p5.Filter.gain() controls the gain parameter of a Biquad Filter node.\n *\n * @method gain\n * @param {Number} gain\n * @return {Number} Returns the current or updated gain value\n */\n p5.Filter.prototype.gain = function(gain, time) {\n var t = time || 0;\n if (typeof gain === 'number') {\n this.biquad.gain.value = gain;\n this.biquad.gain.cancelScheduledValues(this.ac.currentTime + 0.01 + t);\n this.biquad.gain.linearRampToValueAtTime(gain, this.ac.currentTime + 0.02 + t);\n } else if (gain) {\n gain.connect(this.biquad.gain);\n }\n return this.biquad.gain.value;\n };\n\n\n /**\n * Toggle function. Switches between the specified type and allpass\n *\n * @method toggle\n * @return {boolean} [Toggle value]\n */\n p5.Filter.prototype.toggle = function() {\n this._on = !this._on;\n\n if (this._on === true) {\n this.biquad.type = this._untoggledType;\n } else if (this._on === false) {\n this.biquad.type = 'allpass';\n }\n\n return this._on;\n };\n\n /**\n * Set the type of a p5.Filter. Possible types include:\n * \"lowpass\" (default), \"highpass\", \"bandpass\",\n * \"lowshelf\", \"highshelf\", \"peaking\", \"notch\",\n * \"allpass\".\n *\n * @method setType\n * @param {String} t\n */\n p5.Filter.prototype.setType = function(t) {\n this.biquad.type = t;\n this._untoggledType = this.biquad.type;\n };\n\n p5.Filter.prototype.dispose = function() {\n // remove reference from soundArray\n Effect.prototype.dispose.apply(this);\n if (this.biquad) {\n this.biquad.disconnect();\n delete this.biquad;\n }\n };\n\n /**\n * Constructor: new p5.LowPass() Filter.\n * This is the same as creating a p5.Filter and then calling\n * its method setType('lowpass').\n * See p5.Filter for methods.\n *\n * @class p5.LowPass\n * @constructor\n * @extends p5.Filter\n */\n p5.LowPass = function() {\n p5.Filter.call(this, 'lowpass');\n };\n p5.LowPass.prototype = Object.create(p5.Filter.prototype);\n\n /**\n * Constructor: new p5.HighPass() Filter.\n * This is the same as creating a p5.Filter and then calling\n * its method setType('highpass').\n * See p5.Filter for methods.\n *\n * @class p5.HighPass\n * @constructor\n * @extends p5.Filter\n */\n p5.HighPass = function() {\n p5.Filter.call(this, 'highpass');\n };\n p5.HighPass.prototype = Object.create(p5.Filter.prototype);\n\n /**\n * Constructor: new p5.BandPass() Filter.\n * This is the same as creating a p5.Filter and then calling\n * its method setType('bandpass').\n * See p5.Filter for methods.\n *\n * @class p5.BandPass\n * @constructor\n * @extends p5.Filter\n */\n p5.BandPass = function() {\n p5.Filter.call(this, 'bandpass');\n };\n p5.BandPass.prototype = Object.create(p5.Filter.prototype);\n\n return p5.Filter;\n});\n","define([\"Tone/core/Tone\", \"Tone/signal/Add\", \"Tone/signal/Negate\", \"Tone/signal/Signal\", \"Tone/core/Gain\"], function(Tone){\n\n\t\"use strict\";\n\n\t/**\n\t * @class Subtract the signal connected to input[1] from the signal connected \n\t * to input[0]. If an argument is provided in the constructor, the \n\t * signals .value will be subtracted from the incoming signal.\n\t *\n\t * @extends {Tone.Signal}\n\t * @constructor\n\t * @param {number=} value The value to subtract from the incoming signal. If the value\n\t * is omitted, it will subtract the second signal from the first.\n\t * @example\n\t * var sub = new Tone.Subtract(1);\n\t * var sig = new Tone.Signal(4).connect(sub);\n\t * //the output of sub is 3. \n\t * @example\n\t * var sub = new Tone.Subtract();\n\t * var sigA = new Tone.Signal(10);\n\t * var sigB = new Tone.Signal(2.5);\n\t * sigA.connect(sub, 0, 0);\n\t * sigB.connect(sub, 0, 1);\n\t * //output of sub is 7.5\n\t */\n\tTone.Subtract = function(value){\n\n\t\tthis.createInsOuts(2, 0);\n\n\t\t/**\n\t\t * the summing node\n\t\t * @type {GainNode}\n\t\t * @private\n\t\t */\n\t\tthis._sum = this.input[0] = this.output = new Tone.Gain();\n\n\t\t/**\n\t\t * negate the input of the second input before connecting it\n\t\t * to the summing node.\n\t\t * @type {Tone.Negate}\n\t\t * @private\n\t\t */\n\t\tthis._neg = new Tone.Negate();\n\n\t\t/**\n\t\t * the node where the value is set\n\t\t * @private\n\t\t * @type {Tone.Signal}\n\t\t */\n\t\tthis._param = this.input[1] = new Tone.Signal(value);\n\n\t\tthis._param.chain(this._neg, this._sum);\n\t};\n\n\tTone.extend(Tone.Subtract, Tone.Signal);\n\n\t/**\n\t * Clean up.\n\t * @returns {Tone.SignalBase} this\n\t */\n\tTone.Subtract.prototype.dispose = function(){\n\t\tTone.prototype.dispose.call(this);\n\t\tthis._neg.dispose();\n\t\tthis._neg = null;\n\t\tthis._sum.disconnect();\n\t\tthis._sum = null;\n\t\tthis._param.dispose();\n\t\tthis._param = null;\n\t\treturn this;\n\t};\n\n\treturn Tone.Subtract;\n});","'use strict';\n\nglobal.TONE_SILENCE_VERSION_LOGGING = true;\n\ndefine(['startaudiocontext', 'Tone/core/Context', 'Tone/core/Tone'], function (StartAudioContext, Context, Tone) {\n // Create the Audio Context\n const audiocontext = new window.AudioContext();\n\n // Tone and p5.sound share the same audio context\n Tone.context.dispose();\n Tone.setContext(audiocontext);\n\n /**\n *
Returns the Audio Context for this sketch. Useful for users\n * who would like to dig deeper into the Web Audio API\n * .
\n *\n *
Some browsers require users to startAudioContext\n * with a user gesture, such as touchStarted in the example below.
\n *\n * @method getAudioContext\n * @return {Object} AudioContext for this sketch\n * @example\n *
\n * function draw() {\n * background(255);\n * textAlign(CENTER);\n *\n * if (getAudioContext().state !== 'running') {\n * text('click to start audio', width/2, height/2);\n * } else {\n * text('audio is enabled', width/2, height/2);\n * }\n * }\n *\n * function touchStarted() {\n * if (getAudioContext().state !== 'running') {\n * getAudioContext().resume();\n * }\n * var synth = new p5.MonoSynth();\n * synth.play('A4', 0.5, 0, 0.2);\n * }\n *\n *
It is a good practice to give users control over starting audio playback.\n * This practice is enforced by Google Chrome's autoplay policy as of r70\n * (info), iOS Safari, and other browsers.\n *
\n *\n *
\n * userStartAudio() starts the Audio Context on a user gesture. It utilizes\n * the StartAudioContext library by\n * Yotam Mann (MIT Licence, 2016). Read more at https://github.com/tambien/StartAudioContext.\n *
\n *\n *
Starting the audio context on a user gesture can be as simple as userStartAudio().\n * Optional parameters let you decide on a specific element that will start the audio context,\n * and/or call a function once the audio context is started.
\n * @param {Element|Array} [element(s)] This argument can be an Element,\n * Selector String, NodeList, p5.Element,\n * jQuery Element, or an Array of any of those.\n * @param {Function} [callback] Callback to invoke when the AudioContext has started\n * @return {Promise} Returns a Promise which is resolved when\n * the AudioContext state is 'running'\n * @method userStartAudio\n * @for p5\n * @example\n *
\n * function setup() {\n * var myDiv = createDiv('click to start audio');\n * myDiv.position(0, 0);\n *\n * var mySynth = new p5.MonoSynth();\n *\n * // This won't play until the context has started\n * mySynth.play('A6');\n *\n * // Start the audio context on a click/touch event\n * userStartAudio().then(function() {\n * myDiv.remove();\n * });\n * }\n *
\n */\n p5.prototype.userStartAudio = function(elements, callback) {\n var elt = elements;\n if (elements instanceof p5.Element) {\n elt = elements.elt;\n } else if (elements instanceof Array && elements[0] instanceof p5.Element ) {\n elt = elements.map(function(e) { return e.elt});\n }\n return StartAudioContext(audiocontext, elt, callback);\n };\n\n return audiocontext;\n});\n","define([\"Tone/core/Tone\"], function (Tone) {\n\n\t\"use strict\";\n\n\t/**\n\t * @class Tone.Emitter gives classes which extend it\n\t * the ability to listen for and emit events. \n\t * Inspiration and reference from Jerome Etienne's [MicroEvent](https://github.com/jeromeetienne/microevent.js).\n\t * MIT (c) 2011 Jerome Etienne.\n\t * \n\t * @extends {Tone}\n\t */\n\tTone.Emitter = function(){\n\t\t/**\n\t\t * Contains all of the events.\n\t\t * @private\n\t\t * @type {Object}\n\t\t */\n\t\tthis._events = {};\n\t};\n\n\tTone.extend(Tone.Emitter);\n\n\t/**\n\t * Bind a callback to a specific event.\n\t * @param {String} event The name of the event to listen for.\n\t * @param {Function} callback The callback to invoke when the\n\t * event is emitted\n\t * @return {Tone.Emitter} this\n\t */\n\tTone.Emitter.prototype.on = function(event, callback){\n\t\t//split the event\n\t\tvar events = event.split(/\\W+/);\n\t\tfor (var i = 0; i < events.length; i++){\n\t\t\tvar eventName = events[i];\n\t\t\tif (!this._events.hasOwnProperty(eventName)){\n\t\t\t\tthis._events[eventName] = [];\n\t\t\t}\n\t\t\tthis._events[eventName].push(callback);\n\t\t}\n\t\treturn this;\n\t};\n\n\t/**\n\t * Remove the event listener.\n\t * @param {String} event The event to stop listening to.\n\t * @param {Function=} callback The callback which was bound to \n\t * the event with Tone.Emitter.on.\n\t * If no callback is given, all callbacks\n\t * events are removed.\n\t * @return {Tone.Emitter} this\n\t */\n\tTone.Emitter.prototype.off = function(event, callback){\n\t\tvar events = event.split(/\\W+/);\n\t\tfor (var ev = 0; ev < events.length; ev++){\n\t\t\tevent = events[ev];\n\t\t\tif (this._events.hasOwnProperty(event)){\n\t\t\t\tif (Tone.prototype.isUndef(callback)){\n\t\t\t\t\tthis._events[event] = [];\n\t\t\t\t} else {\n\t\t\t\t\tvar eventList = this._events[event];\n\t\t\t\t\tfor (var i = 0; i < eventList.length; i++){\n\t\t\t\t\t\tif (eventList[i] === callback){\n\t\t\t\t\t\t\teventList.splice(i, 1);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\treturn this;\n\t};\n\n\t/**\n\t * Invoke all of the callbacks bound to the event\n\t * with any arguments passed in. \n\t * @param {String} event The name of the event.\n\t * @param {*...} args The arguments to pass to the functions listening.\n\t * @return {Tone.Emitter} this\n\t */\n\tTone.Emitter.prototype.emit = function(event){\n\t\tif (this._events){\n\t\t\tvar args = Array.apply(null, arguments).slice(1);\n\t\t\tif (this._events.hasOwnProperty(event)){\n\t\t\t\tvar eventList = this._events[event];\n\t\t\t\tfor (var i = 0, len = eventList.length; i < len; i++){\n\t\t\t\t\teventList[i].apply(this, args);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\treturn this;\n\t};\n\n\t/**\n\t * Add Emitter functions (on/off/emit) to the object\n\t * @param {Object|Function} object The object or class to extend.\n\t */\n\tTone.Emitter.mixin = function(object){\n\t\tvar functions = [\"on\", \"off\", \"emit\"];\n\t\tobject._events = {};\n\t\tfor (var i = 0; i < functions.length; i++){\n\t\t\tvar func = functions[i];\n\t\t\tvar emitterFunc = Tone.Emitter.prototype[func];\n\t\t\tobject[func] = emitterFunc;\n\t\t}\n\t};\n\n\t/**\n\t * Clean up\n\t * @return {Tone.Emitter} this\n\t */\n\tTone.Emitter.prototype.dispose = function(){\n\t\tTone.prototype.dispose.call(this);\n\t\tthis._events = null;\n\t\treturn this;\n\t};\n\n\treturn Tone.Emitter;\n});","define([\"Tone/core/Tone\"], function(Tone){\n\n\t\"use strict\";\n\n\t/**\n\t * @class Base class for all Signals. Used Internally. \n\t *\n\t * @constructor\n\t * @extends {Tone}\n\t */\n\tTone.SignalBase = function(){};\n\n\tTone.extend(Tone.SignalBase);\n\n\t/**\n\t * When signals connect to other signals or AudioParams, \n\t * they take over the output value of that signal or AudioParam. \n\t * For all other nodes, the behavior is the same as a default connect. \n\t *\n\t * @override\n\t * @param {AudioParam|AudioNode|Tone.Signal|Tone} node \n\t * @param {number} [outputNumber=0] The output number to connect from.\n\t * @param {number} [inputNumber=0] The input number to connect to.\n\t * @returns {Tone.SignalBase} this\n\t */\n\tTone.SignalBase.prototype.connect = function(node, outputNumber, inputNumber){\n\t\t//zero it out so that the signal can have full control\n\t\tif ((Tone.Signal && Tone.Signal === node.constructor) || \n\t\t\t\t(Tone.Param && Tone.Param === node.constructor) || \n\t\t\t\t(Tone.TimelineSignal && Tone.TimelineSignal === node.constructor)){\n\t\t\t//cancel changes\n\t\t\tnode._param.cancelScheduledValues(0);\n\t\t\t//reset the value\n\t\t\tnode._param.value = 0;\n\t\t\t//mark the value as overridden\n\t\t\tnode.overridden = true;\n\t\t} else if (node instanceof AudioParam){\n\t\t\tnode.cancelScheduledValues(0);\n\t\t\tnode.value = 0;\n\t\t} \n\t\tTone.prototype.connect.call(this, node, outputNumber, inputNumber);\n\t\treturn this;\n\t};\n\n\treturn Tone.SignalBase;\n});","define([\"Tone/core/Tone\", \"Tone/type/TimeBase\"], function (Tone) {\n\n\t/**\n\t * @class Tone.Time is a primitive type for encoding Time values. \n\t * Eventually all time values are evaluated to seconds\n\t * using the `eval` method. Tone.Time can be constructed\n\t * with or without the `new` keyword. Tone.Time can be passed\n\t * into the parameter of any method which takes time as an argument. \n\t * @constructor\n\t * @extends {Tone.TimeBase}\n\t * @param {String|Number} val The time value.\n\t * @param {String=} units The units of the value.\n\t * @example\n\t * var t = Tone.Time(\"4n\");//encodes a quarter note\n\t * t.mult(4); // multiply that value by 4\n\t * t.toNotation(); //returns \"1m\"\n\t */\n\tTone.Time = function(val, units){\n\t\tif (this instanceof Tone.Time){\n\n\t\t\t/**\n\t\t\t * If the current clock time should\n\t\t\t * be added to the output\n\t\t\t * @type {Boolean}\n\t\t\t * @private\n\t\t\t */\n\t\t\tthis._plusNow = false;\n\t\t\t\n\t\t\tTone.TimeBase.call(this, val, units);\n\n\t\t} else {\n\t\t\treturn new Tone.Time(val, units);\n\t\t}\n\t};\n\n\tTone.extend(Tone.Time, Tone.TimeBase);\n\n\t//clone the expressions so that \n\t//we can add more without modifying the original\n\tTone.Time.prototype._unaryExpressions = Object.create(Tone.TimeBase.prototype._unaryExpressions);\n\n\t/*\n\t * Adds an additional unary expression\n\t * which quantizes values to the next subdivision\n\t * @type {Object}\n\t * @private\n\t */\n\tTone.Time.prototype._unaryExpressions.quantize = {\n\t\tregexp : /^@/,\n\t\tmethod : function(rh){\n\t\t\treturn Tone.Transport.nextSubdivision(rh());\n\t\t}\n\t};\n\n\t/*\n\t * Adds an additional unary expression\n\t * which adds the current clock time.\n\t * @type {Object}\n\t * @private\n\t */\n\tTone.Time.prototype._unaryExpressions.now = {\n\t\tregexp : /^\\+/,\n\t\tmethod : function(lh){\n\t\t\tthis._plusNow = true;\n\t\t\treturn lh();\n\t\t}\n\t};\n\n\t/**\n\t * Quantize the time by the given subdivision. Optionally add a\n\t * percentage which will move the time value towards the ideal\n\t * quantized value by that percentage. \n\t * @param {Number|Time} val The subdivision to quantize to\n\t * @param {NormalRange} [percent=1] Move the time value\n\t * towards the quantized value by\n\t * a percentage.\n\t * @return {Tone.Time} this\n\t * @example\n\t * Tone.Time(21).quantize(2) //returns 22\n\t * Tone.Time(0.6).quantize(\"4n\", 0.5) //returns 0.55\n\t */\n\tTone.Time.prototype.quantize = function(subdiv, percent){\n\t\tpercent = this.defaultArg(percent, 1);\n\t\tthis._expr = function(expr, subdivision, percent){\n\t\t\texpr = expr();\n\t\t\tsubdivision = subdivision.toSeconds();\n\t\t\tvar multiple = Math.round(expr / subdivision);\n\t\t\tvar ideal = multiple * subdivision;\n\t\t\tvar diff = ideal - expr;\n\t\t\treturn expr + diff * percent;\n\t\t}.bind(this, this._expr, new this.constructor(subdiv), percent);\n\t\treturn this;\n\t};\n\n\t/**\n\t * Adds the clock time to the time expression at the \n\t * moment of evaluation. \n\t * @return {Tone.Time} this\n\t */\n\tTone.Time.prototype.addNow = function(){\n\t\tthis._plusNow = true;\n\t\treturn this;\n\t};\n\n\t/**\n\t * @override\n\t * Override the default value return when no arguments are passed in.\n\t * The default value is 'now'\n\t * @private\n\t */\n\tTone.Time.prototype._defaultExpr = function(){\n\t\tthis._plusNow = true;\n\t\treturn this._noOp;\n\t};\n\n\t/**\n\t * Copies the value of time to this Time\n\t * @param {Tone.Time} time\n\t * @return {Time}\n\t */\n\tTone.Time.prototype.copy = function(time){\n\t\tTone.TimeBase.prototype.copy.call(this, time);\n\t\tthis._plusNow = time._plusNow;\n\t\treturn this;\n\t};\n\n\t//CONVERSIONS//////////////////////////////////////////////////////////////\n\n\t/**\n\t * Convert a Time to Notation. Values will be thresholded to the nearest 128th note. \n\t * @return {Notation} \n\t * @example\n\t * //if the Transport is at 120bpm:\n\t * Tone.Time(2).toNotation();//returns \"1m\"\n\t */\n\tTone.Time.prototype.toNotation = function(){\n\t\tvar time = this.toSeconds();\n\t\tvar testNotations = [\"1m\", \"2n\", \"4n\", \"8n\", \"16n\", \"32n\", \"64n\", \"128n\"];\n\t\tvar retNotation = this._toNotationHelper(time, testNotations);\n\t\t//try the same thing but with tripelets\n\t\tvar testTripletNotations = [\"1m\", \"2n\", \"2t\", \"4n\", \"4t\", \"8n\", \"8t\", \"16n\", \"16t\", \"32n\", \"32t\", \"64n\", \"64t\", \"128n\"];\n\t\tvar retTripletNotation = this._toNotationHelper(time, testTripletNotations);\n\t\t//choose the simpler expression of the two\n\t\tif (retTripletNotation.split(\"+\").length < retNotation.split(\"+\").length){\n\t\t\treturn retTripletNotation;\n\t\t} else {\n\t\t\treturn retNotation;\n\t\t}\n\t};\n\n\t/**\n\t * Helper method for Tone.toNotation\n\t * @param {Number} units \n\t * @param {Array} testNotations\n\t * @return {String}\n\t * @private\n\t */\n\tTone.Time.prototype._toNotationHelper = function(units, testNotations){\n\t\t//the threshold is the last value in the array\n\t\tvar threshold = this._notationToUnits(testNotations[testNotations.length - 1]);\n\t\tvar retNotation = \"\";\n\t\tfor (var i = 0; i < testNotations.length; i++){\n\t\t\tvar notationTime = this._notationToUnits(testNotations[i]);\n\t\t\t//account for floating point errors (i.e. round up if the value is 0.999999)\n\t\t\tvar multiple = units / notationTime;\n\t\t\tvar floatingPointError = 0.000001;\n\t\t\tif (1 - multiple % 1 < floatingPointError){\n\t\t\t\tmultiple += floatingPointError;\n\t\t\t}\n\t\t\tmultiple = Math.floor(multiple);\n\t\t\tif (multiple > 0){\n\t\t\t\tif (multiple === 1){\n\t\t\t\t\tretNotation += testNotations[i];\n\t\t\t\t} else {\n\t\t\t\t\tretNotation += multiple.toString() + \"*\" + testNotations[i];\n\t\t\t\t}\n\t\t\t\tunits -= multiple * notationTime;\n\t\t\t\tif (units < threshold){\n\t\t\t\t\tbreak;\n\t\t\t\t} else {\n\t\t\t\t\tretNotation += \" + \";\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tif (retNotation === \"\"){\n\t\t\tretNotation = \"0\";\n\t\t}\n\t\treturn retNotation;\n\t};\n\n\t/**\n\t * Convert a notation value to the current units\n\t * @param {Notation} notation \n\t * @return {Number} \n\t * @private\n\t */\n\tTone.Time.prototype._notationToUnits = function(notation){\n\t\tvar primaryExprs = this._primaryExpressions;\n\t\tvar notationExprs = [primaryExprs.n, primaryExprs.t, primaryExprs.m];\n\t\tfor (var i = 0; i < notationExprs.length; i++){\n\t\t\tvar expr = notationExprs[i];\n\t\t\tvar match = notation.match(expr.regexp);\n\t\t\tif (match){\n\t\t\t\treturn expr.method.call(this, match[1]);\n\t\t\t}\n\t\t}\n\t};\n\n\t/**\n\t * Return the time encoded as Bars:Beats:Sixteenths.\n\t * @return {BarsBeatsSixteenths}\n\t */\n\tTone.Time.prototype.toBarsBeatsSixteenths = function(){\n\t\tvar quarterTime = this._beatsToUnits(1);\n\t\tvar quarters = this.toSeconds() / quarterTime;\n\t\tvar measures = Math.floor(quarters / this._timeSignature());\n\t\tvar sixteenths = (quarters % 1) * 4;\n\t\tquarters = Math.floor(quarters) % this._timeSignature();\n\t\tsixteenths = sixteenths.toString();\n\t\tif (sixteenths.length > 3){\n\t\t\tsixteenths = parseFloat(sixteenths).toFixed(3);\n\t\t}\n\t\tvar progress = [measures, quarters, sixteenths];\n\t\treturn progress.join(\":\");\n\t};\n\n\t/**\n\t * Return the time in ticks.\n\t * @return {Ticks}\n\t */\n\tTone.Time.prototype.toTicks = function(){\n\t\tvar quarterTime = this._beatsToUnits(1);\n\t\tvar quarters = this.valueOf() / quarterTime;\n\t\treturn Math.floor(quarters * Tone.Transport.PPQ);\n\t};\n\n\t/**\n\t * Return the time in samples\n\t * @return {Samples} \n\t */\n\tTone.Time.prototype.toSamples = function(){\n\t\treturn this.toSeconds() * this.context.sampleRate;\n\t};\n\n\t/**\n\t * Return the time as a frequency value\n\t * @return {Frequency} \n\t * @example\n\t * Tone.Time(2).toFrequency(); //0.5\n\t */\n\tTone.Time.prototype.toFrequency = function(){\n\t\treturn 1/this.toSeconds();\n\t};\n\n\t/**\n\t * Return the time in seconds.\n\t * @return {Seconds} \n\t */\n\tTone.Time.prototype.toSeconds = function(){\n\t\treturn this.valueOf();\n\t};\n\n\t/**\n\t * Return the time in milliseconds.\n\t * @return {Milliseconds} \n\t */\n\tTone.Time.prototype.toMilliseconds = function(){\n\t\treturn this.toSeconds() * 1000;\n\t};\n\n\t/**\n\t * Return the time in seconds.\n\t * @return {Seconds} \n\t */\n\tTone.Time.prototype.valueOf = function(){\n\t\tvar val = this._expr();\n\t\treturn val + (this._plusNow?this.now():0);\n\t};\n\n\treturn Tone.Time;\n});","define([\"Tone/core/Tone\"], function (Tone) {\n\n\t/**\n\t * @class Tone.TimeBase is a flexible encoding of time\n\t * which can be evaluated to and from a string.\n\t * Parsing code modified from https://code.google.com/p/tapdigit/\n\t * Copyright 2011 2012 Ariya Hidayat, New BSD License\n\t * @extends {Tone}\n\t * @param {Time} val The time value as a number or string\n\t * @param {String=} units Unit values\n\t * @example\n\t * Tone.TimeBase(4, \"n\")\n\t * Tone.TimeBase(2, \"t\")\n\t * Tone.TimeBase(\"2t\").add(\"1m\")\n\t * Tone.TimeBase(\"2t + 1m\");\n\t */\n\tTone.TimeBase = function(val, units){\n\n\t\t//allows it to be constructed with or without 'new'\n\t\tif (this instanceof Tone.TimeBase) {\n\n\t\t\t/**\n\t\t\t * Any expressions parsed from the Time\n\t\t\t * @type {Array}\n\t\t\t * @private\n\t\t\t */\n\t\t\tthis._expr = this._noOp;\n\n\t\t\tif (val instanceof Tone.TimeBase){\n\t\t\t\tthis.copy(val);\n\t\t\t} else if (!this.isUndef(units) || this.isNumber(val)){\n\t\t\t\t//default units\n\t\t\t\tunits = this.defaultArg(units, this._defaultUnits);\n\t\t\t\tvar method = this._primaryExpressions[units].method;\n\t\t\t\tthis._expr = method.bind(this, val);\n\t\t\t} else if (this.isString(val)){\n\t\t\t\tthis.set(val);\n\t\t\t} else if (this.isUndef(val)){\n\t\t\t\t//default expression\n\t\t\t\tthis._expr = this._defaultExpr();\n\t\t\t}\n\t\t} else {\n\n\t\t\treturn new Tone.TimeBase(val, units);\n\t\t}\n\t};\n\n\tTone.extend(Tone.TimeBase);\n\n\t/**\n\t * Repalce the current time value with the value\n\t * given by the expression string.\n\t * @param {String} exprString\n\t * @return {Tone.TimeBase} this\n\t */\n\tTone.TimeBase.prototype.set = function(exprString){\n\t\tthis._expr = this._parseExprString(exprString);\n\t\treturn this;\n\t};\n\n\t/**\n\t * Return a clone of the TimeBase object.\n\t * @return {Tone.TimeBase} The new cloned Tone.TimeBase\n\t */\n\tTone.TimeBase.prototype.clone = function(){\n\t\tvar instance = new this.constructor();\n\t\tinstance.copy(this);\n\t\treturn instance;\n\t};\n\n\t/**\n\t * Copies the value of time to this Time\n\t * @param {Tone.TimeBase} time\n\t * @return {TimeBase}\n\t */\n\tTone.TimeBase.prototype.copy = function(time){\n\t\tvar val = time._expr();\n\t\treturn this.set(val);\n\t};\n\n\t///////////////////////////////////////////////////////////////////////////\n\t//\tABSTRACT SYNTAX TREE PARSER\n\t///////////////////////////////////////////////////////////////////////////\n\n\t/**\n\t * All the primary expressions.\n\t * @private\n\t * @type {Object}\n\t */\n\tTone.TimeBase.prototype._primaryExpressions = {\n\t\t\"n\" : {\n\t\t\tregexp : /^(\\d+)n/i,\n\t\t\tmethod : function(value){\n\t\t\t\tvalue = parseInt(value);\n\t\t\t\tif (value === 1){\n\t\t\t\t\treturn this._beatsToUnits(this._timeSignature());\n\t\t\t\t} else {\n\t\t\t\t\treturn this._beatsToUnits(4 / value);\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\t\t\"t\" : {\n\t\t\tregexp : /^(\\d+)t/i,\n\t\t\tmethod : function(value){\n\t\t\t\tvalue = parseInt(value);\n\t\t\t\treturn this._beatsToUnits(8 / (parseInt(value) * 3));\n\t\t\t}\n\t\t},\n\t\t\"m\" : {\n\t\t\tregexp : /^(\\d+)m/i,\n\t\t\tmethod : function(value){\n\t\t\t\treturn this._beatsToUnits(parseInt(value) * this._timeSignature());\n\t\t\t}\n\t\t},\n\t\t\"i\" : {\n\t\t\tregexp : /^(\\d+)i/i,\n\t\t\tmethod : function(value){\n\t\t\t\treturn this._ticksToUnits(parseInt(value));\n\t\t\t}\n\t\t},\n\t\t\"hz\" : {\n\t\t\tregexp : /^(\\d+(?:\\.\\d+)?)hz/i,\n\t\t\tmethod : function(value){\n\t\t\t\treturn this._frequencyToUnits(parseFloat(value));\n\t\t\t}\n\t\t},\n\t\t\"tr\" : {\n\t\t\tregexp : /^(\\d+(?:\\.\\d+)?):(\\d+(?:\\.\\d+)?):?(\\d+(?:\\.\\d+)?)?/,\n\t\t\tmethod : function(m, q, s){\n\t\t\t\tvar total = 0;\n\t\t\t\tif (m && m !== \"0\"){\n\t\t\t\t\ttotal += this._beatsToUnits(this._timeSignature() * parseFloat(m));\n\t\t\t\t}\n\t\t\t\tif (q && q !== \"0\"){\n\t\t\t\t\ttotal += this._beatsToUnits(parseFloat(q));\n\t\t\t\t}\n\t\t\t\tif (s && s !== \"0\"){\n\t\t\t\t\ttotal += this._beatsToUnits(parseFloat(s) / 4);\n\t\t\t\t}\n\t\t\t\treturn total;\n\t\t\t}\n\t\t},\n\t\t\"s\" : {\n\t\t\tregexp : /^(\\d+(?:\\.\\d+)?s)/,\n\t\t\tmethod : function(value){\n\t\t\t\treturn this._secondsToUnits(parseFloat(value));\n\t\t\t}\n\t\t},\n\t\t\"samples\" : {\n\t\t\tregexp : /^(\\d+)samples/,\n\t\t\tmethod : function(value){\n\t\t\t\treturn parseInt(value) / this.context.sampleRate;\n\t\t\t}\n\t\t},\n\t\t\"default\" : {\n\t\t\tregexp : /^(\\d+(?:\\.\\d+)?)/,\n\t\t\tmethod : function(value){\n\t\t\t\treturn this._primaryExpressions[this._defaultUnits].method.call(this, value);\n\t\t\t}\n\t\t}\n\t};\n\n\t/**\n\t * All the binary expressions that TimeBase can accept.\n\t * @private\n\t * @type {Object}\n\t */\n\tTone.TimeBase.prototype._binaryExpressions = {\n\t\t\"+\" : {\n\t\t\tregexp : /^\\+/,\n\t\t\tprecedence : 2,\n\t\t\tmethod : function(lh, rh){\n\t\t\t\treturn lh() + rh();\n\t\t\t}\n\t\t},\n\t\t\"-\" : {\n\t\t\tregexp : /^\\-/,\n\t\t\tprecedence : 2,\n\t\t\tmethod : function(lh, rh){\n\t\t\t\treturn lh() - rh();\n\t\t\t}\n\t\t},\n\t\t\"*\" : {\n\t\t\tregexp : /^\\*/,\n\t\t\tprecedence : 1,\n\t\t\tmethod : function(lh, rh){\n\t\t\t\treturn lh() * rh();\n\t\t\t}\n\t\t},\n\t\t\"/\" : {\n\t\t\tregexp : /^\\//,\n\t\t\tprecedence : 1,\n\t\t\tmethod : function(lh, rh){\n\t\t\t\treturn lh() / rh();\n\t\t\t}\n\t\t}\n\t};\n\n\t/**\n\t * All the unary expressions.\n\t * @private\n\t * @type {Object}\n\t */\n\tTone.TimeBase.prototype._unaryExpressions = {\n\t\t\"neg\" : {\n\t\t\tregexp : /^\\-/,\n\t\t\tmethod : function(lh){\n\t\t\t\treturn -lh();\n\t\t\t}\n\t\t}\n\t};\n\n\t/**\n\t * Syntactic glue which holds expressions together\n\t * @private\n\t * @type {Object}\n\t */\n\tTone.TimeBase.prototype._syntaxGlue = {\n\t\t\"(\" : {\n\t\t\tregexp : /^\\(/\n\t\t},\n\t\t\")\" : {\n\t\t\tregexp : /^\\)/\n\t\t}\n\t};\n\n\t/**\n\t * tokenize the expression based on the Expressions object\n\t * @param {string} expr \n\t * @return {Object} returns two methods on the tokenized list, next and peek\n\t * @private\n\t */\n\tTone.TimeBase.prototype._tokenize = function(expr){\n\t\tvar position = -1;\n\t\tvar tokens = [];\n\n\t\twhile(expr.length > 0){\n\t\t\texpr = expr.trim();\n\t\t\tvar token = getNextToken(expr, this);\n\t\t\ttokens.push(token);\n\t\t\texpr = expr.substr(token.value.length);\n\t\t}\n\n\t\tfunction getNextToken(expr, context){\n\t\t\tvar expressions = [\"_binaryExpressions\", \"_unaryExpressions\", \"_primaryExpressions\", \"_syntaxGlue\"];\n\t\t\tfor (var i = 0; i < expressions.length; i++){\n\t\t\t\tvar group = context[expressions[i]];\n\t\t\t\tfor (var opName in group){\n\t\t\t\t\tvar op = group[opName];\n\t\t\t\t\tvar reg = op.regexp;\n\t\t\t\t\tvar match = expr.match(reg);\n\t\t\t\t\tif (match !== null){\n\t\t\t\t\t\treturn {\n\t\t\t\t\t\t\tmethod : op.method,\n\t\t\t\t\t\t\tprecedence : op.precedence,\n\t\t\t\t\t\t\tregexp : op.regexp,\n\t\t\t\t\t\t\tvalue : match[0],\n\t\t\t\t\t\t};\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\tthrow new SyntaxError(\"Tone.TimeBase: Unexpected token \"+expr);\n\t\t}\n\n\t\treturn {\n\t\t\tnext : function(){\n\t\t\t\treturn tokens[++position];\n\t\t\t},\n\t\t\tpeek : function(){\n\t\t\t\treturn tokens[position + 1];\n\t\t\t}\n\t\t};\n\t};\n\n\t/**\n\t * Given a token, find the value within the groupName\n\t * @param {Object} token\n\t * @param {String} groupName\n\t * @param {Number} precedence\n\t * @private\n\t */\n\tTone.TimeBase.prototype._matchGroup = function(token, group, prec) {\n\t\tvar ret = false;\n\t\tif (!this.isUndef(token)){\n\t\t\tfor (var opName in group){\n\t\t\t\tvar op = group[opName];\n\t\t\t\tif (op.regexp.test(token.value)){\n\t\t\t\t\tif (!this.isUndef(prec)){\n\t\t\t\t\t\tif(op.precedence === prec){\t\n\t\t\t\t\t\t\treturn op;\n\t\t\t\t\t\t}\n\t\t\t\t\t} else {\n\t\t\t\t\t\treturn op;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\treturn ret;\n\t};\n\n\t/**\n\t * Match a binary expression given the token and the precedence\n\t * @param {Lexer} lexer\n\t * @param {Number} precedence\n\t * @private\n\t */\n\tTone.TimeBase.prototype._parseBinary = function(lexer, precedence){\n\t\tif (this.isUndef(precedence)){\n\t\t\tprecedence = 2;\n\t\t}\n\t\tvar expr;\n\t\tif (precedence < 0){\n\t\t\texpr = this._parseUnary(lexer);\n\t\t} else {\n\t\t\texpr = this._parseBinary(lexer, precedence - 1);\n\t\t}\n\t\tvar token = lexer.peek();\n\t\twhile (token && this._matchGroup(token, this._binaryExpressions, precedence)){\n\t\t\ttoken = lexer.next();\n\t\t\texpr = token.method.bind(this, expr, this._parseBinary(lexer, precedence - 1));\n\t\t\ttoken = lexer.peek();\n\t\t}\n\t\treturn expr;\n\t};\n\n\t/**\n\t * Match a unary expression.\n\t * @param {Lexer} lexer\n\t * @private\n\t */\n\tTone.TimeBase.prototype._parseUnary = function(lexer){\n\t\tvar token, expr;\n\t\ttoken = lexer.peek();\n\t\tvar op = this._matchGroup(token, this._unaryExpressions);\n\t\tif (op) {\n\t\t\ttoken = lexer.next();\n\t\t\texpr = this._parseUnary(lexer);\n\t\t\treturn op.method.bind(this, expr);\n\t\t}\n\t\treturn this._parsePrimary(lexer);\n\t};\n\n\t/**\n\t * Match a primary expression (a value).\n\t * @param {Lexer} lexer\n\t * @private\n\t */\n\tTone.TimeBase.prototype._parsePrimary = function(lexer){\n\t\tvar token, expr;\n\t\ttoken = lexer.peek();\n\t\tif (this.isUndef(token)) {\n\t\t\tthrow new SyntaxError(\"Tone.TimeBase: Unexpected end of expression\");\n\t\t}\n\t\tif (this._matchGroup(token, this._primaryExpressions)) {\n\t\t\ttoken = lexer.next();\n\t\t\tvar matching = token.value.match(token.regexp);\n\t\t\treturn token.method.bind(this, matching[1], matching[2], matching[3]);\n\t\t}\n\t\tif (token && token.value === \"(\"){\n\t\t\tlexer.next();\n\t\t\texpr = this._parseBinary(lexer);\n\t\t\ttoken = lexer.next();\n\t\t\tif (!(token && token.value === \")\")) {\n\t\t\t\tthrow new SyntaxError(\"Expected )\");\n\t\t\t}\n\t\t\treturn expr;\n\t\t}\n\t\tthrow new SyntaxError(\"Tone.TimeBase: Cannot process token \" + token.value);\n\t};\n\n\t/**\n\t * Recursively parse the string expression into a syntax tree.\n\t * @param {string} expr \n\t * @return {Function} the bound method to be evaluated later\n\t * @private\n\t */\n\tTone.TimeBase.prototype._parseExprString = function(exprString){\n\t\tif (!this.isString(exprString)){\n\t\t\texprString = exprString.toString();\n\t\t}\n\t\tvar lexer = this._tokenize(exprString);\n\t\tvar tree = this._parseBinary(lexer);\n\t\treturn tree;\n\t};\n\n\t///////////////////////////////////////////////////////////////////////////\n\t//\tDEFAULTS\n\t///////////////////////////////////////////////////////////////////////////\n\n\t/**\n\t * The initial expression value\n\t * @return {Number} The initial value 0\n\t * @private\n\t */\n\tTone.TimeBase.prototype._noOp = function(){\n\t\treturn 0;\n\t};\n\n\t/**\n\t * The default expression value if no arguments are given\n\t * @private\n\t */\n\tTone.TimeBase.prototype._defaultExpr = function(){\n\t\treturn this._noOp;\n\t};\n\n\t/**\n\t * The default units if none are given.\n\t * @private\n\t */\n\tTone.TimeBase.prototype._defaultUnits = \"s\";\n\n\t///////////////////////////////////////////////////////////////////////////\n\t//\tUNIT CONVERSIONS\n\t///////////////////////////////////////////////////////////////////////////\n\n\t/**\n\t * Returns the value of a frequency in the current units\n\t * @param {Frequency} freq\n\t * @return {Number}\n\t * @private\n\t */\n\tTone.TimeBase.prototype._frequencyToUnits = function(freq){\n\t\treturn 1/freq;\n\t};\n\n\t/**\n\t * Return the value of the beats in the current units\n\t * @param {Number} beats\n\t * @return {Number}\n\t * @private\n\t */\n\tTone.TimeBase.prototype._beatsToUnits = function(beats){\n\t\treturn (60 / Tone.Transport.bpm.value) * beats;\n\t};\n\n\t/**\n\t * Returns the value of a second in the current units\n\t * @param {Seconds} seconds\n\t * @return {Number}\n\t * @private\n\t */\n\tTone.TimeBase.prototype._secondsToUnits = function(seconds){\n\t\treturn seconds;\n\t};\n\n\t/**\n\t * Returns the value of a tick in the current time units\n\t * @param {Ticks} ticks\n\t * @return {Number}\n\t * @private\n\t */\n\tTone.TimeBase.prototype._ticksToUnits = function(ticks){\n\t\treturn ticks * (this._beatsToUnits(1) / Tone.Transport.PPQ);\n\t};\n\n\t/**\n\t * Return the time signature.\n\t * @return {Number}\n\t * @private\n\t */\n\tTone.TimeBase.prototype._timeSignature = function(){\n\t\treturn Tone.Transport.timeSignature;\n\t};\n\n\t///////////////////////////////////////////////////////////////////////////\n\t//\tEXPRESSIONS\n\t///////////////////////////////////////////////////////////////////////////\n\n\t/**\n\t * Push an expression onto the expression list\n\t * @param {Time} val\n\t * @param {String} type\n\t * @param {String} units\n\t * @return {Tone.TimeBase} \n\t * @private\n\t */\n\tTone.TimeBase.prototype._pushExpr = function(val, name, units){\n\t\t//create the expression\n\t\tif (!(val instanceof Tone.TimeBase)){\n\t\t\tval = new this.constructor(val, units);\n\t\t}\n\t\tthis._expr = this._binaryExpressions[name].method.bind(this, this._expr, val._expr);\n\t\treturn this;\n\t};\n\n\t/**\n\t * Add to the current value.\n\t * @param {Time} val The value to add\n\t * @param {String=} units Optional units to use with the value.\n\t * @return {Tone.TimeBase} this\n\t * @example\n\t * Tone.TimeBase(\"2m\").add(\"1m\"); //\"3m\"\n\t */\n\tTone.TimeBase.prototype.add = function(val, units){\n\t\treturn this._pushExpr(val, \"+\", units);\n\t};\n\n\t/**\n\t * Subtract the value from the current time.\n\t * @param {Time} val The value to subtract\n\t * @param {String=} units Optional units to use with the value.\n\t * @return {Tone.TimeBase} this\n\t * @example\n\t * Tone.TimeBase(\"2m\").sub(\"1m\"); //\"1m\"\n\t */\n\tTone.TimeBase.prototype.sub = function(val, units){\n\t\treturn this._pushExpr(val, \"-\", units);\n\t};\n\n\t/**\n\t * Multiply the current value by the given time.\n\t * @param {Time} val The value to multiply\n\t * @param {String=} units Optional units to use with the value.\n\t * @return {Tone.TimeBase} this\n\t * @example\n\t * Tone.TimeBase(\"2m\").mult(\"2\"); //\"4m\"\n\t */\n\tTone.TimeBase.prototype.mult = function(val, units){\n\t\treturn this._pushExpr(val, \"*\", units);\n\t};\n\n\t/**\n\t * Divide the current value by the given time.\n\t * @param {Time} val The value to divide by\n\t * @param {String=} units Optional units to use with the value.\n\t * @return {Tone.TimeBase} this\n\t * @example\n\t * Tone.TimeBase(\"2m\").div(2); //\"1m\"\n\t */\n\tTone.TimeBase.prototype.div = function(val, units){\n\t\treturn this._pushExpr(val, \"/\", units);\n\t};\n\n\t/**\n\t * Evaluate the time value. Returns the time\n\t * in seconds.\n\t * @return {Seconds} \n\t */\n\tTone.TimeBase.prototype.valueOf = function(){\n\t\treturn this._expr();\n\t};\n\n\t/**\n\t * Clean up\n\t * @return {Tone.TimeBase} this\n\t */\n\tTone.TimeBase.prototype.dispose = function(){\n\t\tthis._expr = null;\n\t};\n\n\treturn Tone.TimeBase;\n});","define([\"Tone/core/Tone\", \"Tone/type/Type\"], function(Tone){\n\n\t\"use strict\";\n\n\t/**\n\t * @class Tone.Param wraps the native Web Audio's AudioParam to provide\n\t * additional unit conversion functionality. It also\n\t * serves as a base-class for classes which have a single,\n\t * automatable parameter. \n\t * @extends {Tone}\n\t * @param {AudioParam} param The parameter to wrap.\n\t * @param {Tone.Type} units The units of the audio param.\n\t * @param {Boolean} convert If the param should be converted.\n\t */\n\tTone.Param = function(){\n\n\t\tvar options = this.optionsObject(arguments, [\"param\", \"units\", \"convert\"], Tone.Param.defaults);\n\n\t\t/**\n\t\t * The native parameter to control\n\t\t * @type {AudioParam}\n\t\t * @private\n\t\t */\n\t\tthis._param = this.input = options.param;\n\n\t\t/**\n\t\t * The units of the parameter\n\t\t * @type {Tone.Type}\n\t\t */\n\t\tthis.units = options.units;\n\n\t\t/**\n\t\t * If the value should be converted or not\n\t\t * @type {Boolean}\n\t\t */\n\t\tthis.convert = options.convert;\n\n\t\t/**\n\t\t * True if the signal value is being overridden by \n\t\t * a connected signal.\n\t\t * @readOnly\n\t\t * @type {boolean}\n\t\t * @private\n\t\t */\n\t\tthis.overridden = false;\n\n\t\t/**\n\t\t * If there is an LFO, this is where it is held.\n\t\t * @type {Tone.LFO}\n\t\t * @private\n\t\t */\n\t\tthis._lfo = null;\n\n\t\tif (this.isObject(options.lfo)){\n\t\t\tthis.value = options.lfo;\n\t\t} else if (!this.isUndef(options.value)){\n\t\t\tthis.value = options.value;\n\t\t}\n\t};\n\n\tTone.extend(Tone.Param);\n\t\n\t/**\n\t * Defaults\n\t * @type {Object}\n\t * @const\n\t */\n\tTone.Param.defaults = {\n\t\t\"units\" : Tone.Type.Default,\n\t\t\"convert\" : true,\n\t\t\"param\" : undefined\n\t};\n\n\t/**\n\t * The current value of the parameter. \n\t * @memberOf Tone.Param#\n\t * @type {Number}\n\t * @name value\n\t */\n\tObject.defineProperty(Tone.Param.prototype, \"value\", {\n\t\tget : function(){\n\t\t\treturn this._toUnits(this._param.value);\n\t\t},\n\t\tset : function(value){\n\t\t\tif (this.isObject(value)){\n\t\t\t\t//throw an error if the LFO needs to be included\n\t\t\t\tif (this.isUndef(Tone.LFO)){\n\t\t\t\t\tthrow new Error(\"Include 'Tone.LFO' to use an LFO as a Param value.\");\n\t\t\t\t}\n\t\t\t\t//remove the old one\n\t\t\t\tif (this._lfo){\n\t\t\t\t\tthis._lfo.dispose();\n\t\t\t\t}\n\t\t\t\tthis._lfo = new Tone.LFO(value).start();\n\t\t\t\tthis._lfo.connect(this.input);\n\t\t\t} else {\n\t\t\t\tvar convertedVal = this._fromUnits(value);\n\t\t\t\tthis._param.cancelScheduledValues(0);\n\t\t\t\tthis._param.value = convertedVal;\n\t\t\t}\n\t\t}\n\t});\n\n\t/**\n\t * Convert the given value from the type specified by Tone.Param.units\n\t * into the destination value (such as Gain or Frequency).\n\t * @private\n\t * @param {*} val the value to convert\n\t * @return {number} the number which the value should be set to\n\t */\n\tTone.Param.prototype._fromUnits = function(val){\n\t\tif (this.convert || this.isUndef(this.convert)){\n\t\t\tswitch(this.units){\n\t\t\t\tcase Tone.Type.Time: \n\t\t\t\t\treturn this.toSeconds(val);\n\t\t\t\tcase Tone.Type.Frequency: \n\t\t\t\t\treturn this.toFrequency(val);\n\t\t\t\tcase Tone.Type.Decibels: \n\t\t\t\t\treturn this.dbToGain(val);\n\t\t\t\tcase Tone.Type.NormalRange: \n\t\t\t\t\treturn Math.min(Math.max(val, 0), 1);\n\t\t\t\tcase Tone.Type.AudioRange: \n\t\t\t\t\treturn Math.min(Math.max(val, -1), 1);\n\t\t\t\tcase Tone.Type.Positive: \n\t\t\t\t\treturn Math.max(val, 0);\n\t\t\t\tdefault:\n\t\t\t\t\treturn val;\n\t\t\t}\n\t\t} else {\n\t\t\treturn val;\n\t\t}\n\t};\n\n\t/**\n\t * Convert the parameters value into the units specified by Tone.Param.units.\n\t * @private\n\t * @param {number} val the value to convert\n\t * @return {number}\n\t */\n\tTone.Param.prototype._toUnits = function(val){\n\t\tif (this.convert || this.isUndef(this.convert)){\n\t\t\tswitch(this.units){\n\t\t\t\tcase Tone.Type.Decibels: \n\t\t\t\t\treturn this.gainToDb(val);\n\t\t\t\tdefault:\n\t\t\t\t\treturn val;\n\t\t\t}\n\t\t} else {\n\t\t\treturn val;\n\t\t}\n\t};\n\n\t/**\n\t * the minimum output value\n\t * @type {Number}\n\t * @private\n\t */\n\tTone.Param.prototype._minOutput = 0.00001;\n\n\t/**\n\t * Schedules a parameter value change at the given time.\n\t * @param {*}\tvalue The value to set the signal.\n\t * @param {Time} time The time when the change should occur.\n\t * @returns {Tone.Param} this\n\t * @example\n\t * //set the frequency to \"G4\" in exactly 1 second from now. \n\t * freq.setValueAtTime(\"G4\", \"+1\");\n\t */\n\tTone.Param.prototype.setValueAtTime = function(value, time){\n\t\tvalue = this._fromUnits(value);\n\t\ttime = this.toSeconds(time);\n\t\tif (time <= this.now() + this.blockTime){\n\t\t\tthis._param.value = value;\n\t\t} else {\n\t\t\tthis._param.setValueAtTime(value, time);\n\t\t}\n\t\treturn this;\n\t};\n\n\t/**\n\t * Creates a schedule point with the current value at the current time.\n\t * This is useful for creating an automation anchor point in order to \n\t * schedule changes from the current value. \n\t *\n\t * @param {number=} now (Optionally) pass the now value in. \n\t * @returns {Tone.Param} this\n\t */\n\tTone.Param.prototype.setRampPoint = function(now){\n\t\tnow = this.defaultArg(now, this.now());\n\t\tvar currentVal = this._param.value;\n\t\t// exponentialRampToValueAt cannot ever ramp from or to 0\n\t\t// More info: https://bugzilla.mozilla.org/show_bug.cgi?id=1125600#c2\n\t\tif (currentVal === 0){\n\t\t\tcurrentVal = this._minOutput;\n\t\t}\n\t\tthis._param.setValueAtTime(currentVal, now);\n\t\treturn this;\n\t};\n\n\t/**\n\t * Schedules a linear continuous change in parameter value from the \n\t * previous scheduled parameter value to the given value.\n\t * \n\t * @param {number} value \n\t * @param {Time} endTime \n\t * @returns {Tone.Param} this\n\t */\n\tTone.Param.prototype.linearRampToValueAtTime = function(value, endTime){\n\t\tvalue = this._fromUnits(value);\n\t\tthis._param.linearRampToValueAtTime(value, this.toSeconds(endTime));\n\t\treturn this;\n\t};\n\n\t/**\n\t * Schedules an exponential continuous change in parameter value from \n\t * the previous scheduled parameter value to the given value.\n\t * \n\t * @param {number} value \n\t * @param {Time} endTime \n\t * @returns {Tone.Param} this\n\t */\n\tTone.Param.prototype.exponentialRampToValueAtTime = function(value, endTime){\n\t\tvalue = this._fromUnits(value);\n\t\tvalue = Math.max(this._minOutput, value);\n\t\tthis._param.exponentialRampToValueAtTime(value, this.toSeconds(endTime));\n\t\treturn this;\n\t};\n\n\t/**\n\t * Schedules an exponential continuous change in parameter value from \n\t * the current time and current value to the given value over the \n\t * duration of the rampTime.\n\t * \n\t * @param {number} value The value to ramp to.\n\t * @param {Time} rampTime the time that it takes the \n\t * value to ramp from it's current value\n\t * @param {Time}\t[startTime=now] \tWhen the ramp should start. \n\t * @returns {Tone.Param} this\n\t * @example\n\t * //exponentially ramp to the value 2 over 4 seconds. \n\t * signal.exponentialRampToValue(2, 4);\n\t */\n\tTone.Param.prototype.exponentialRampToValue = function(value, rampTime, startTime){\n\t\tstartTime = this.toSeconds(startTime);\n\t\tthis.setRampPoint(startTime);\n\t\tthis.exponentialRampToValueAtTime(value, startTime + this.toSeconds(rampTime));\n\t\treturn this;\n\t};\n\n\t/**\n\t * Schedules an linear continuous change in parameter value from \n\t * the current time and current value to the given value over the \n\t * duration of the rampTime.\n\t * \n\t * @param {number} value The value to ramp to.\n\t * @param {Time} rampTime the time that it takes the \n\t * value to ramp from it's current value\n\t * @param {Time}\t[startTime=now] \tWhen the ramp should start. \n\t * @returns {Tone.Param} this\n\t * @example\n\t * //linearly ramp to the value 4 over 3 seconds. \n\t * signal.linearRampToValue(4, 3);\n\t */\n\tTone.Param.prototype.linearRampToValue = function(value, rampTime, startTime){\n\t\tstartTime = this.toSeconds(startTime);\n\t\tthis.setRampPoint(startTime);\n\t\tthis.linearRampToValueAtTime(value, startTime + this.toSeconds(rampTime));\n\t\treturn this;\n\t};\n\n\t/**\n\t * Start exponentially approaching the target value at the given time with\n\t * a rate having the given time constant.\n\t * @param {number} value \n\t * @param {Time} startTime \n\t * @param {number} timeConstant \n\t * @returns {Tone.Param} this \n\t */\n\tTone.Param.prototype.setTargetAtTime = function(value, startTime, timeConstant){\n\t\tvalue = this._fromUnits(value);\n\t\t// The value will never be able to approach without timeConstant > 0.\n\t\t// http://www.w3.org/TR/webaudio/#dfn-setTargetAtTime, where the equation\n\t\t// is described. 0 results in a division by 0.\n\t\tvalue = Math.max(this._minOutput, value);\n\t\ttimeConstant = Math.max(this._minOutput, timeConstant);\n\t\tthis._param.setTargetAtTime(value, this.toSeconds(startTime), timeConstant);\n\t\treturn this;\n\t};\n\n\t/**\n\t * Sets an array of arbitrary parameter values starting at the given time\n\t * for the given duration.\n\t * \t\n\t * @param {Array} values \n\t * @param {Time} startTime \n\t * @param {Time} duration \n\t * @returns {Tone.Param} this\n\t */\n\tTone.Param.prototype.setValueCurveAtTime = function(values, startTime, duration){\n\t\tfor (var i = 0; i < values.length; i++){\n\t\t\tvalues[i] = this._fromUnits(values[i]);\n\t\t}\n\t\tthis._param.setValueCurveAtTime(values, this.toSeconds(startTime), this.toSeconds(duration));\n\t\treturn this;\n\t};\n\n\t/**\n\t * Cancels all scheduled parameter changes with times greater than or \n\t * equal to startTime.\n\t * \n\t * @param {Time} startTime\n\t * @returns {Tone.Param} this\n\t */\n\tTone.Param.prototype.cancelScheduledValues = function(startTime){\n\t\tthis._param.cancelScheduledValues(this.toSeconds(startTime));\n\t\treturn this;\n\t};\n\n\t/**\n\t * Ramps to the given value over the duration of the rampTime. \n\t * Automatically selects the best ramp type (exponential or linear)\n\t * depending on the `units` of the signal\n\t * \n\t * @param {number} value \n\t * @param {Time} rampTime \tThe time that it takes the \n\t * value to ramp from it's current value\n\t * @param {Time}\t[startTime=now] \tWhen the ramp should start. \n\t * @returns {Tone.Param} this\n\t * @example\n\t * //ramp to the value either linearly or exponentially \n\t * //depending on the \"units\" value of the signal\n\t * signal.rampTo(0, 10);\n\t * @example\n\t * //schedule it to ramp starting at a specific time\n\t * signal.rampTo(0, 10, 5)\n\t */\n\tTone.Param.prototype.rampTo = function(value, rampTime, startTime){\n\t\trampTime = this.defaultArg(rampTime, 0);\n\t\tif (this.units === Tone.Type.Frequency || this.units === Tone.Type.BPM || this.units === Tone.Type.Decibels){\n\t\t\tthis.exponentialRampToValue(value, rampTime, startTime);\n\t\t} else {\n\t\t\tthis.linearRampToValue(value, rampTime, startTime);\n\t\t}\n\t\treturn this;\n\t};\n\n\t/**\n\t * The LFO created by the signal instance. If none\n\t * was created, this is null.\n\t * @type {Tone.LFO}\n\t * @readOnly\n\t * @memberOf Tone.Param#\n\t * @name lfo\n\t */\n\tObject.defineProperty(Tone.Param.prototype, \"lfo\", {\n\t\tget : function(){\n\t\t\treturn this._lfo;\n\t\t}\n\t});\n\n\t/**\n\t * Clean up\n\t * @returns {Tone.Param} this\n\t */\n\tTone.Param.prototype.dispose = function(){\n\t\tTone.prototype.dispose.call(this);\n\t\tthis._param = null;\n\t\tif (this._lfo){\n\t\t\tthis._lfo.dispose();\n\t\t\tthis._lfo = null;\n\t\t}\n\t\treturn this;\n\t};\n\n\treturn Tone.Param;\n});","'use strict';\n\ndefine(function (require) {\n var p5sound = require('master');\n\n var Add = require('Tone/signal/Add');\n var Mult = require('Tone/signal/Multiply');\n var Scale = require('Tone/signal/Scale');\n\n /**\n *
Creates a signal that oscillates between -1.0 and 1.0.\n * By default, the oscillation takes the form of a sinusoidal\n * shape ('sine'). Additional types include 'triangle',\n * 'sawtooth' and 'square'. The frequency defaults to\n * 440 oscillations per second (440Hz, equal to the pitch of an\n * 'A' note).
\n *\n * @class p5.Oscillator\n * @constructor\n * @param {Number} [freq] frequency defaults to 440Hz\n * @param {String} [type] type of oscillator. Options:\n * 'sine' (default), 'triangle',\n * 'sawtooth', 'square'\n * @example\n *
\n * var osc;\n * var playing = false;\n *\n * function setup() {\n * backgroundColor = color(255,0,255);\n * textAlign(CENTER);\n *\n * osc = new p5.Oscillator();\n * osc.setType('sine');\n * osc.freq(240);\n * osc.amp(0);\n * osc.start();\n * }\n *\n * function draw() {\n * background(backgroundColor)\n * text('click to play', width/2, height/2);\n * }\n *\n * function mouseClicked() {\n * if (mouseX > 0 && mouseX < width && mouseY < height && mouseY > 0) {\n * if (!playing) {\n * // ramp amplitude to 0.5 over 0.05 seconds\n * osc.amp(0.5, 0.05);\n * playing = true;\n * backgroundColor = color(0,255,255);\n * } else {\n * // ramp amplitude to 0 over 0.5 seconds\n * osc.amp(0, 0.5);\n * playing = false;\n * backgroundColor = color(255,0,255);\n * }\n * }\n * }\n *
\n */\n p5.Oscillator = function(freq, type) {\n if (typeof freq === 'string') {\n var f = type;\n type = freq;\n freq = f;\n } if (typeof type === 'number') {\n var f = type;\n type = freq;\n freq = f;\n }\n this.started = false;\n\n // components\n this.phaseAmount = undefined;\n this.oscillator = p5sound.audiocontext.createOscillator();\n this.f = freq || 440.0; // frequency\n this.oscillator.type = type || 'sine';\n this.oscillator.frequency.setValueAtTime(this.f, p5sound.audiocontext.currentTime);\n\n // connections\n this.output = p5sound.audiocontext.createGain();\n\n this._freqMods = []; // modulators connected to this oscillator's frequency\n\n // set default output gain to 0.5\n this.output.gain.value = 0.5;\n this.output.gain.setValueAtTime(0.5, p5sound.audiocontext.currentTime);\n\n this.oscillator.connect(this.output);\n // stereo panning\n this.panPosition = 0.0;\n this.connection = p5sound.input; // connect to p5sound by default\n this.panner = new p5.Panner(this.output, this.connection, 1);\n\n //array of math operation signal chaining\n this.mathOps = [this.output];\n\n // add to the soundArray so we can dispose of the osc later\n p5sound.soundArray.push(this);\n };\n\n /**\n * Start an oscillator. Accepts an optional parameter to\n * determine how long (in seconds from now) until the\n * oscillator starts.\n *\n * @method start\n * @for p5.Oscillator\n * @param {Number} [time] startTime in seconds from now.\n * @param {Number} [frequency] frequency in Hz.\n */\n p5.Oscillator.prototype.start = function(time, f) {\n if (this.started) {\n var now = p5sound.audiocontext.currentTime;\n this.stop(now);\n }\n if (!this.started) {\n var freq = f || this.f;\n var type = this.oscillator.type;\n\n // set old osc free to be garbage collected (memory)\n if (this.oscillator) {\n this.oscillator.disconnect();\n delete this.oscillator;\n }\n\n // var detune = this.oscillator.frequency.value;\n this.oscillator = p5sound.audiocontext.createOscillator();\n this.oscillator.frequency.value = Math.abs(freq);\n this.oscillator.type = type;\n // this.oscillator.detune.value = detune;\n this.oscillator.connect(this.output);\n time = time || 0;\n this.oscillator.start(time + p5sound.audiocontext.currentTime);\n this.freqNode = this.oscillator.frequency;\n\n // if other oscillators are already connected to this osc's freq\n for (var i in this._freqMods) {\n if (typeof this._freqMods[i].connect !== 'undefined') {\n this._freqMods[i].connect(this.oscillator.frequency);\n }\n }\n\n this.started = true;\n }\n };\n\n /**\n * Stop an oscillator. Accepts an optional parameter\n * to determine how long (in seconds from now) until the\n * oscillator stops.\n *\n * @method stop\n * @for p5.Oscillator\n * @param {Number} secondsFromNow Time, in seconds from now.\n */\n p5.Oscillator.prototype.stop = function(time) {\n if (this.started) {\n var t = time || 0;\n var now = p5sound.audiocontext.currentTime;\n this.oscillator.stop(t + now);\n this.started = false;\n }\n };\n\n /**\n * Set the amplitude between 0 and 1.0. Or, pass in an object\n * such as an oscillator to modulate amplitude with an audio signal.\n *\n * @method amp\n * @for p5.Oscillator\n * @param {Number|Object} vol between 0 and 1.0\n * or a modulating signal/oscillator\n * @param {Number} [rampTime] create a fade that lasts rampTime\n * @param {Number} [timeFromNow] schedule this event to happen\n * seconds from now\n * @return {AudioParam} gain If no value is provided,\n * returns the Web Audio API\n * AudioParam that controls\n * this oscillator's\n * gain/amplitude/volume)\n */\n p5.Oscillator.prototype.amp = function(vol, rampTime, tFromNow) {\n var self = this;\n if (typeof vol === 'number') {\n var rampTime = rampTime || 0;\n var tFromNow = tFromNow || 0;\n var now = p5sound.audiocontext.currentTime;\n this.output.gain.linearRampToValueAtTime(vol, now + tFromNow + rampTime);\n }\n\n else if (vol) {\n vol.connect(self.output.gain);\n } else {\n // return the Gain Node\n return this.output.gain;\n }\n };\n\n // these are now the same thing\n p5.Oscillator.prototype.fade = p5.Oscillator.prototype.amp;\n\n p5.Oscillator.prototype.getAmp = function() {\n return this.output.gain.value;\n };\n\n /**\n * Set frequency of an oscillator to a value. Or, pass in an object\n * such as an oscillator to modulate the frequency with an audio signal.\n *\n * @method freq\n * @for p5.Oscillator\n * @param {Number|Object} Frequency Frequency in Hz\n * or modulating signal/oscillator\n * @param {Number} [rampTime] Ramp time (in seconds)\n * @param {Number} [timeFromNow] Schedule this event to happen\n * at x seconds from now\n * @return {AudioParam} Frequency If no value is provided,\n * returns the Web Audio API\n * AudioParam that controls\n * this oscillator's frequency\n * @example\n *
\n * var osc = new p5.Oscillator(300);\n * osc.start();\n * osc.freq(40, 10);\n *
\n */\n p5.Oscillator.prototype.freq = function(val, rampTime, tFromNow) {\n if (typeof val === 'number' && !isNaN(val)) {\n this.f = val;\n var now = p5sound.audiocontext.currentTime;\n var rampTime = rampTime || 0;\n var tFromNow = tFromNow || 0;\n var t = now + tFromNow + rampTime;\n // var currentFreq = this.oscillator.frequency.value;\n // this.oscillator.frequency.cancelScheduledValues(now);\n\n if (rampTime === 0) {\n this.oscillator.frequency.setValueAtTime(val, tFromNow + now);\n } else {\n if (val > 0 ) {\n this.oscillator.frequency.exponentialRampToValueAtTime(val, tFromNow + rampTime + now);\n } else {\n this.oscillator.frequency.linearRampToValueAtTime(val, tFromNow + rampTime + now);\n }\n }\n\n // reset phase if oscillator has a phase\n if (this.phaseAmount) {\n this.phase(this.phaseAmount);\n }\n\n } else if (val) {\n if (val.output) {\n val = val.output;\n }\n val.connect(this.oscillator.frequency);\n\n // keep track of what is modulating this param\n // so it can be re-connected if\n this._freqMods.push( val );\n } else {\n // return the Frequency Node\n return this.oscillator.frequency;\n }\n };\n\n p5.Oscillator.prototype.getFreq = function() {\n return this.oscillator.frequency.value;\n };\n\n /**\n * Set type to 'sine', 'triangle', 'sawtooth' or 'square'.\n *\n * @method setType\n * @for p5.Oscillator\n * @param {String} type 'sine', 'triangle', 'sawtooth' or 'square'.\n */\n p5.Oscillator.prototype.setType = function(type) {\n this.oscillator.type = type;\n };\n\n p5.Oscillator.prototype.getType = function() {\n return this.oscillator.type;\n };\n\n /**\n * Connect to a p5.sound / Web Audio object.\n *\n * @method connect\n * @for p5.Oscillator\n * @param {Object} unit A p5.sound or Web Audio object\n */\n p5.Oscillator.prototype.connect = function(unit) {\n if (!unit) {\n this.panner.connect(p5sound.input);\n }\n else if (unit.hasOwnProperty('input')) {\n this.panner.connect(unit.input);\n this.connection = unit.input;\n }\n else {\n this.panner.connect(unit);\n this.connection = unit;\n }\n };\n\n /**\n * Disconnect all outputs\n *\n * @method disconnect\n * @for p5.Oscillator\n */\n p5.Oscillator.prototype.disconnect = function() {\n if (this.output) {\n this.output.disconnect();\n }\n if (this.panner) {\n this.panner.disconnect();\n if (this.output) {\n this.output.connect(this.panner);\n }\n }\n this.oscMods = [];\n };\n\n /**\n * Pan between Left (-1) and Right (1)\n *\n * @method pan\n * @for p5.Oscillator\n * @param {Number} panning Number between -1 and 1\n * @param {Number} timeFromNow schedule this event to happen\n * seconds from now\n */\n p5.Oscillator.prototype.pan = function(pval, tFromNow) {\n this.panPosition = pval;\n this.panner.pan(pval, tFromNow);\n };\n\n p5.Oscillator.prototype.getPan = function() {\n return this.panPosition;\n };\n\n // get rid of the oscillator\n p5.Oscillator.prototype.dispose = function() {\n // remove reference from soundArray\n var index = p5sound.soundArray.indexOf(this);\n p5sound.soundArray.splice(index, 1);\n\n if (this.oscillator) {\n var now = p5sound.audiocontext.currentTime;\n this.stop(now);\n this.disconnect();\n this.panner = null;\n this.oscillator = null;\n }\n // if it is a Pulse\n if (this.osc2) {\n this.osc2.dispose();\n }\n };\n\n /**\n * Set the phase of an oscillator between 0.0 and 1.0.\n * In this implementation, phase is a delay time\n * based on the oscillator's current frequency.\n *\n * @method phase\n * @for p5.Oscillator\n * @param {Number} phase float between 0.0 and 1.0\n */\n p5.Oscillator.prototype.phase = function(p) {\n var delayAmt = p5.prototype.map(p, 0, 1.0, 0, 1/this.f);\n var now = p5sound.audiocontext.currentTime;\n\n this.phaseAmount = p;\n\n if (!this.dNode) {\n // create a delay node\n this.dNode = p5sound.audiocontext.createDelay();\n // put the delay node in between output and panner\n this.oscillator.disconnect();\n this.oscillator.connect(this.dNode);\n this.dNode.connect(this.output);\n }\n\n // set delay time to match phase:\n this.dNode.delayTime.setValueAtTime(delayAmt, now);\n };\n\n // ========================== //\n // SIGNAL MATH FOR MODULATION //\n // ========================== //\n\n // return sigChain(this, scale, thisChain, nextChain, Scale);\n var sigChain = function(o, mathObj, thisChain, nextChain, type) {\n var chainSource = o.oscillator;\n // if this type of math already exists in the chain, replace it\n for (var i in o.mathOps) {\n if (o.mathOps[i] instanceof type) {\n chainSource.disconnect();\n o.mathOps[i].dispose();\n thisChain = i;\n // assume nextChain is output gain node unless...\n if (thisChain < o.mathOps.length - 2) {\n nextChain = o.mathOps[i+1];\n }\n }\n }\n if (thisChain === o.mathOps.length - 1) {\n o.mathOps.push(nextChain);\n }\n // assume source is the oscillator unless i > 0\n if (i > 0) {\n chainSource = o.mathOps[i-1];\n }\n chainSource.disconnect();\n chainSource.connect(mathObj);\n mathObj.connect(nextChain);\n o.mathOps[thisChain] = mathObj;\n return o;\n };\n\n /**\n * Add a value to the p5.Oscillator's output amplitude,\n * and return the oscillator. Calling this method again\n * will override the initial add() with a new value.\n *\n * @method add\n * @for p5.Oscillator\n * @param {Number} number Constant number to add\n * @return {p5.Oscillator} Oscillator Returns this oscillator\n * with scaled output\n *\n */\n p5.Oscillator.prototype.add = function(num) {\n var add = new Add(num);\n var thisChain = this.mathOps.length-1;\n var nextChain = this.output;\n return sigChain(this, add, thisChain, nextChain, Add);\n };\n\n /**\n * Multiply the p5.Oscillator's output amplitude\n * by a fixed value (i.e. turn it up!). Calling this method\n * again will override the initial mult() with a new value.\n *\n * @method mult\n * @for p5.Oscillator\n * @param {Number} number Constant number to multiply\n * @return {p5.Oscillator} Oscillator Returns this oscillator\n * with multiplied output\n */\n p5.Oscillator.prototype.mult = function(num) {\n var mult = new Mult(num);\n var thisChain = this.mathOps.length-1;\n var nextChain = this.output;\n return sigChain(this, mult, thisChain, nextChain, Mult);\n };\n\n /**\n * Scale this oscillator's amplitude values to a given\n * range, and return the oscillator. Calling this method\n * again will override the initial scale() with new values.\n *\n * @method scale\n * @for p5.Oscillator\n * @param {Number} inMin input range minumum\n * @param {Number} inMax input range maximum\n * @param {Number} outMin input range minumum\n * @param {Number} outMax input range maximum\n * @return {p5.Oscillator} Oscillator Returns this oscillator\n * with scaled output\n */\n p5.Oscillator.prototype.scale = function(inMin, inMax, outMin, outMax) {\n var mapOutMin, mapOutMax;\n if (arguments.length === 4) {\n mapOutMin = p5.prototype.map(outMin, inMin, inMax, 0, 1) - 0.5;\n mapOutMax = p5.prototype.map(outMax, inMin, inMax, 0, 1) - 0.5;\n }\n else {\n mapOutMin = arguments[0];\n mapOutMax = arguments[1];\n }\n var scale = new Scale(mapOutMin, mapOutMax);\n var thisChain = this.mathOps.length-1;\n var nextChain = this.output;\n return sigChain(this, scale, thisChain, nextChain, Scale);\n\n // this.output.disconnect();\n // this.output.connect(scale)\n };\n\n // ============================== //\n // SinOsc, TriOsc, SqrOsc, SawOsc //\n // ============================== //\n\n /**\n * Constructor: new p5.SinOsc().\n * This creates a Sine Wave Oscillator and is\n * equivalent to new p5.Oscillator('sine')\n * or creating a p5.Oscillator and then calling\n * its method setType('sine').\n * See p5.Oscillator for methods.\n *\n * @class p5.SinOsc\n * @constructor\n * @extends p5.Oscillator\n * @param {Number} [freq] Set the frequency\n */\n p5.SinOsc = function(freq) {\n p5.Oscillator.call(this, freq, 'sine');\n };\n\n p5.SinOsc.prototype = Object.create(p5.Oscillator.prototype);\n\n /**\n * Constructor: new p5.TriOsc().\n * This creates a Triangle Wave Oscillator and is\n * equivalent to new p5.Oscillator('triangle')\n * or creating a p5.Oscillator and then calling\n * its method setType('triangle').\n * See p5.Oscillator for methods.\n *\n * @class p5.TriOsc\n * @constructor\n * @extends p5.Oscillator\n * @param {Number} [freq] Set the frequency\n */\n p5.TriOsc = function(freq) {\n p5.Oscillator.call(this, freq, 'triangle');\n };\n\n p5.TriOsc.prototype = Object.create(p5.Oscillator.prototype);\n\n /**\n * Constructor: new p5.SawOsc().\n * This creates a SawTooth Wave Oscillator and is\n * equivalent to new p5.Oscillator('sawtooth')\n * or creating a p5.Oscillator and then calling\n * its method setType('sawtooth').\n * See p5.Oscillator for methods.\n *\n * @class p5.SawOsc\n * @constructor\n * @extends p5.Oscillator\n * @param {Number} [freq] Set the frequency\n */\n p5.SawOsc = function(freq) {\n p5.Oscillator.call(this, freq, 'sawtooth');\n };\n\n p5.SawOsc.prototype = Object.create(p5.Oscillator.prototype);\n\n /**\n * Constructor: new p5.SqrOsc().\n * This creates a Square Wave Oscillator and is\n * equivalent to new p5.Oscillator('square')\n * or creating a p5.Oscillator and then calling\n * its method setType('square').\n * See p5.Oscillator for methods.\n *\n * @class p5.SqrOsc\n * @constructor\n * @extends p5.Oscillator\n * @param {Number} [freq] Set the frequency\n */\n p5.SqrOsc = function(freq) {\n p5.Oscillator.call(this, freq, 'square');\n };\n\n p5.SqrOsc.prototype = Object.create(p5.Oscillator.prototype);\n\n});\n","define([\"Tone/core/Tone\", \"Tone/type/Type\"], function (Tone) {\n\n\t\"use strict\";\n\n\t/**\n\t * @class A Timeline class for scheduling and maintaining state\n\t * along a timeline. All events must have a \"time\" property. \n\t * Internally, events are stored in time order for fast \n\t * retrieval.\n\t * @extends {Tone}\n\t * @param {Positive} [memory=Infinity] The number of previous events that are retained.\n\t */\n\tTone.Timeline = function(){\n\n\t\tvar options = this.optionsObject(arguments, [\"memory\"], Tone.Timeline.defaults);\n\n\t\t/**\n\t\t * The array of scheduled timeline events\n\t\t * @type {Array}\n\t\t * @private\n\t\t */\n\t\tthis._timeline = [];\n\n\t\t/**\n\t\t * An array of items to remove from the list. \n\t\t * @type {Array}\n\t\t * @private\n\t\t */\n\t\tthis._toRemove = [];\n\n\t\t/**\n\t\t * Flag if the tieline is mid iteration\n\t\t * @private\n\t\t * @type {Boolean}\n\t\t */\n\t\tthis._iterating = false;\n\n\t\t/**\n\t\t * The memory of the timeline, i.e.\n\t\t * how many events in the past it will retain\n\t\t * @type {Positive}\n\t\t */\n\t\tthis.memory = options.memory;\n\t};\n\n\tTone.extend(Tone.Timeline);\n\n\t/**\n\t * the default parameters\n\t * @static\n\t * @const\n\t */\n\tTone.Timeline.defaults = {\n\t\t\"memory\" : Infinity\n\t};\n\n\t/**\n\t * The number of items in the timeline.\n\t * @type {Number}\n\t * @memberOf Tone.Timeline#\n\t * @name length\n\t * @readOnly\n\t */\n\tObject.defineProperty(Tone.Timeline.prototype, \"length\", {\n\t\tget : function(){\n\t\t\treturn this._timeline.length;\n\t\t}\n\t});\n\n\t/**\n\t * Insert an event object onto the timeline. Events must have a \"time\" attribute.\n\t * @param {Object} event The event object to insert into the \n\t * timeline. \n\t * @returns {Tone.Timeline} this\n\t */\n\tTone.Timeline.prototype.add = function(event){\n\t\t//the event needs to have a time attribute\n\t\tif (this.isUndef(event.time)){\n\t\t\tthrow new Error(\"Tone.Timeline: events must have a time attribute\");\n\t\t}\n\t\tif (this._timeline.length){\n\t\t\tvar index = this._search(event.time);\n\t\t\tthis._timeline.splice(index + 1, 0, event);\n\t\t} else {\n\t\t\tthis._timeline.push(event);\t\t\t\n\t\t}\n\t\t//if the length is more than the memory, remove the previous ones\n\t\tif (this.length > this.memory){\n\t\t\tvar diff = this.length - this.memory;\n\t\t\tthis._timeline.splice(0, diff);\n\t\t}\n\t\treturn this;\n\t};\n\n\t/**\n\t * Remove an event from the timeline.\n\t * @param {Object} event The event object to remove from the list.\n\t * @returns {Tone.Timeline} this\n\t */\n\tTone.Timeline.prototype.remove = function(event){\n\t\tif (this._iterating){\n\t\t\tthis._toRemove.push(event);\n\t\t} else {\n\t\t\tvar index = this._timeline.indexOf(event);\n\t\t\tif (index !== -1){\n\t\t\t\tthis._timeline.splice(index, 1);\n\t\t\t}\n\t\t}\n\t\treturn this;\n\t};\n\n\t/**\n\t * Get the nearest event whose time is less than or equal to the given time.\n\t * @param {Number} time The time to query.\n\t * @returns {Object} The event object set after that time.\n\t */\n\tTone.Timeline.prototype.get = function(time){\n\t\tvar index = this._search(time);\n\t\tif (index !== -1){\n\t\t\treturn this._timeline[index];\n\t\t} else {\n\t\t\treturn null;\n\t\t}\n\t};\n\n\t/**\n\t * Return the first event in the timeline without removing it\n\t * @returns {Object} The first event object\n\t */\n\tTone.Timeline.prototype.peek = function(){\n\t\treturn this._timeline[0];\n\t};\n\n\t/**\n\t * Return the first event in the timeline and remove it\n\t * @returns {Object} The first event object\n\t */\n\tTone.Timeline.prototype.shift = function(){\n\t\treturn this._timeline.shift();\n\t};\n\n\t/**\n\t * Get the event which is scheduled after the given time.\n\t * @param {Number} time The time to query.\n\t * @returns {Object} The event object after the given time\n\t */\n\tTone.Timeline.prototype.getAfter = function(time){\n\t\tvar index = this._search(time);\n\t\tif (index + 1 < this._timeline.length){\n\t\t\treturn this._timeline[index + 1];\n\t\t} else {\n\t\t\treturn null;\n\t\t}\n\t};\n\n\t/**\n\t * Get the event before the event at the given time.\n\t * @param {Number} time The time to query.\n\t * @returns {Object} The event object before the given time\n\t */\n\tTone.Timeline.prototype.getBefore = function(time){\n\t\tvar len = this._timeline.length;\n\t\t//if it's after the last item, return the last item\n\t\tif (len > 0 && this._timeline[len - 1].time < time){\n\t\t\treturn this._timeline[len - 1];\n\t\t}\n\t\tvar index = this._search(time);\n\t\tif (index - 1 >= 0){\n\t\t\treturn this._timeline[index - 1];\n\t\t} else {\n\t\t\treturn null;\n\t\t}\n\t};\n\n\t/**\n\t * Cancel events after the given time\n\t * @param {Number} time The time to query.\n\t * @returns {Tone.Timeline} this\n\t */\n\tTone.Timeline.prototype.cancel = function(after){\n\t\tif (this._timeline.length > 1){\n\t\t\tvar index = this._search(after);\n\t\t\tif (index >= 0){\n\t\t\t\tif (this._timeline[index].time === after){\n\t\t\t\t\t//get the first item with that time\n\t\t\t\t\tfor (var i = index; i >= 0; i--){\n\t\t\t\t\t\tif (this._timeline[i].time === after){\n\t\t\t\t\t\t\tindex = i;\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tthis._timeline = this._timeline.slice(0, index);\n\t\t\t\t} else {\n\t\t\t\t\tthis._timeline = this._timeline.slice(0, index + 1);\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tthis._timeline = [];\n\t\t\t}\n\t\t} else if (this._timeline.length === 1){\n\t\t\t//the first item's time\n\t\t\tif (this._timeline[0].time >= after){\n\t\t\t\tthis._timeline = [];\n\t\t\t}\n\t\t}\n\t\treturn this;\n\t};\n\n\t/**\n\t * Cancel events before or equal to the given time.\n\t * @param {Number} time The time to cancel before.\n\t * @returns {Tone.Timeline} this\n\t */\n\tTone.Timeline.prototype.cancelBefore = function(time){\n\t\tif (this._timeline.length){\n\t\t\tvar index = this._search(time);\n\t\t\tif (index >= 0){\n\t\t\t\tthis._timeline = this._timeline.slice(index + 1);\n\t\t\t}\n\t\t}\n\t\treturn this;\n\t};\n\n\t/**\n\t * Does a binary serach on the timeline array and returns the \n\t * nearest event index whose time is after or equal to the given time.\n\t * If a time is searched before the first index in the timeline, -1 is returned.\n\t * If the time is after the end, the index of the last item is returned.\n\t * @param {Number} time \n\t * @return {Number} the index in the timeline array \n\t * @private\n\t */\n\tTone.Timeline.prototype._search = function(time){\n\t\tvar beginning = 0;\n\t\tvar len = this._timeline.length;\n\t\tvar end = len;\n\t\tif (len > 0 && this._timeline[len - 1].time <= time){\n\t\t\treturn len - 1;\n\t\t}\n\t\twhile (beginning < end){\n\t\t\t// calculate the midpoint for roughly equal partition\n\t\t\tvar midPoint = Math.floor(beginning + (end - beginning) / 2);\n\t\t\tvar event = this._timeline[midPoint];\n\t\t\tvar nextEvent = this._timeline[midPoint + 1];\n\t\t\tif (event.time === time){\n\t\t\t\t//choose the last one that has the same time\n\t\t\t\tfor (var i = midPoint; i < this._timeline.length; i++){\n\t\t\t\t\tvar testEvent = this._timeline[i];\n\t\t\t\t\tif (testEvent.time === time){\n\t\t\t\t\t\tmidPoint = i;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\treturn midPoint;\n\t\t\t} else if (event.time < time && nextEvent.time > time){\n\t\t\t\treturn midPoint;\n\t\t\t} else if (event.time > time){\n\t\t\t\t//search lower\n\t\t\t\tend = midPoint;\n\t\t\t} else if (event.time < time){\n\t\t\t\t//search upper\n\t\t\t\tbeginning = midPoint + 1;\n\t\t\t} \n\t\t}\n\t\treturn -1;\n\t};\n\n\t/**\n\t * Internal iterator. Applies extra safety checks for \n\t * removing items from the array. \n\t * @param {Function} callback \n\t * @param {Number=} lowerBound \n\t * @param {Number=} upperBound \n\t * @private\n\t */\n\tTone.Timeline.prototype._iterate = function(callback, lowerBound, upperBound){\n\t\tthis._iterating = true;\n\t\tlowerBound = this.defaultArg(lowerBound, 0);\n\t\tupperBound = this.defaultArg(upperBound, this._timeline.length - 1);\n\t\tfor (var i = lowerBound; i <= upperBound; i++){\n\t\t\tcallback(this._timeline[i]);\n\t\t}\n\t\tthis._iterating = false;\n\t\tif (this._toRemove.length > 0){\n\t\t\tfor (var j = 0; j < this._toRemove.length; j++){\n\t\t\t\tvar index = this._timeline.indexOf(this._toRemove[j]);\n\t\t\t\tif (index !== -1){\n\t\t\t\t\tthis._timeline.splice(index, 1);\n\t\t\t\t}\n\t\t\t}\n\t\t\tthis._toRemove = [];\n\t\t}\n\t};\n\n\t/**\n\t * Iterate over everything in the array\n\t * @param {Function} callback The callback to invoke with every item\n\t * @returns {Tone.Timeline} this\n\t */\n\tTone.Timeline.prototype.forEach = function(callback){\n\t\tthis._iterate(callback);\n\t\treturn this;\n\t};\n\n\t/**\n\t * Iterate over everything in the array at or before the given time.\n\t * @param {Number} time The time to check if items are before\n\t * @param {Function} callback The callback to invoke with every item\n\t * @returns {Tone.Timeline} this\n\t */\n\tTone.Timeline.prototype.forEachBefore = function(time, callback){\n\t\t//iterate over the items in reverse so that removing an item doesn't break things\n\t\tvar upperBound = this._search(time);\n\t\tif (upperBound !== -1){\n\t\t\tthis._iterate(callback, 0, upperBound);\n\t\t}\n\t\treturn this;\n\t};\n\n\t/**\n\t * Iterate over everything in the array after the given time.\n\t * @param {Number} time The time to check if items are before\n\t * @param {Function} callback The callback to invoke with every item\n\t * @returns {Tone.Timeline} this\n\t */\n\tTone.Timeline.prototype.forEachAfter = function(time, callback){\n\t\t//iterate over the items in reverse so that removing an item doesn't break things\n\t\tvar lowerBound = this._search(time);\n\t\tthis._iterate(callback, lowerBound + 1);\n\t\treturn this;\n\t};\n\n\t/**\n\t * Iterate over everything in the array at or after the given time. Similar to \n\t * forEachAfter, but includes the item(s) at the given time.\n\t * @param {Number} time The time to check if items are before\n\t * @param {Function} callback The callback to invoke with every item\n\t * @returns {Tone.Timeline} this\n\t */\n\tTone.Timeline.prototype.forEachFrom = function(time, callback){\n\t\t//iterate over the items in reverse so that removing an item doesn't break things\n\t\tvar lowerBound = this._search(time);\n\t\t//work backwards until the event time is less than time\n\t\twhile (lowerBound >= 0 && this._timeline[lowerBound].time >= time){\n\t\t\tlowerBound--;\n\t\t}\n\t\tthis._iterate(callback, lowerBound + 1);\n\t\treturn this;\n\t};\n\n\t/**\n\t * Iterate over everything in the array at the given time\n\t * @param {Number} time The time to check if items are before\n\t * @param {Function} callback The callback to invoke with every item\n\t * @returns {Tone.Timeline} this\n\t */\n\tTone.Timeline.prototype.forEachAtTime = function(time, callback){\n\t\t//iterate over the items in reverse so that removing an item doesn't break things\n\t\tvar upperBound = this._search(time);\n\t\tif (upperBound !== -1){\n\t\t\tthis._iterate(function(event){\n\t\t\t\tif (event.time === time){\n\t\t\t\t\tcallback(event);\n\t\t\t\t} \n\t\t\t}, 0, upperBound);\n\t\t}\n\t\treturn this;\n\t};\n\n\t/**\n\t * Clean up.\n\t * @return {Tone.Timeline} this\n\t */\n\tTone.Timeline.prototype.dispose = function(){\n\t\tTone.prototype.dispose.call(this);\n\t\tthis._timeline = null;\n\t\tthis._toRemove = null;\n\t};\n\n\treturn Tone.Timeline;\n});","define([\"Tone/core/Tone\", \"Tone/signal/Multiply\", \"Tone/signal/Signal\"], function(Tone){\n\n\t\"use strict\";\n\n\t/**\n\t * @class Negate the incoming signal. i.e. an input signal of 10 will output -10\n\t *\n\t * @constructor\n\t * @extends {Tone.SignalBase}\n\t * @example\n\t * var neg = new Tone.Negate();\n\t * var sig = new Tone.Signal(-2).connect(neg);\n\t * //output of neg is positive 2. \n\t */\n\tTone.Negate = function(){\n\t\t/**\n\t\t * negation is done by multiplying by -1\n\t\t * @type {Tone.Multiply}\n\t\t * @private\n\t\t */\n\t\tthis._multiply = this.input = this.output = new Tone.Multiply(-1);\n\t};\n\n\tTone.extend(Tone.Negate, Tone.SignalBase);\n\n\t/**\n\t * clean up\n\t * @returns {Tone.Negate} this\n\t */\n\tTone.Negate.prototype.dispose = function(){\n\t\tTone.prototype.dispose.call(this);\n\t\tthis._multiply.dispose();\n\t\tthis._multiply = null;\n\t\treturn this;\n\t}; \n\n\treturn Tone.Negate;\n});","define([\"Tone/core/Tone\", \"Tone/signal/Signal\", \"Tone/signal/Multiply\", \"Tone/signal/WaveShaper\"], \nfunction(Tone){\n\n\t\"use strict\";\n\n\t/**\n\t * @class GreaterThanZero outputs 1 when the input is strictly greater than zero\n\t * \n\t * @constructor\n\t * @extends {Tone.SignalBase}\n\t * @example\n\t * var gt0 = new Tone.GreaterThanZero();\n\t * var sig = new Tone.Signal(0.01).connect(gt0);\n\t * //the output of gt0 is 1. \n\t * sig.value = 0;\n\t * //the output of gt0 is 0. \n\t */\n\tTone.GreaterThanZero = function(){\n\t\t\n\t\t/**\n\t\t * @type {Tone.WaveShaper}\n\t\t * @private\n\t\t */\n\t\tthis._thresh = this.output = new Tone.WaveShaper(function(val){\n\t\t\tif (val <= 0){\n\t\t\t\treturn 0;\n\t\t\t} else {\n\t\t\t\treturn 1;\n\t\t\t}\n\t\t}, 127);\n\n\t\t/**\n\t\t * scale the first thresholded signal by a large value.\n\t\t * this will help with values which are very close to 0\n\t\t * @type {Tone.Multiply}\n\t\t * @private\n\t\t */\n\t\tthis._scale = this.input = new Tone.Multiply(10000);\n\n\t\t//connections\n\t\tthis._scale.connect(this._thresh);\n\t};\n\n\tTone.extend(Tone.GreaterThanZero, Tone.SignalBase);\n\n\t/**\n\t * dispose method\n\t * @returns {Tone.GreaterThanZero} this\n\t */\n\tTone.GreaterThanZero.prototype.dispose = function(){\n\t\tTone.prototype.dispose.call(this);\n\t\tthis._scale.dispose();\n\t\tthis._scale = null;\n\t\tthis._thresh.dispose();\n\t\tthis._thresh = null;\n\t\treturn this;\n\t};\n\n\treturn Tone.GreaterThanZero;\n});","define([\"Tone/core/Tone\", \"Tone/signal/TimelineSignal\", \"Tone/core/TimelineState\", \n\t\"Tone/core/Emitter\", \"Tone/core/Context\"], function (Tone) {\n\n\t\"use strict\";\n\n\t/**\n\t * @class A sample accurate clock which provides a callback at the given rate. \n\t * While the callback is not sample-accurate (it is still susceptible to\n\t * loose JS timing), the time passed in as the argument to the callback\n\t * is precise. For most applications, it is better to use Tone.Transport\n\t * instead of the Clock by itself since you can synchronize multiple callbacks.\n\t *\n\t * \t@constructor\n\t * @extends {Tone.Emitter}\n\t * \t@param {function} callback The callback to be invoked with the time of the audio event\n\t * \t@param {Frequency} frequency The rate of the callback\n\t * \t@example\n\t * //the callback will be invoked approximately once a second\n\t * //and will print the time exactly once a second apart.\n\t * var clock = new Tone.Clock(function(time){\n\t * \tconsole.log(time);\n\t * }, 1);\n\t */\n\tTone.Clock = function(){\n\n\t\tTone.Emitter.call(this);\n\n\t\tvar options = this.optionsObject(arguments, [\"callback\", \"frequency\"], Tone.Clock.defaults);\n\n\t\t/**\n\t\t * The callback function to invoke at the scheduled tick.\n\t\t * @type {Function}\n\t\t */\n\t\tthis.callback = options.callback;\n\n\t\t/**\n\t\t * The next time the callback is scheduled.\n\t\t * @type {Number}\n\t\t * @private\n\t\t */\n\t\tthis._nextTick = 0;\n\n\t\t/**\n\t\t * The last state of the clock.\n\t\t * @type {State}\n\t\t * @private\n\t\t */\n\t\tthis._lastState = Tone.State.Stopped;\n\n\t\t/**\n\t\t * The rate the callback function should be invoked. \n\t\t * @type {BPM}\n\t\t * @signal\n\t\t */\n\t\tthis.frequency = new Tone.TimelineSignal(options.frequency, Tone.Type.Frequency);\n\t\tthis._readOnly(\"frequency\");\n\n\t\t/**\n\t\t * The number of times the callback was invoked. Starts counting at 0\n\t\t * and increments after the callback was invoked. \n\t\t * @type {Ticks}\n\t\t * @readOnly\n\t\t */\n\t\tthis.ticks = 0;\n\n\t\t/**\n\t\t * The state timeline\n\t\t * @type {Tone.TimelineState}\n\t\t * @private\n\t\t */\n\t\tthis._state = new Tone.TimelineState(Tone.State.Stopped);\n\n\t\t/**\n\t\t * The loop function bound to its context. \n\t\t * This is necessary to remove the event in the end.\n\t\t * @type {Function}\n\t\t * @private\n\t\t */\n\t\tthis._boundLoop = this._loop.bind(this);\n\n\t\t//bind a callback to the worker thread\n \tthis.context.on(\"tick\", this._boundLoop);\n\t};\n\n\tTone.extend(Tone.Clock, Tone.Emitter);\n\n\t/**\n\t * The defaults\n\t * @const\n\t * @type {Object}\n\t */\n\tTone.Clock.defaults = {\n\t\t\"callback\" : Tone.noOp,\n\t\t\"frequency\" : 1,\n\t\t\"lookAhead\" : \"auto\",\n\t};\n\n\t/**\n\t * Returns the playback state of the source, either \"started\", \"stopped\" or \"paused\".\n\t * @type {Tone.State}\n\t * @readOnly\n\t * @memberOf Tone.Clock#\n\t * @name state\n\t */\n\tObject.defineProperty(Tone.Clock.prototype, \"state\", {\n\t\tget : function(){\n\t\t\treturn this._state.getValueAtTime(this.now());\n\t\t}\n\t});\n\n\t/**\n\t * Start the clock at the given time. Optionally pass in an offset\n\t * of where to start the tick counter from.\n\t * @param {Time} time The time the clock should start\n\t * @param {Ticks=} offset Where the tick counter starts counting from.\n\t * @return {Tone.Clock} this\n\t */\n\tTone.Clock.prototype.start = function(time, offset){\n\t\ttime = this.toSeconds(time);\n\t\tif (this._state.getValueAtTime(time) !== Tone.State.Started){\n\t\t\tthis._state.add({\n\t\t\t\t\"state\" : Tone.State.Started, \n\t\t\t\t\"time\" : time,\n\t\t\t\t\"offset\" : offset\n\t\t\t});\n\t\t}\n\t\treturn this;\t\n\t};\n\n\t/**\n\t * Stop the clock. Stopping the clock resets the tick counter to 0.\n\t * @param {Time} [time=now] The time when the clock should stop.\n\t * @returns {Tone.Clock} this\n\t * @example\n\t * clock.stop();\n\t */\n\tTone.Clock.prototype.stop = function(time){\n\t\ttime = this.toSeconds(time);\n\t\tthis._state.cancel(time);\n\t\tthis._state.setStateAtTime(Tone.State.Stopped, time);\n\t\treturn this;\t\n\t};\n\n\n\t/**\n\t * Pause the clock. Pausing does not reset the tick counter.\n\t * @param {Time} [time=now] The time when the clock should stop.\n\t * @returns {Tone.Clock} this\n\t */\n\tTone.Clock.prototype.pause = function(time){\n\t\ttime = this.toSeconds(time);\n\t\tif (this._state.getValueAtTime(time) === Tone.State.Started){\n\t\t\tthis._state.setStateAtTime(Tone.State.Paused, time);\n\t\t}\n\t\treturn this;\t\n\t};\n\n\t/**\n\t * The scheduling loop.\n\t * @param {Number} time The current page time starting from 0\n\t * when the page was loaded.\n\t * @private\n\t */\n\tTone.Clock.prototype._loop = function(){\n\t\t//get the frequency value to compute the value of the next loop\n\t\tvar now = this.now();\n\t\t//if it's started\n\t\tvar lookAhead = this.context.lookAhead;\n\t\tvar updateInterval = this.context.updateInterval;\n\t\tvar lagCompensation = this.context.lag * 2;\n\t\tvar loopInterval = now + lookAhead + updateInterval + lagCompensation;\n\t\twhile (loopInterval > this._nextTick && this._state){\n\t\t\tvar currentState = this._state.getValueAtTime(this._nextTick);\n\t\t\tif (currentState !== this._lastState){\n\t\t\t\tthis._lastState = currentState;\n\t\t\t\tvar event = this._state.get(this._nextTick);\n\t\t\t\t// emit an event\n\t\t\t\tif (currentState === Tone.State.Started){\n\t\t\t\t\t//correct the time\n\t\t\t\t\tthis._nextTick = event.time;\n\t\t\t\t\tif (!this.isUndef(event.offset)){\n\t\t\t\t\t\tthis.ticks = event.offset;\n\t\t\t\t\t}\n\t\t\t\t\tthis.emit(\"start\", event.time, this.ticks);\n\t\t\t\t} else if (currentState === Tone.State.Stopped){\n\t\t\t\t\tthis.ticks = 0;\n\n\t\t\t\t\tthis.emit(\"stop\", event.time);\n\t\t\t\t} else if (currentState === Tone.State.Paused){\n\t\t\t\t\tthis.emit(\"pause\", event.time);\n\t\t\t\t}\n\t\t\t}\n\t\t\tvar tickTime = this._nextTick;\n\t\t\tif (this.frequency){\n\t\t\t\tthis._nextTick += 1 / this.frequency.getValueAtTime(this._nextTick);\n\t\t\t\tif (currentState === Tone.State.Started){\n\t\t\t\t\tthis.callback(tickTime);\n\t\t\t\t\tthis.ticks++;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t};\n\n\t/**\n\t * Returns the scheduled state at the given time.\n\t * @param {Time} time The time to query.\n\t * @return {String} The name of the state input in setStateAtTime.\n\t * @example\n\t * clock.start(\"+0.1\");\n\t * clock.getStateAtTime(\"+0.1\"); //returns \"started\"\n\t */\n\tTone.Clock.prototype.getStateAtTime = function(time){\n\t\ttime = this.toSeconds(time);\n\t\treturn this._state.getValueAtTime(time);\n\t};\n\n\t/**\n\t * Clean up\n\t * @returns {Tone.Clock} this\n\t */\n\tTone.Clock.prototype.dispose = function(){\n\t\tTone.Emitter.prototype.dispose.call(this);\n\t\tthis.context.off(\"tick\", this._boundLoop);\n\t\tthis._writable(\"frequency\");\n\t\tthis.frequency.dispose();\n\t\tthis.frequency = null;\n\t\tthis._boundLoop = null;\n\t\tthis._nextTick = Infinity;\n\t\tthis.callback = null;\n\t\tthis._state.dispose();\n\t\tthis._state = null;\n\t};\n\n\treturn Tone.Clock;\n});","'use strict';\ndefine(function (require) {\n\n var p5sound = require('master');\n var AudioVoice = require('audioVoice');\n var noteToFreq = require('helpers').noteToFreq;\n\n var DEFAULT_SUSTAIN = 0.15;\n\n /**\n * A MonoSynth is used as a single voice for sound synthesis.\n * This is a class to be used in conjunction with the PolySynth\n * class. Custom synthetisers should be built inheriting from\n * this class.\n *\n * @class p5.MonoSynth\n * @constructor\n * @example\n *
\n * var monoSynth;\n *\n * function setup() {\n * var cnv = createCanvas(100, 100);\n * cnv.mousePressed(playSynth);\n *\n * monoSynth = new p5.MonoSynth();\n *\n * textAlign(CENTER);\n * text('click to play', width/2, height/2);\n * }\n *\n * function playSynth() {\n * // time from now (in seconds)\n * var time = 0;\n * // note duration (in seconds)\n * var dur = 0.25;\n * // velocity (volume, from 0 to 1)\n * var v = 0.2;\n *\n * monoSynth.play(\"G3\", v, time, dur);\n * monoSynth.play(\"C4\", v, time += dur, dur);\n *\n * background(random(255), random(255), 255);\n * text('click to play', width/2, height/2);\n * }\n *
\n **/\n\n p5.MonoSynth = function () {\n AudioVoice.call(this);\n\n this.oscillator = new p5.Oscillator();\n\n this.env = new p5.Envelope();\n this.env.setRange(1, 0);\n this.env.setExp(true);\n\n //set params\n this.setADSR(0.02, 0.25, 0.05, 0.35);\n\n // oscillator --> env --> this.output (gain) --> p5.soundOut\n this.oscillator.disconnect();\n this.oscillator.connect(this.output);\n\n this.env.disconnect();\n this.env.setInput(this.output.gain);\n\n // reset oscillator gain to 1.0\n this.oscillator.output.gain.value = 1.0;\n\n this.oscillator.start();\n this.connect();\n\n p5sound.soundArray.push(this);\n };\n\n p5.MonoSynth.prototype = Object.create(p5.AudioVoice.prototype);\n\n /**\n * Play tells the MonoSynth to start playing a note. This method schedules\n * the calling of .triggerAttack and .triggerRelease.\n *\n * @method play\n * @for p5.MonoSynth\n * @param {String | Number} note the note you want to play, specified as a\n * frequency in Hertz (Number) or as a midi\n * value in Note/Octave format (\"C4\", \"Eb3\"...etc\")\n * See \n * Tone. Defaults to 440 hz.\n * @param {Number} [velocity] velocity of the note to play (ranging from 0 to 1)\n * @param {Number} [secondsFromNow] time from now (in seconds) at which to play\n * @param {Number} [sustainTime] time to sustain before releasing the envelope\n * @example\n *
\n * var monoSynth;\n *\n * function setup() {\n * var cnv = createCanvas(100, 100);\n * cnv.mousePressed(playSynth);\n *\n * monoSynth = new p5.MonoSynth();\n *\n * textAlign(CENTER);\n * text('click to play', width/2, height/2);\n * }\n *\n * function playSynth() {\n * // time from now (in seconds)\n * var time = 0;\n * // note duration (in seconds)\n * var dur = 1/6;\n * // note velocity (volume, from 0 to 1)\n * var v = random();\n *\n * monoSynth.play(\"Fb3\", v, 0, dur);\n * monoSynth.play(\"Gb3\", v, time += dur, dur);\n *\n * background(random(255), random(255), 255);\n * text('click to play', width/2, height/2);\n * }\n *
\n *\n */\n p5.MonoSynth.prototype.play = function (note, velocity, secondsFromNow, susTime) {\n this.triggerAttack(note, velocity, ~~secondsFromNow);\n this.triggerRelease(~~secondsFromNow + (susTime || DEFAULT_SUSTAIN));\n };\n\n /**\n * Trigger the Attack, and Decay portion of the Envelope.\n * Similar to holding down a key on a piano, but it will\n * hold the sustain level until you let go.\n *\n * @param {String | Number} note the note you want to play, specified as a\n * frequency in Hertz (Number) or as a midi\n * value in Note/Octave format (\"C4\", \"Eb3\"...etc\")\n * See \n * Tone. Defaults to 440 hz\n * @param {Number} [velocity] velocity of the note to play (ranging from 0 to 1)\n * @param {Number} [secondsFromNow] time from now (in seconds) at which to play\n * @method triggerAttack\n * @for p5.MonoSynth\n * @example\n *
\n * var monoSynth = new p5.MonoSynth();\n *\n * function mousePressed() {\n * monoSynth.triggerAttack(\"E3\");\n * }\n *\n * function mouseReleased() {\n * monoSynth.triggerRelease();\n * }\n *
\n */\n p5.MonoSynth.prototype.triggerAttack = function (note, velocity, secondsFromNow) {\n var secondsFromNow = ~~secondsFromNow;\n var freq = noteToFreq(note);\n var vel = velocity || 0.1;\n this.oscillator.freq(freq, 0, secondsFromNow);\n this.env.ramp(this.output.gain, secondsFromNow, vel);\n };\n\n /**\n * Trigger the release of the Envelope. This is similar to releasing\n * the key on a piano and letting the sound fade according to the\n * release level and release time.\n *\n * @param {Number} secondsFromNow time to trigger the release\n * @method triggerRelease\n * @for p5.MonoSynth\n * @example\n *
\n * var monoSynth = new p5.MonoSynth();\n *\n * function mousePressed() {\n * monoSynth.triggerAttack(\"E3\");\n * }\n *\n * function mouseReleased() {\n * monoSynth.triggerRelease();\n * }\n *
\n */\n p5.MonoSynth.prototype.triggerRelease = function (secondsFromNow) {\n var secondsFromNow = secondsFromNow || 0;\n this.env.ramp(this.output.gain, secondsFromNow, 0);\n };\n\n /**\n * Set values like a traditional\n * \n * ADSR envelope\n * .\n *\n * @method setADSR\n * @for p5.MonoSynth\n * @param {Number} attackTime Time (in seconds before envelope\n * reaches Attack Level\n * @param {Number} [decayTime] Time (in seconds) before envelope\n * reaches Decay/Sustain Level\n * @param {Number} [susRatio] Ratio between attackLevel and releaseLevel, on a scale from 0 to 1,\n * where 1.0 = attackLevel, 0.0 = releaseLevel.\n * The susRatio determines the decayLevel and the level at which the\n * sustain portion of the envelope will sustain.\n * For example, if attackLevel is 0.4, releaseLevel is 0,\n * and susAmt is 0.5, the decayLevel would be 0.2. If attackLevel is\n * increased to 1.0 (using setRange),\n * then decayLevel would increase proportionally, to become 0.5.\n * @param {Number} [releaseTime] Time in seconds from now (defaults to 0)\n */\n p5.MonoSynth.prototype.setADSR = function (attack,decay,sustain,release) {\n this.env.setADSR(attack, decay, sustain, release);\n };\n\n\n /**\n * Getters and Setters\n * @property {Number} attack\n * @for p5.MonoSynth\n */\n /**\n * @property {Number} decay\n * @for p5.MonoSynth\n */\n /**\n * @property {Number} sustain\n * @for p5.MonoSynth\n */\n /**\n * @property {Number} release\n * @for p5.MonoSynth\n */\n Object.defineProperties(p5.MonoSynth.prototype, {\n 'attack': {\n get : function() {\n return this.env.aTime;\n },\n set : function(attack) {\n this.env.setADSR(attack, this.env.dTime,\n this.env.sPercent, this.env.rTime);\n }\n },\n 'decay': {\n get : function() {\n return this.env.dTime;\n },\n set : function(decay) {\n this.env.setADSR(this.env.aTime, decay,\n this.env.sPercent, this.env.rTime);\n }\n },\n 'sustain': {\n get : function() {\n return this.env.sPercent;\n },\n set : function(sustain) {\n this.env.setADSR(this.env.aTime, this.env.dTime,\n sustain, this.env.rTime);\n }\n },\n 'release': {\n get : function() {\n return this.env.rTime;\n },\n set : function(release) {\n this.env.setADSR(this.env.aTime, this.env.dTime,\n this.env.sPercent, release);\n }\n },\n });\n\n\n /**\n * MonoSynth amp\n * @method amp\n * @for p5.MonoSynth\n * @param {Number} vol desired volume\n * @param {Number} [rampTime] Time to reach new volume\n * @return {Number} new volume value\n */\n p5.MonoSynth.prototype.amp = function(vol, rampTime) {\n var t = rampTime || 0;\n if (typeof vol !== 'undefined') {\n this.oscillator.amp(vol, t);\n }\n return this.oscillator.amp().value;\n };\n\n /**\n * Connect to a p5.sound / Web Audio object.\n *\n * @method connect\n * @for p5.MonoSynth\n * @param {Object} unit A p5.sound or Web Audio object\n */\n\n p5.MonoSynth.prototype.connect = function(unit) {\n var u = unit || p5sound.input;\n this.output.connect(u.input ? u.input : u);\n };\n\n /**\n * Disconnect all outputs\n *\n * @method disconnect\n * @for p5.MonoSynth\n */\n p5.MonoSynth.prototype.disconnect = function() {\n if (this.output) {\n this.output.disconnect();\n }\n };\n\n\n /**\n * Get rid of the MonoSynth and free up its resources / memory.\n *\n * @method dispose\n * @for p5.MonoSynth\n */\n p5.MonoSynth.prototype.dispose = function() {\n AudioVoice.prototype.dispose.apply(this);\n\n if (this.env) {\n this.env.dispose();\n }\n if (this.oscillator) {\n this.oscillator.dispose();\n }\n };\n\n});\n","'use strict';\ndefine(function() {\n var p5sound = require('master');\n\n /**\n * Base class for monophonic synthesizers. Any extensions of this class\n * should follow the API and implement the methods below in order to\n * remain compatible with p5.PolySynth();\n *\n * @class p5.AudioVoice\n * @constructor\n */\n p5.AudioVoice = function () {\n\t this.ac = p5sound.audiocontext;\n\t this.output = this.ac.createGain();\n\t this.connect();\n\t p5sound.soundArray.push(this);\n };\n\n p5.AudioVoice.prototype.play = function (note, velocity, secondsFromNow, sustime) {\n };\n\n p5.AudioVoice.prototype.triggerAttack = function (note, velocity, secondsFromNow) {\n };\n\n p5.AudioVoice.prototype.triggerRelease = function (secondsFromNow) {\n };\n\n p5.AudioVoice.prototype.amp = function(vol, rampTime) {\n };\n\n /**\n * Connect to p5 objects or Web Audio Nodes\n * @method connect\n * @for p5.AudioVoice\n * @param {Object} unit\n */\n p5.AudioVoice.prototype.connect = function(unit) {\n var u = unit || p5sound.input;\n this.output.connect(u.input ? u.input : u);\n };\n\n /**\n * Disconnect from soundOut\n * @method disconnect\n * @for p5.AudioVoice\n */\n p5.AudioVoice.prototype.disconnect = function() {\n this.output.disconnect();\n };\n\n p5.AudioVoice.prototype.dispose = function() {\n if (this.output) {\n this.output.disconnect();\n delete this.output;\n }\n };\n\n return p5.AudioVoice;\n});\n","'use strict';\ndefine(function (require) {\n\n var p5sound = require('master');\n var TimelineSignal = require('Tone/signal/TimelineSignal');\n var noteToFreq = require('helpers').noteToFreq;\n\n /**\n * An AudioVoice is used as a single voice for sound synthesis.\n * The PolySynth class holds an array of AudioVoice, and deals\n * with voices allocations, with setting notes to be played, and\n * parameters to be set.\n *\n * @class p5.PolySynth\n * @constructor\n *\n * @param {Number} [synthVoice] A monophonic synth voice inheriting\n * the AudioVoice class. Defaults to p5.MonoSynth\n * @param {Number} [maxVoices] Number of voices, defaults to 8;\n * @example\n *
\n * var polySynth;\n *\n * function setup() {\n * var cnv = createCanvas(100, 100);\n * cnv.mousePressed(playSynth);\n *\n * polySynth = new p5.PolySynth();\n *\n * textAlign(CENTER);\n * text('click to play', width/2, height/2);\n * }\n *\n * function playSynth() {\n * // note duration (in seconds)\n * var dur = 1.5;\n *\n * // time from now (in seconds)\n * var time = 0;\n *\n * // velocity (volume, from 0 to 1)\n * var vel = 0.1;\n *\n * // notes can overlap with each other\n * polySynth.play(\"G2\", vel, 0, dur);\n * polySynth.play(\"C3\", vel, time += 1/3, dur);\n * polySynth.play(\"G3\", vel, time += 1/3, dur);\n *\n * background(random(255), random(255), 255);\n * text('click to play', width/2, height/2);\n * }\n *
\n **/\n p5.PolySynth = function(audioVoice, maxVoices) {\n //audiovoices will contain maxVoices many monophonic synths\n this.audiovoices = [];\n\n /**\n * An object that holds information about which notes have been played and\n * which notes are currently being played. New notes are added as keys\n * on the fly. While a note has been attacked, but not released, the value of the\n * key is the audiovoice which is generating that note. When notes are released,\n * the value of the key becomes undefined.\n * @property notes\n */\n this.notes = {};\n\n //indices of the most recently used, and least recently used audiovoice\n this._newest = 0;\n this._oldest = 0;\n\n /**\n * A PolySynth must have at least 1 voice, defaults to 8\n * @property polyvalue\n */\n this.maxVoices = maxVoices || 8;\n\n /**\n * Monosynth that generates the sound for each note that is triggered. The\n * p5.PolySynth defaults to using the p5.MonoSynth as its voice.\n * @property AudioVoice\n */\n this.AudioVoice = audioVoice === undefined ? p5.MonoSynth : audioVoice;\n\n /**\n * This value must only change as a note is attacked or released. Due to delay\n * and sustain times, Tone.TimelineSignal is required to schedule the change in value.\n\t * @private\n * @property {Tone.TimelineSignal} _voicesInUse\n */\n this._voicesInUse = new TimelineSignal(0);\n\n this.output = p5sound.audiocontext.createGain();\n this.connect();\n\n //Construct the appropriate number of audiovoices\n this._allocateVoices();\n p5sound.soundArray.push(this);\n };\n\n /**\n * Construct the appropriate number of audiovoices\n * @private\n * @for p5.PolySynth\n * @method _allocateVoices\n */\n p5.PolySynth.prototype._allocateVoices = function() {\n for(var i = 0; i< this.maxVoices; i++) {\n this.audiovoices.push(new this.AudioVoice());\n this.audiovoices[i].disconnect();\n this.audiovoices[i].connect(this.output);\n }\n };\n\n /**\n * Play a note by triggering noteAttack and noteRelease with sustain time\n *\n * @method play\n * @for p5.PolySynth\n * @param {Number} [note] midi note to play (ranging from 0 to 127 - 60 being a middle C)\n * @param {Number} [velocity] velocity of the note to play (ranging from 0 to 1)\n * @param {Number} [secondsFromNow] time from now (in seconds) at which to play\n * @param {Number} [sustainTime] time to sustain before releasing the envelope\n * @example\n *
\n * var polySynth;\n *\n * function setup() {\n * var cnv = createCanvas(100, 100);\n * cnv.mousePressed(playSynth);\n *\n * polySynth = new p5.PolySynth();\n *\n * textAlign(CENTER);\n * text('click to play', width/2, height/2);\n * }\n *\n * function playSynth() {\n * // note duration (in seconds)\n * var dur = 0.1;\n *\n * // time from now (in seconds)\n * var time = 0;\n *\n * // velocity (volume, from 0 to 1)\n * var vel = 0.1;\n *\n * polySynth.play(\"G2\", vel, 0, dur);\n * polySynth.play(\"C3\", vel, 0, dur);\n * polySynth.play(\"G3\", vel, 0, dur);\n *\n * background(random(255), random(255), 255);\n * text('click to play', width/2, height/2);\n * }\n *
\n */\n p5.PolySynth.prototype.play = function (note,velocity, secondsFromNow, susTime) {\n var susTime = susTime || 1;\n this.noteAttack(note, velocity, secondsFromNow);\n this.noteRelease(note, secondsFromNow + susTime);\n };\n\n\n /**\n * noteADSR sets the envelope for a specific note that has just been triggered.\n * Using this method modifies the envelope of whichever audiovoice is being used\n * to play the desired note. The envelope should be reset before noteRelease is called\n * in order to prevent the modified envelope from being used on other notes.\n *\n * @method noteADSR\n * @for p5.PolySynth\n * @param {Number} [note] Midi note on which ADSR should be set.\n * @param {Number} [attackTime] Time (in seconds before envelope\n * reaches Attack Level\n * @param {Number} [decayTime] Time (in seconds) before envelope\n * reaches Decay/Sustain Level\n * @param {Number} [susRatio] Ratio between attackLevel and releaseLevel, on a scale from 0 to 1,\n * where 1.0 = attackLevel, 0.0 = releaseLevel.\n * The susRatio determines the decayLevel and the level at which the\n * sustain portion of the envelope will sustain.\n * For example, if attackLevel is 0.4, releaseLevel is 0,\n * and susAmt is 0.5, the decayLevel would be 0.2. If attackLevel is\n * increased to 1.0 (using setRange),\n * then decayLevel would increase proportionally, to become 0.5.\n * @param {Number} [releaseTime] Time in seconds from now (defaults to 0)\n **/\n\n p5.PolySynth.prototype.noteADSR = function (note,a,d,s,r,timeFromNow) {\n var now = p5sound.audiocontext.currentTime;\n var timeFromNow = timeFromNow || 0;\n var t = now + timeFromNow\n this.audiovoices[ this.notes[note].getValueAtTime(t) ].setADSR(a,d,s,r);\n };\n\n\n /**\n * Set the PolySynths global envelope. This method modifies the envelopes of each\n * monosynth so that all notes are played with this envelope.\n *\n * @method setADSR\n * @for p5.PolySynth\n * @param {Number} [attackTime] Time (in seconds before envelope\n * reaches Attack Level\n * @param {Number} [decayTime] Time (in seconds) before envelope\n * reaches Decay/Sustain Level\n * @param {Number} [susRatio] Ratio between attackLevel and releaseLevel, on a scale from 0 to 1,\n * where 1.0 = attackLevel, 0.0 = releaseLevel.\n * The susRatio determines the decayLevel and the level at which the\n * sustain portion of the envelope will sustain.\n * For example, if attackLevel is 0.4, releaseLevel is 0,\n * and susAmt is 0.5, the decayLevel would be 0.2. If attackLevel is\n * increased to 1.0 (using setRange),\n * then decayLevel would increase proportionally, to become 0.5.\n * @param {Number} [releaseTime] Time in seconds from now (defaults to 0)\n **/\n p5.PolySynth.prototype.setADSR = function(a,d,s,r) {\n this.audiovoices.forEach(function(voice) {\n voice.setADSR(a,d,s,r);\n });\n };\n\n /**\n * Trigger the Attack, and Decay portion of a MonoSynth.\n * Similar to holding down a key on a piano, but it will\n * hold the sustain level until you let go.\n *\n * @method noteAttack\n * @for p5.PolySynth\n * @param {Number} [note] midi note on which attack should be triggered.\n * @param {Number} [velocity] velocity of the note to play (ranging from 0 to 1)/\n * @param {Number} [secondsFromNow] time from now (in seconds)\n * @example\n *
\n * var polySynth = new p5.PolySynth();\n * var pitches = [\"G\", \"D\", \"G\", \"C\"];\n * var octaves = [2, 3, 4];\n *\n * function mousePressed() {\n * // play a chord: multiple notes at the same time\n * for (var i = 0; i < 4; i++) {\n * var note = random(pitches) + random(octaves);\n * polySynth.noteAttack(note, 0.1);\n * }\n * }\n *\n * function mouseReleased() {\n * // release all voices\n * polySynth.noteRelease();\n * }\n *
\n */\n p5.PolySynth.prototype.noteAttack = function (_note, _velocity, secondsFromNow) {\n //this value goes to the audiovoices which handle their own scheduling\n var secondsFromNow = ~~secondsFromNow;\n\n //this value is used by this._voicesInUse\n var acTime = p5sound.audiocontext.currentTime + secondsFromNow;\n\n //Convert note to frequency if necessary. This is because entries into this.notes\n //should be based on frequency for the sake of consistency.\n var note = noteToFreq(_note);\n var velocity = _velocity || 0.1;\n\n var currentVoice;\n\n //Release the note if it is already playing\n if (this.notes[note] && this.notes[note].getValueAtTime(acTime) !== null) {\n this.noteRelease(note, 0);\n }\n\n //Check to see how many voices are in use at the time the note will start\n if (this._voicesInUse.getValueAtTime(acTime) < this.maxVoices) {\n currentVoice = Math.max(~~this._voicesInUse.getValueAtTime(acTime), 0);\n }\n //If we are exceeding the polyvalue, bump off the oldest notes and replace\n //with a new note\n else {\n currentVoice = this._oldest;\n\n var oldestNote = p5.prototype.freqToMidi(this.audiovoices[this._oldest].oscillator.freq().value);\n this.noteRelease(oldestNote);\n this._oldest = ( this._oldest + 1 ) % (this.maxVoices - 1);\n }\n\n //Overrite the entry in the notes object. A note (frequency value)\n //corresponds to the index of the audiovoice that is playing it\n this.notes[note] = new TimelineSignal();\n this.notes[note].setValueAtTime(currentVoice, acTime);\n\n //Find the scheduled change in this._voicesInUse that will be previous to this new note\n //Add 1 and schedule this value at time 't', when this note will start playing\n var previousVal = this._voicesInUse._searchBefore(acTime) === null ? 0 : this._voicesInUse._searchBefore(acTime).value;\n this._voicesInUse.setValueAtTime(previousVal + 1, acTime);\n\n //Then update all scheduled values that follow to increase by 1\n this._updateAfter(acTime, 1);\n\n this._newest = currentVoice;\n //The audiovoice handles the actual scheduling of the note\n if (typeof velocity === 'number') {\n var maxRange = 1 / this._voicesInUse.getValueAtTime(acTime) * 2;\n velocity = velocity > maxRange ? maxRange : velocity;\n }\n this.audiovoices[currentVoice].triggerAttack(note, velocity, secondsFromNow);\n };\n\n /**\n * Private method to ensure accurate values of this._voicesInUse\n * Any time a new value is scheduled, it is necessary to increment all subsequent\n * scheduledValues after attack, and decrement all subsequent\n * scheduledValues after release\n *\n * @private\n * @for p5.PolySynth\n * @param {[type]} time [description]\n * @param {[type]} value [description]\n * @return {[type]} [description]\n */\n p5.PolySynth.prototype._updateAfter = function(time, value) {\n if(this._voicesInUse._searchAfter(time) === null) {\n return;\n } else{\n this._voicesInUse._searchAfter(time).value += value;\n var nextTime = this._voicesInUse._searchAfter(time).time;\n this._updateAfter(nextTime, value);\n }\n };\n\n\n /**\n * Trigger the Release of an AudioVoice note. This is similar to releasing\n * the key on a piano and letting the sound fade according to the\n * release level and release time.\n *\n * @method noteRelease\n * @for p5.PolySynth\n * @param {Number} [note] midi note on which attack should be triggered.\n * If no value is provided, all notes will be released.\n * @param {Number} [secondsFromNow] time to trigger the release\n * @example\n *
\n * var pitches = [\"G\", \"D\", \"G\", \"C\"];\n * var octaves = [2, 3, 4];\n * var polySynth = new p5.PolySynth();\n *\n * function mousePressed() {\n * // play a chord: multiple notes at the same time\n * for (var i = 0; i < 4; i++) {\n * var note = random(pitches) + random(octaves);\n * polySynth.noteAttack(note, 0.1);\n * }\n * }\n *\n * function mouseReleased() {\n * // release all voices\n * polySynth.noteRelease();\n * }\n *
\n *\n */\n p5.PolySynth.prototype.noteRelease = function (_note,secondsFromNow) {\n var now = p5sound.audiocontext.currentTime;\n var tFromNow = secondsFromNow || 0;\n var t = now + tFromNow;\n\n // if a note value is not provided, release all voices\n if (!_note) {\n this.audiovoices.forEach(function(voice) {\n voice.triggerRelease(tFromNow)\n });\n this._voicesInUse.setValueAtTime(0, t);\n for (var n in this.notes) {\n this.notes[n].dispose();\n delete this.notes[n];\n }\n return;\n }\n\n //Make sure note is in frequency inorder to query the this.notes object\n var note = noteToFreq(_note);\n\n if (!this.notes[note] || this.notes[note].getValueAtTime(t) === null) {\n console.warn('Cannot release a note that is not already playing');\n } else {\n //Find the scheduled change in this._voicesInUse that will be previous to this new note\n //subtract 1 and schedule this value at time 't', when this note will stop playing\n var previousVal = Math.max(~~this._voicesInUse.getValueAtTime(t).value, 1);\n this._voicesInUse.setValueAtTime(previousVal - 1, t);\n //Then update all scheduled values that follow to decrease by 1 but never go below 0\n if (previousVal > 0) {\n this._updateAfter(t, -1);\n }\n\n this.audiovoices[ this.notes[note].getValueAtTime(t) ].triggerRelease(tFromNow);\n this.notes[note].dispose();\n delete this.notes[note];\n\n this._newest = this._newest === 0 ? 0 : (this._newest - 1) % (this.maxVoices - 1);\n }\n\n };\n\n /**\n * Connect to a p5.sound / Web Audio object.\n *\n * @method connect\n * @for p5.PolySynth\n * @param {Object} unit A p5.sound or Web Audio object\n */\n p5.PolySynth.prototype.connect = function (unit) {\n var u = unit || p5sound.input;\n this.output.connect(u.input ? u.input : u);\n };\n\n /**\n * Disconnect all outputs\n *\n * @method disconnect\n * @for p5.PolySynth\n */\n p5.PolySynth.prototype.disconnect = function() {\n if (this.output) {\n this.output.disconnect();\n }\n };\n\n /**\n * Get rid of the MonoSynth and free up its resources / memory.\n *\n * @method dispose\n * @for p5.PolySynth\n */\n p5.PolySynth.prototype.dispose = function() {\n this.audiovoices.forEach(function(voice) {\n voice.dispose();\n });\n\n if (this.output) {\n this.output.disconnect();\n delete this.output;\n }\n };\n\n});\n","'use strict';\n\ndefine(function (require) {\n\n require('audioworklet-polyfill');\n require('shims');\n require('audiocontext');\n var p5SOUND = require('master');\n require('helpers');\n require('errorHandler');\n require('audioWorklet');\n require('panner');\n require('soundfile');\n require('amplitude');\n require('fft');\n require('signal');\n require('oscillator');\n require('envelope');\n require('pulse');\n require('noise');\n require('audioin');\n require('filter');\n require('eq');\n require('panner3d');\n require('listener3d');\n require('delay');\n require('reverb');\n require('metro');\n require('looper');\n require('soundLoop');\n require('compressor');\n require('soundRecorder');\n require('peakDetect');\n require('gain');\n require('monosynth');\n require('polysynth');\n require('distortion');\n require('audioVoice');\n require('monosynth');\n require('polysynth');\n\n return p5SOUND;\n\n});\n","!function(){var e,t=[];function r(e){var r=this,n={},i=-1;this.parameters.forEach(function(e,o){var s=t[++i]||(t[i]=new Float32Array(r.bufferSize));s.fill(e.value),n[o]=s}),this.processor.realm.exec(\"self.sampleRate=sampleRate=\"+this.context.sampleRate+\";self.currentTime=currentTime=\"+this.context.currentTime);var s=o(e.inputBuffer),a=o(e.outputBuffer);this.instance.process([s],[a],n)}function o(e){for(var t=[],r=0;r= this.sampleLimit) {\\n this.stop();\\n return true;\\n }\\n\\n var input = inputs[0];\\n var output = outputs[0];\\n\\n for (var channel = 0; channel < output.length; ++channel) {\\n var inputChannel = input[channel];\\n\\n if (channel === 0) {\\n this.leftBuffers.push(inputChannel);\\n\\n if (this.numInputChannels === 1) {\\n this.rightBuffers.push(inputChannel);\\n }\\n } else if (channel === 1 && this.numInputChannels > 1) {\\n this.rightBuffers.push(inputChannel);\\n }\\n }\\n\\n this.recordedSamples += output[0].length;\\n return true;\\n }\\n }, {\\n key: \\\"record\\\",\\n value: function record(duration) {\\n if (duration) {\\n this.sampleLimit = Math.round(duration * sampleRate);\\n }\\n\\n this.recording = true;\\n }\\n }, {\\n key: \\\"stop\\\",\\n value: function stop() {\\n this.recording = false;\\n var buffers = this.getBuffers();\\n var leftBuffer = buffers[0].buffer;\\n var rightBuffer = buffers[1].buffer;\\n this.port.postMessage({\\n name: 'buffers',\\n leftBuffer: leftBuffer,\\n rightBuffer: rightBuffer\\n }, [leftBuffer, rightBuffer]);\\n this.clear();\\n }\\n }, {\\n key: \\\"getBuffers\\\",\\n value: function getBuffers() {\\n var buffers = [];\\n buffers.push(this.mergeBuffers(this.leftBuffers));\\n buffers.push(this.mergeBuffers(this.rightBuffers));\\n return buffers;\\n }\\n }, {\\n key: \\\"mergeBuffers\\\",\\n value: function mergeBuffers(channelBuffer) {\\n var result = new Float32Array(this.recordedSamples);\\n var offset = 0;\\n var lng = channelBuffer.length;\\n\\n for (var i = 0; i < lng; i++) {\\n var buffer = channelBuffer[i];\\n result.set(buffer, offset);\\n offset += buffer.length;\\n }\\n\\n return result;\\n }\\n }, {\\n key: \\\"clear\\\",\\n value: function clear() {\\n this.leftBuffers = [];\\n this.rightBuffers = [];\\n this.recordedSamples = 0;\\n this.sampleLimit = null;\\n }\\n }]);\\n\\n return RecorderProcessor;\\n}(_wrapNativeSuper(AudioWorkletProcessor));\\n\\nregisterProcessor(processorNames.recorderProcessor, RecorderProcessor);\"","export default \"function _typeof(obj) { if (typeof Symbol === \\\"function\\\" && typeof Symbol.iterator === \\\"symbol\\\") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === \\\"function\\\" && obj.constructor === Symbol && obj !== Symbol.prototype ? \\\"symbol\\\" : typeof obj; }; } return _typeof(obj); }\\n\\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\\\"Cannot call a class as a function\\\"); } }\\n\\nfunction _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if (\\\"value\\\" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }\\n\\nfunction _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }\\n\\nfunction _possibleConstructorReturn(self, call) { if (call && (_typeof(call) === \\\"object\\\" || typeof call === \\\"function\\\")) { return call; } return _assertThisInitialized(self); }\\n\\nfunction _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError(\\\"this hasn't been initialised - super() hasn't been called\\\"); } return self; }\\n\\nfunction _inherits(subClass, superClass) { if (typeof superClass !== \\\"function\\\" && superClass !== null) { throw new TypeError(\\\"Super expression must either be null or a function\\\"); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, writable: true, configurable: true } }); if (superClass) _setPrototypeOf(subClass, superClass); }\\n\\nfunction _wrapNativeSuper(Class) { var _cache = typeof Map === \\\"function\\\" ? new Map() : undefined; _wrapNativeSuper = function _wrapNativeSuper(Class) { if (Class === null || !_isNativeFunction(Class)) return Class; if (typeof Class !== \\\"function\\\") { throw new TypeError(\\\"Super expression must either be null or a function\\\"); } if (typeof _cache !== \\\"undefined\\\") { if (_cache.has(Class)) return _cache.get(Class); _cache.set(Class, Wrapper); } function Wrapper() { return _construct(Class, arguments, _getPrototypeOf(this).constructor); } Wrapper.prototype = Object.create(Class.prototype, { constructor: { value: Wrapper, enumerable: false, writable: true, configurable: true } }); return _setPrototypeOf(Wrapper, Class); }; return _wrapNativeSuper(Class); }\\n\\nfunction isNativeReflectConstruct() { if (typeof Reflect === \\\"undefined\\\" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === \\\"function\\\") return true; try { Date.prototype.toString.call(Reflect.construct(Date, [], function () {})); return true; } catch (e) { return false; } }\\n\\nfunction _construct(Parent, args, Class) { if (isNativeReflectConstruct()) { _construct = Reflect.construct; } else { _construct = function _construct(Parent, args, Class) { var a = [null]; a.push.apply(a, args); var Constructor = Function.bind.apply(Parent, a); var instance = new Constructor(); if (Class) _setPrototypeOf(instance, Class.prototype); return instance; }; } return _construct.apply(null, arguments); }\\n\\nfunction _isNativeFunction(fn) { return Function.toString.call(fn).indexOf(\\\"[native code]\\\") !== -1; }\\n\\nfunction _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); }\\n\\nfunction _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); }; return _getPrototypeOf(o); }\\n\\n// import processor name via preval.require so that it's available as a value at compile time\\nvar processorNames = {\\n \\\"recorderProcessor\\\": \\\"recorder-processor\\\",\\n \\\"soundFileProcessor\\\": \\\"sound-file-processor\\\",\\n \\\"amplitudeProcessor\\\": \\\"amplitude-processor\\\"\\n};\\n\\nvar SoundFileProcessor =\\n/*#__PURE__*/\\nfunction (_AudioWorkletProcesso) {\\n _inherits(SoundFileProcessor, _AudioWorkletProcesso);\\n\\n function SoundFileProcessor() {\\n _classCallCheck(this, SoundFileProcessor);\\n\\n return _possibleConstructorReturn(this, _getPrototypeOf(SoundFileProcessor).apply(this, arguments));\\n }\\n\\n _createClass(SoundFileProcessor, [{\\n key: \\\"process\\\",\\n value: function process(inputs) {\\n var input = inputs[0];\\n var inputChannel = input[0];\\n var position = inputChannel[inputChannel.length - 1] || 0;\\n this.port.postMessage({\\n name: 'position',\\n position: position\\n });\\n return true;\\n }\\n }]);\\n\\n return SoundFileProcessor;\\n}(_wrapNativeSuper(AudioWorkletProcessor));\\n\\nregisterProcessor(processorNames.soundFileProcessor, SoundFileProcessor);\"","export default \"function _typeof(obj) { if (typeof Symbol === \\\"function\\\" && typeof Symbol.iterator === \\\"symbol\\\") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === \\\"function\\\" && obj.constructor === Symbol && obj !== Symbol.prototype ? \\\"symbol\\\" : typeof obj; }; } return _typeof(obj); }\\n\\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\\\"Cannot call a class as a function\\\"); } }\\n\\nfunction _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if (\\\"value\\\" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }\\n\\nfunction _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }\\n\\nfunction _possibleConstructorReturn(self, call) { if (call && (_typeof(call) === \\\"object\\\" || typeof call === \\\"function\\\")) { return call; } return _assertThisInitialized(self); }\\n\\nfunction _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError(\\\"this hasn't been initialised - super() hasn't been called\\\"); } return self; }\\n\\nfunction _inherits(subClass, superClass) { if (typeof superClass !== \\\"function\\\" && superClass !== null) { throw new TypeError(\\\"Super expression must either be null or a function\\\"); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, writable: true, configurable: true } }); if (superClass) _setPrototypeOf(subClass, superClass); }\\n\\nfunction _wrapNativeSuper(Class) { var _cache = typeof Map === \\\"function\\\" ? new Map() : undefined; _wrapNativeSuper = function _wrapNativeSuper(Class) { if (Class === null || !_isNativeFunction(Class)) return Class; if (typeof Class !== \\\"function\\\") { throw new TypeError(\\\"Super expression must either be null or a function\\\"); } if (typeof _cache !== \\\"undefined\\\") { if (_cache.has(Class)) return _cache.get(Class); _cache.set(Class, Wrapper); } function Wrapper() { return _construct(Class, arguments, _getPrototypeOf(this).constructor); } Wrapper.prototype = Object.create(Class.prototype, { constructor: { value: Wrapper, enumerable: false, writable: true, configurable: true } }); return _setPrototypeOf(Wrapper, Class); }; return _wrapNativeSuper(Class); }\\n\\nfunction isNativeReflectConstruct() { if (typeof Reflect === \\\"undefined\\\" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === \\\"function\\\") return true; try { Date.prototype.toString.call(Reflect.construct(Date, [], function () {})); return true; } catch (e) { return false; } }\\n\\nfunction _construct(Parent, args, Class) { if (isNativeReflectConstruct()) { _construct = Reflect.construct; } else { _construct = function _construct(Parent, args, Class) { var a = [null]; a.push.apply(a, args); var Constructor = Function.bind.apply(Parent, a); var instance = new Constructor(); if (Class) _setPrototypeOf(instance, Class.prototype); return instance; }; } return _construct.apply(null, arguments); }\\n\\nfunction _isNativeFunction(fn) { return Function.toString.call(fn).indexOf(\\\"[native code]\\\") !== -1; }\\n\\nfunction _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); }\\n\\nfunction _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); }; return _getPrototypeOf(o); }\\n\\n// import processor name via preval.require so that it's available as a value at compile time\\nvar processorNames = {\\n \\\"recorderProcessor\\\": \\\"recorder-processor\\\",\\n \\\"soundFileProcessor\\\": \\\"sound-file-processor\\\",\\n \\\"amplitudeProcessor\\\": \\\"amplitude-processor\\\"\\n};\\n\\nvar AmplitudeProcessor =\\n/*#__PURE__*/\\nfunction (_AudioWorkletProcesso) {\\n _inherits(AmplitudeProcessor, _AudioWorkletProcesso);\\n\\n function AmplitudeProcessor(options) {\\n var _this;\\n\\n _classCallCheck(this, AmplitudeProcessor);\\n\\n _this = _possibleConstructorReturn(this, _getPrototypeOf(AmplitudeProcessor).call(this));\\n var processorOptions = options.processorOptions || {};\\n _this.smoothing = processorOptions.smoothing || 0;\\n _this.normalize = processorOptions.normalize || false;\\n _this.stereoVol = [0, 0];\\n _this.stereoVolNorm = [0, 0];\\n _this.volMax = 0.001;\\n\\n _this.port.onmessage = function (event) {\\n var data = event.data;\\n\\n if (data.name === 'toggleNormalize') {\\n _this.normalize = data.normalize;\\n } else if (data.name === 'smoothing') {\\n _this.smoothing = Math.max(0, Math.min(1, data.smoothing));\\n }\\n };\\n\\n return _this;\\n } // TO DO make this stereo / dependent on # of audio channels\\n\\n\\n _createClass(AmplitudeProcessor, [{\\n key: \\\"process\\\",\\n value: function process(inputs, outputs) {\\n var input = inputs[0];\\n var output = outputs[0];\\n var smoothing = this.smoothing;\\n\\n for (var channel = 0; channel < input.length; ++channel) {\\n var inputBuffer = input[channel];\\n var bufLength = inputBuffer.length;\\n var sum = 0;\\n\\n for (var i = 0; i < bufLength; i++) {\\n var x = inputBuffer[i];\\n\\n if (this.normalize) {\\n sum += Math.max(Math.min(x / this.volMax, 1), -1) * Math.max(Math.min(x / this.volMax, 1), -1);\\n } else {\\n sum += x * x;\\n }\\n } // ... then take the square root of the sum.\\n\\n\\n var rms = Math.sqrt(sum / bufLength);\\n this.stereoVol[channel] = Math.max(rms, this.stereoVol[channel] * smoothing);\\n this.volMax = Math.max(this.stereoVol[channel], this.volMax);\\n } // calculate stero normalized volume and add volume from all channels together\\n\\n\\n var volSum = 0;\\n\\n for (var index = 0; index < this.stereoVol.length; index++) {\\n this.stereoVolNorm[index] = Math.max(Math.min(this.stereoVol[index] / this.volMax, 1), 0);\\n volSum += this.stereoVol[index];\\n } // volume is average of channels\\n\\n\\n var volume = volSum / this.stereoVol.length; // normalized value\\n\\n var volNorm = Math.max(Math.min(volume / this.volMax, 1), 0);\\n this.port.postMessage({\\n name: 'amplitude',\\n volume: volume,\\n volNorm: volNorm,\\n stereoVol: this.stereoVol,\\n stereoVolNorm: this.stereoVolNorm\\n }); // pass input through to output\\n\\n for (var _channel = 0; _channel < output.length; ++_channel) {\\n output[_channel].set(input[_channel]);\\n }\\n\\n return true;\\n }\\n }]);\\n\\n return AmplitudeProcessor;\\n}(_wrapNativeSuper(AudioWorkletProcessor));\\n\\nregisterProcessor(processorNames.amplitudeProcessor, AmplitudeProcessor);\"","'use strict';\n\ndefine(function (require) {\n\n var p5sound = require('master');\n var ac = p5sound.audiocontext;\n\n // Stereo panner\n // if there is a stereo panner node use it\n if(typeof ac.createStereoPanner !== 'undefined') {\n p5.Panner = function (input, output) {\n this.stereoPanner = this.input = ac.createStereoPanner();\n input.connect(this.stereoPanner);\n this.stereoPanner.connect(output);\n };\n\n p5.Panner.prototype.pan = function(val, tFromNow) {\n var time = tFromNow || 0;\n var t = ac.currentTime + time;\n\n this.stereoPanner.pan.linearRampToValueAtTime(val, t);\n };\n\n //not implemented because stereopanner\n //node does not require this and will automatically\n //convert single channel or multichannel to stereo.\n //tested with single and stereo, not with (>2) multichannel\n p5.Panner.prototype.inputChannels = function() {};\n\n p5.Panner.prototype.connect = function(obj) {\n this.stereoPanner.connect(obj);\n };\n\n p5.Panner.prototype.disconnect = function() {\n if (this.stereoPanner) {\n this.stereoPanner.disconnect();\n }\n };\n\n } else {\n // if there is no createStereoPanner object\n // such as in safari 7.1.7 at the time of writing this\n // use this method to create the effect\n p5.Panner = function(input, output, numInputChannels) {\n this.input = ac.createGain();\n input.connect(this.input);\n\n this.left = ac.createGain();\n this.right = ac.createGain();\n this.left.channelInterpretation = 'discrete';\n this.right.channelInterpretation = 'discrete';\n\n // if input is stereo\n if (numInputChannels > 1) {\n this.splitter = ac.createChannelSplitter(2);\n this.input.connect(this.splitter);\n\n this.splitter.connect(this.left, 1);\n this.splitter.connect(this.right, 0);\n }\n else {\n this.input.connect(this.left);\n this.input.connect(this.right);\n }\n\n this.output = ac.createChannelMerger(2);\n this.left.connect(this.output, 0, 1);\n this.right.connect(this.output, 0, 0);\n this.output.connect(output);\n };\n\n // -1 is left, +1 is right\n p5.Panner.prototype.pan = function(val, tFromNow) {\n var time = tFromNow || 0;\n var t = ac.currentTime + time;\n var v = (val + 1) / 2;\n var rightVal = Math.cos(v*Math.PI/2);\n var leftVal = Math.sin(v * Math.PI/2);\n this.left.gain.linearRampToValueAtTime(leftVal, t);\n this.right.gain.linearRampToValueAtTime(rightVal, t);\n };\n\n p5.Panner.prototype.inputChannels = function(numChannels) {\n if (numChannels === 1) {\n this.input.disconnect();\n this.input.connect(this.left);\n this.input.connect(this.right);\n } else if (numChannels === 2) {\n if (typeof(this.splitter === 'undefined')) {\n this.splitter = ac.createChannelSplitter(2);\n }\n this.input.disconnect();\n this.input.connect(this.splitter);\n this.splitter.connect(this.left, 1);\n this.splitter.connect(this.right, 0);\n }\n };\n\n p5.Panner.prototype.connect = function(obj) {\n this.output.connect(obj);\n };\n\n p5.Panner.prototype.disconnect = function() {\n if (this.output) {\n this.output.disconnect();\n }\n };\n }\n});\n","'use strict';\n\ndefine(function (require) {\n\n var CustomError = require('errorHandler');\n var p5sound = require('master');\n var ac = p5sound.audiocontext;\n var midiToFreq = require('helpers').midiToFreq;\n var convertToWav = require('helpers').convertToWav;\n var processorNames = require('./audioWorklet/processorNames');\n\n /**\n *
SoundFile object with a path to a file.
\n *\n *
The p5.SoundFile may not be available immediately because\n * it loads the file information asynchronously.
\n *\n *
To do something with the sound as soon as it loads\n * pass the name of a function as the second parameter.
\n *\n *
Only one file path is required. However, audio file formats\n * (i.e. mp3, ogg, wav and m4a/aac) are not supported by all\n * web browsers. If you want to ensure compatability, instead of a single\n * file path, you may include an Array of filepaths, and the browser will\n * choose a format that works.
\n *\n * @class p5.SoundFile\n * @constructor\n * @param {String|Array} path path to a sound file (String). Optionally,\n * you may include multiple file formats in\n * an array. Alternately, accepts an object\n * from the HTML5 File API, or a p5.File.\n * @param {Function} [successCallback] Name of a function to call once file loads\n * @param {Function} [errorCallback] Name of a function to call if file fails to\n * load. This function will receive an error or\n * XMLHttpRequest object with information\n * about what went wrong.\n * @param {Function} [whileLoadingCallback] Name of a function to call while file\n * is loading. That function will\n * receive progress of the request to\n * load the sound file\n * (between 0 and 1) as its first\n * parameter. This progress\n * does not account for the additional\n * time needed to decode the audio data.\n *\n * @example\n *
\n */\n p5.SoundFile = function(paths, onload, onerror, whileLoading) {\n if (typeof paths !== 'undefined') {\n if (typeof paths === 'string' || typeof paths[0] === 'string') {\n var path = p5.prototype._checkFileFormats(paths);\n this.url = path;\n }\n else if(typeof paths === 'object') {\n if (!(window.File && window.FileReader && window.FileList && window.Blob)) {\n // The File API isn't supported in this browser\n throw 'Unable to load file because the File API is not supported';\n }\n }\n\n // if type is a p5.File...get the actual file\n if (paths.file) {\n paths = paths.file;\n }\n\n this.file = paths;\n }\n\n // private _onended callback, set by the method: onended(callback)\n this._onended = function() {};\n\n this._looping = false;\n this._playing = false;\n this._paused = false;\n this._pauseTime = 0;\n\n // cues for scheduling events with addCue() removeCue()\n this._cues = [];\n this._cueIDCounter = 0;\n\n // position of the most recently played sample\n this._lastPos = 0;\n this._counterNode = null;\n this._workletNode = null;\n\n // array of sources so that they can all be stopped!\n this.bufferSourceNodes = [];\n\n // current source\n this.bufferSourceNode = null;\n\n this.buffer = null;\n this.playbackRate = 1;\n\n this.input = p5sound.audiocontext.createGain();\n this.output = p5sound.audiocontext.createGain();\n\n this.reversed = false;\n\n // start and end of playback / loop\n this.startTime = 0;\n this.endTime = null;\n this.pauseTime = 0;\n\n // \"restart\" would stop playback before retriggering\n this.mode = 'sustain';\n\n // time that playback was started, in millis\n this.startMillis = null;\n\n // stereo panning\n this.panPosition = 0.0;\n this.panner = new p5.Panner(this.output, p5sound.input, 2);\n\n // it is possible to instantiate a soundfile with no path\n if (this.url || this.file) {\n this.load(onload, onerror);\n }\n\n // add this p5.SoundFile to the soundArray\n p5sound.soundArray.push(this);\n\n if (typeof whileLoading === 'function') {\n this._whileLoading = whileLoading;\n } else {\n this._whileLoading = function() {};\n }\n\n this._clearOnEnd = _clearOnEnd.bind(this);\n };\n\n // register preload handling of loadSound\n p5.prototype.registerPreloadMethod('loadSound', p5.prototype);\n\n /**\n * loadSound() returns a new p5.SoundFile from a specified\n * path. If called during preload(), the p5.SoundFile will be ready\n * to play in time for setup() and draw(). If called outside of\n * preload, the p5.SoundFile will not be ready immediately, so\n * loadSound accepts a callback as the second parameter. Using a\n * \n * local server is recommended when loading external files.\n *\n * @method loadSound\n * @for p5\n * @param {String|Array} path Path to the sound file, or an array with\n * paths to soundfiles in multiple formats\n * i.e. ['sound.ogg', 'sound.mp3'].\n * Alternately, accepts an object: either\n * from the HTML5 File API, or a p5.File.\n * @param {Function} [successCallback] Name of a function to call once file loads\n * @param {Function} [errorCallback] Name of a function to call if there is\n * an error loading the file.\n * @param {Function} [whileLoading] Name of a function to call while file is loading.\n * This function will receive the percentage loaded\n * so far, from 0.0 to 1.0.\n * @return {SoundFile} Returns a p5.SoundFile\n * @example\n *
\n */\n p5.prototype.loadSound = function(path, callback, onerror, whileLoading) {\n // if loading locally without a server\n if (window.location.origin.indexOf('file://') > -1 && window.cordova === 'undefined' ) {\n window.alert('This sketch may require a server to load external files. Please see http://bit.ly/1qcInwS');\n }\n\n var self = this;\n var s = new p5.SoundFile(path, function() {\n if(typeof callback === 'function') {\n callback.apply(self, arguments);\n }\n\n if (typeof self._decrementPreload === 'function') {\n self._decrementPreload();\n }\n }, onerror, whileLoading);\n\n return s;\n };\n\n /**\n * This is a helper function that the p5.SoundFile calls to load\n * itself. Accepts a callback (the name of another function)\n * as an optional parameter.\n *\n * @private\n * @for p5.SoundFile\n * @param {Function} [successCallback] Name of a function to call once file loads\n * @param {Function} [errorCallback] Name of a function to call if there is an error\n */\n p5.SoundFile.prototype.load = function(callback, errorCallback) {\n var self = this;\n var errorTrace = new Error().stack;\n\n if (this.url !== undefined && this.url !== '') {\n var request = new XMLHttpRequest();\n request.addEventListener('progress', function(evt) {\n self._updateProgress(evt);\n }, false);\n request.open('GET', this.url, true);\n request.responseType = 'arraybuffer';\n\n request.onload = function() {\n if (request.status === 200) {\n // on sucess loading file:\n if (!self.panner) return;\n ac.decodeAudioData(request.response,\n // success decoding buffer:\n function(buff) {\n if (!self.panner) return;\n self.buffer = buff;\n self.panner.inputChannels(buff.numberOfChannels);\n if (callback) {\n callback(self);\n }\n },\n // error decoding buffer. \"e\" is undefined in Chrome 11/22/2015\n function() {\n if (!self.panner) return;\n var err = new CustomError('decodeAudioData', errorTrace, self.url);\n var msg = 'AudioContext error at decodeAudioData for ' + self.url;\n if (errorCallback) {\n err.msg = msg;\n errorCallback(err);\n } else {\n console.error(msg +'\\n The error stack trace includes: \\n' + err.stack);\n }\n }\n );\n }\n // if request status != 200, it failed\n else {\n if (!self.panner) return;\n var err = new CustomError('loadSound', errorTrace, self.url);\n var msg = 'Unable to load ' + self.url + '. The request status was: ' +\n request.status + ' (' + request.statusText + ')';\n\n if (errorCallback) {\n err.message = msg;\n errorCallback(err);\n } else {\n console.error(msg +'\\n The error stack trace includes: \\n' + err.stack);\n }\n }\n };\n\n // if there is another error, aside from 404...\n request.onerror = function() {\n var err = new CustomError('loadSound', errorTrace, self.url);\n var msg = 'There was no response from the server at ' + self.url + '. Check the url and internet connectivity.';\n\n if (errorCallback) {\n err.message = msg;\n errorCallback(err);\n } else {\n console.error(msg +'\\n The error stack trace includes: \\n' + err.stack);\n }\n };\n\n request.send();\n }\n else if (this.file !== undefined) {\n var reader = new FileReader();\n reader.onload = function() {\n if (!self.panner) return;\n ac.decodeAudioData(reader.result, function(buff) {\n if (!self.panner) return;\n self.buffer = buff;\n self.panner.inputChannels(buff.numberOfChannels);\n if (callback) {\n callback(self);\n }\n });\n };\n reader.onerror = function(e) {\n if (!self.panner) return;\n if (onerror) {\n onerror(e);\n }\n };\n reader.readAsArrayBuffer(this.file);\n }\n };\n\n // TO DO: use this method to create a loading bar that shows progress during file upload/decode.\n p5.SoundFile.prototype._updateProgress = function(evt) {\n if (evt.lengthComputable) {\n var percentComplete = evt.loaded / evt.total * 0.99;\n this._whileLoading(percentComplete, evt);\n // ...\n } else {\n // Unable to compute progress information since the total size is unknown\n this._whileLoading('size unknown');\n }\n };\n\n /**\n * Returns true if the sound file finished loading successfully.\n *\n * @method isLoaded\n * @for p5.SoundFile\n * @return {Boolean}\n */\n p5.SoundFile.prototype.isLoaded = function() {\n if (this.buffer) {\n return true;\n } else {\n return false;\n }\n };\n\n /**\n * Play the p5.SoundFile\n *\n * @method play\n * @for p5.SoundFile\n * @param {Number} [startTime] (optional) schedule playback to start (in seconds from now).\n * @param {Number} [rate] (optional) playback rate\n * @param {Number} [amp] (optional) amplitude (volume)\n * of playback\n * @param {Number} [cueStart] (optional) cue start time in seconds\n * @param {Number} [duration] (optional) duration of playback in seconds\n */\n p5.SoundFile.prototype.play = function(startTime, rate, amp, _cueStart, duration) {\n if (!this.output) {\n console.warn('SoundFile.play() called after dispose');\n return;\n }\n\n var now = p5sound.audiocontext.currentTime;\n var cueStart, cueEnd;\n var time = startTime || 0;\n if (time < 0) {\n time = 0;\n }\n\n time = time + now;\n\n if (typeof rate !== 'undefined') {\n this.rate(rate);\n }\n\n if (typeof amp !== 'undefined') {\n this.setVolume(amp);\n }\n\n // TO DO: if already playing, create array of buffers for easy stop()\n if (this.buffer) {\n // reset the pause time (if it was paused)\n this._pauseTime = 0;\n\n // handle restart playmode\n if (this.mode === 'restart' && this.buffer && this.bufferSourceNode) {\n this.bufferSourceNode.stop(time);\n this._counterNode.stop(time);\n }\n\n //dont create another instance if already playing\n if (this.mode === 'untildone' && this.isPlaying()) {\n return;\n }\n // make a new source and counter. They are automatically assigned playbackRate and buffer\n this.bufferSourceNode = this._initSourceNode();\n\n // garbage collect counterNode and create a new one\n delete this._counterNode;\n this._counterNode = this._initCounterNode();\n\n if (_cueStart) {\n if (_cueStart >=0 && _cueStart < this.buffer.duration) {\n // this.startTime = cueStart;\n cueStart = _cueStart;\n } else { throw 'start time out of range'; }\n } else {\n cueStart = 0;\n }\n\n if (duration) {\n // if duration is greater than buffer.duration, just play entire file anyway rather than throw an error\n duration = duration <= this.buffer.duration - cueStart ? duration : this.buffer.duration;\n }\n\n // if it was paused, play at the pause position\n if (this._paused) {\n this.bufferSourceNode.start(time, this.pauseTime, duration);\n this._counterNode.start(time, this.pauseTime, duration);\n } else {\n this.bufferSourceNode.start(time, cueStart, duration);\n this._counterNode.start(time, cueStart, duration);\n }\n\n this._playing = true;\n this._paused = false;\n\n // add source to sources array, which is used in stopAll()\n this.bufferSourceNodes.push(this.bufferSourceNode);\n this.bufferSourceNode._arrayIndex = this.bufferSourceNodes.length - 1;\n\n this.bufferSourceNode.addEventListener('ended', this._clearOnEnd);\n }\n // If soundFile hasn't loaded the buffer yet, throw an error\n else {\n throw 'not ready to play file, buffer has yet to load. Try preload()';\n }\n\n // if looping, will restart at original time\n this.bufferSourceNode.loop = this._looping;\n this._counterNode.loop = this._looping;\n\n if (this._looping === true) {\n cueEnd = duration ? duration : cueStart - 0.000000000000001;\n this.bufferSourceNode.loopStart = cueStart;\n this.bufferSourceNode.loopEnd = cueEnd;\n this._counterNode.loopStart = cueStart;\n this._counterNode.loopEnd = cueEnd;\n }\n\n };\n\n\n /**\n * p5.SoundFile has two play modes: restart and\n * sustain. Play Mode determines what happens to a\n * p5.SoundFile if it is triggered while in the middle of playback.\n * In sustain mode, playback will continue simultaneous to the\n * new playback. In restart mode, play() will stop playback\n * and start over. With untilDone, a sound will play only if it's\n * not already playing. Sustain is the default mode.\n *\n * @method playMode\n * @for p5.SoundFile\n * @param {String} str 'restart' or 'sustain' or 'untilDone'\n * @example\n *
\n * var mySound;\n * function preload(){\n * mySound = loadSound('assets/Damscray_DancingTiger.mp3');\n * }\n * function mouseClicked() {\n * mySound.playMode('sustain');\n * mySound.play();\n * }\n * function keyPressed() {\n * mySound.playMode('restart');\n * mySound.play();\n * }\n *\n *
\n */\n p5.SoundFile.prototype.playMode = function(str) {\n var s = str.toLowerCase();\n\n // if restart, stop all other sounds from playing\n if (s === 'restart' && this.buffer && this.bufferSourceNode) {\n for (var i = 0; i < this.bufferSourceNodes.length - 1; i++) {\n var now = p5sound.audiocontext.currentTime;\n this.bufferSourceNodes[i].stop(now);\n }\n }\n\n // set play mode to effect future playback\n if (s === 'restart' || s === 'sustain' || s === 'untildone') {\n this.mode = s;\n } else {\n throw 'Invalid play mode. Must be either \"restart\" or \"sustain\"';\n }\n };\n\n /**\n * Pauses a file that is currently playing. If the file is not\n * playing, then nothing will happen.\n *\n * After pausing, .play() will resume from the paused\n * position.\n * If p5.SoundFile had been set to loop before it was paused,\n * it will continue to loop after it is unpaused with .play().\n *\n * @method pause\n * @for p5.SoundFile\n * @param {Number} [startTime] (optional) schedule event to occur\n * seconds from now\n * @example\n *
\n */\n p5.SoundFile.prototype.pause = function(startTime) {\n var now = p5sound.audiocontext.currentTime;\n var time = startTime || 0;\n var pTime = time + now;\n\n if (this.isPlaying() && this.buffer && this.bufferSourceNode) {\n this._paused = true;\n this._playing = false;\n\n this.pauseTime = this.currentTime();\n this.bufferSourceNode.stop(pTime);\n this._counterNode.stop(pTime);\n\n this._pauseTime = this.currentTime();\n // TO DO: make sure play() still starts from orig start position\n } else {\n this._pauseTime = 0;\n }\n };\n\n /**\n * Loop the p5.SoundFile. Accepts optional parameters to set the\n * playback rate, playback volume, loopStart, loopEnd.\n *\n * @method loop\n * @for p5.SoundFile\n * @param {Number} [startTime] (optional) schedule event to occur\n * seconds from now\n * @param {Number} [rate] (optional) playback rate\n * @param {Number} [amp] (optional) playback volume\n * @param {Number} [cueLoopStart] (optional) startTime in seconds\n * @param {Number} [duration] (optional) loop duration in seconds\n */\n p5.SoundFile.prototype.loop = function(startTime, rate, amp, loopStart, duration) {\n this._looping = true;\n this.play(startTime, rate, amp, loopStart, duration);\n };\n\n /**\n * Set a p5.SoundFile's looping flag to true or false. If the sound\n * is currently playing, this change will take effect when it\n * reaches the end of the current playback.\n *\n * @method setLoop\n * @for p5.SoundFile\n * @param {Boolean} Boolean set looping to true or false\n */\n p5.SoundFile.prototype.setLoop = function(bool) {\n if (bool === true) {\n this._looping = true;\n }\n else if (bool === false) {\n this._looping = false;\n }\n else {\n throw 'Error: setLoop accepts either true or false';\n }\n if (this.bufferSourceNode) {\n this.bufferSourceNode.loop = this._looping;\n this._counterNode.loop = this._looping;\n }\n };\n\n /**\n * Returns 'true' if a p5.SoundFile is currently looping and playing, 'false' if not.\n *\n * @method isLooping\n * @for p5.SoundFile\n * @return {Boolean}\n */\n p5.SoundFile.prototype.isLooping = function() {\n if (!this.bufferSourceNode) {\n return false;\n }\n if (this._looping === true && this.isPlaying() === true) {\n return true;\n }\n return false;\n };\n\n /**\n * Returns true if a p5.SoundFile is playing, false if not (i.e.\n * paused or stopped).\n *\n * @method isPlaying\n * @for p5.SoundFile\n * @return {Boolean}\n */\n p5.SoundFile.prototype.isPlaying = function() {\n return this._playing;\n };\n\n /**\n * Returns true if a p5.SoundFile is paused, false if not (i.e.\n * playing or stopped).\n *\n * @method isPaused\n * @for p5.SoundFile\n * @return {Boolean}\n */\n p5.SoundFile.prototype.isPaused = function() {\n return this._paused;\n };\n\n /**\n * Stop soundfile playback.\n *\n * @method stop\n * @for p5.SoundFile\n * @param {Number} [startTime] (optional) schedule event to occur\n * in seconds from now\n */\n p5.SoundFile.prototype.stop = function(timeFromNow) {\n var time = timeFromNow || 0;\n\n if (this.mode === 'sustain' || this.mode === 'untildone') {\n this.stopAll(time);\n this._playing = false;\n this.pauseTime = 0;\n this._paused = false;\n }\n else if (this.buffer && this.bufferSourceNode) {\n var now = p5sound.audiocontext.currentTime;\n var t = time || 0;\n this.pauseTime = 0;\n this.bufferSourceNode.stop(now + t);\n this._counterNode.stop(now + t);\n this._playing = false;\n this._paused = false;\n }\n };\n\n /**\n * Stop playback on all of this soundfile's sources.\n * @private\n */\n p5.SoundFile.prototype.stopAll = function(_time) {\n var now = p5sound.audiocontext.currentTime;\n var time = _time || 0;\n if (this.buffer && this.bufferSourceNode) {\n for (var i in this.bufferSourceNodes) {\n const bufferSourceNode = this.bufferSourceNodes[i];\n if (!!bufferSourceNode) {\n try {\n bufferSourceNode.stop(now + time);\n } catch(e) {\n // this was throwing errors only on Safari\n }\n }\n }\n this._counterNode.stop(now + time);\n this._onended(this);\n }\n };\n\n /**\n * Multiply the output volume (amplitude) of a sound file\n * between 0.0 (silence) and 1.0 (full volume).\n * 1.0 is the maximum amplitude of a digital sound, so multiplying\n * by greater than 1.0 may cause digital distortion. To\n * fade, provide a rampTime parameter. For more\n * complex fades, see the Envelope class.\n *\n * Alternately, you can pass in a signal source such as an\n * oscillator to modulate the amplitude with an audio signal.\n *\n * @method setVolume\n * @for p5.SoundFile\n * @param {Number|Object} volume Volume (amplitude) between 0.0\n * and 1.0 or modulating signal/oscillator\n * @param {Number} [rampTime] Fade for t seconds\n * @param {Number} [timeFromNow] Schedule this event to happen at\n * t seconds in the future\n */\n p5.SoundFile.prototype.setVolume = function(vol, _rampTime, _tFromNow) {\n if (typeof vol === 'number') {\n var rampTime = _rampTime || 0;\n var tFromNow = _tFromNow || 0;\n var now = p5sound.audiocontext.currentTime;\n var currentVol = this.output.gain.value;\n this.output.gain.cancelScheduledValues(now + tFromNow);\n this.output.gain.linearRampToValueAtTime(currentVol, now + tFromNow);\n this.output.gain.linearRampToValueAtTime(vol, now + tFromNow + rampTime);\n }\n else if (vol) {\n vol.connect(this.output.gain);\n } else {\n // return the Gain Node\n return this.output.gain;\n }\n };\n\n // same as setVolume, to match Processing Sound\n p5.SoundFile.prototype.amp = p5.SoundFile.prototype.setVolume;\n\n // these are the same thing\n p5.SoundFile.prototype.fade = p5.SoundFile.prototype.setVolume;\n\n p5.SoundFile.prototype.getVolume = function() {\n return this.output.gain.value;\n };\n\n /**\n * Set the stereo panning of a p5.sound object to\n * a floating point number between -1.0 (left) and 1.0 (right).\n * Default is 0.0 (center).\n *\n * @method pan\n * @for p5.SoundFile\n * @param {Number} [panValue] Set the stereo panner\n * @param {Number} [timeFromNow] schedule this event to happen\n * seconds from now\n * @example\n *
\n *\n * var ball = {};\n * var soundFile;\n *\n * function preload() {\n * soundFormats('ogg', 'mp3');\n * soundFile = loadSound('assets/beatbox.mp3');\n * }\n *\n * function draw() {\n * background(0);\n * ball.x = constrain(mouseX, 0, width);\n * ellipse(ball.x, height/2, 20, 20)\n * }\n *\n * function mousePressed(){\n * // map the ball's x location to a panning degree\n * // between -1.0 (left) and 1.0 (right)\n * var panning = map(ball.x, 0., width,-1.0, 1.0);\n * soundFile.pan(panning);\n * soundFile.play();\n * }\n *
\n */\n p5.SoundFile.prototype.pan = function(pval, tFromNow) {\n this.panPosition = pval;\n this.panner.pan(pval, tFromNow);\n };\n\n /**\n * Returns the current stereo pan position (-1.0 to 1.0)\n *\n * @method getPan\n * @for p5.SoundFile\n * @return {Number} Returns the stereo pan setting of the Oscillator\n * as a number between -1.0 (left) and 1.0 (right).\n * 0.0 is center and default.\n */\n p5.SoundFile.prototype.getPan = function() {\n return this.panPosition;\n };\n\n /**\n * Set the playback rate of a sound file. Will change the speed and the pitch.\n * Values less than zero will reverse the audio buffer.\n *\n * @method rate\n * @for p5.SoundFile\n * @param {Number} [playbackRate] Set the playback rate. 1.0 is normal,\n * .5 is half-speed, 2.0 is twice as fast.\n * Values less than zero play backwards.\n * @example\n *
\n * var song;\n *\n * function preload() {\n * song = loadSound('assets/Damscray_DancingTiger.mp3');\n * }\n *\n * function setup() {\n * song.loop();\n * }\n *\n * function draw() {\n * background(200);\n *\n * // Set the rate to a range between 0.1 and 4\n * // Changing the rate also alters the pitch\n * var speed = map(mouseY, 0.1, height, 0, 2);\n * speed = constrain(speed, 0.01, 4);\n * song.rate(speed);\n *\n * // Draw a circle to show what is going on\n * stroke(0);\n * fill(51, 100);\n * ellipse(mouseX, 100, 48, 48);\n * }\n *\n * \n *
\n *\n */\n p5.SoundFile.prototype.rate = function(playbackRate) {\n var reverse = false;\n if (typeof playbackRate === 'undefined') {\n return this.playbackRate;\n }\n\n this.playbackRate = playbackRate;\n\n if (playbackRate === 0) {\n playbackRate = 0.0000000000001;\n }\n\n else if (playbackRate < 0 && !this.reversed) {\n playbackRate = Math.abs(playbackRate);\n reverse = true;\n }\n\n else if (playbackRate > 0 && this.reversed) {\n reverse = true;\n }\n\n if (this.bufferSourceNode) {\n var now = p5sound.audiocontext.currentTime;\n this.bufferSourceNode.playbackRate.cancelScheduledValues(now);\n this.bufferSourceNode.playbackRate.linearRampToValueAtTime(Math.abs(playbackRate), now);\n this._counterNode.playbackRate.cancelScheduledValues(now);\n this._counterNode.playbackRate.linearRampToValueAtTime(Math.abs(playbackRate), now);\n }\n\n if (reverse) {\n this.reverseBuffer();\n }\n return this.playbackRate;\n };\n\n // TO DO: document this\n p5.SoundFile.prototype.setPitch = function(num) {\n var newPlaybackRate = midiToFreq(num) / midiToFreq(60);\n this.rate(newPlaybackRate);\n };\n\n p5.SoundFile.prototype.getPlaybackRate = function() {\n return this.playbackRate;\n };\n\n /**\n * Returns the duration of a sound file in seconds.\n *\n * @method duration\n * @for p5.SoundFile\n * @return {Number} The duration of the soundFile in seconds.\n */\n p5.SoundFile.prototype.duration = function() {\n // Return Duration\n if (this.buffer) {\n return this.buffer.duration;\n } else {\n return 0;\n }\n };\n\n /**\n * Return the current position of the p5.SoundFile playhead, in seconds.\n * Time is relative to the normal buffer direction, so if `reverseBuffer`\n * has been called, currentTime will count backwards.\n *\n * @method currentTime\n * @for p5.SoundFile\n * @return {Number} currentTime of the soundFile in seconds.\n */\n p5.SoundFile.prototype.currentTime = function() {\n return this.reversed\n ? Math.abs(this._lastPos - this.buffer.length) / ac.sampleRate\n : this._lastPos / ac.sampleRate;\n };\n\n /**\n * Move the playhead of the song to a position, in seconds. Start timing\n * and playback duration. If none are given, will reset the file to play\n * entire duration from start to finish.\n *\n * @method jump\n * @for p5.SoundFile\n * @param {Number} cueTime cueTime of the soundFile in seconds.\n * @param {Number} duration duration in seconds.\n */\n p5.SoundFile.prototype.jump = function(cueTime, duration) {\n if (cueTime < 0 || cueTime > this.buffer.duration) {\n throw 'jump time out of range';\n }\n if (duration > this.buffer.duration - cueTime) {\n throw 'end time out of range';\n }\n\n var cTime = cueTime || 0;\n var dur = duration || undefined;\n if (this.isPlaying()) {\n this.stop(0);\n }\n this.play(0, this.playbackRate, this.output.gain.value, cTime, dur);\n };\n\n /**\n * Return the number of channels in a sound file.\n * For example, Mono = 1, Stereo = 2.\n *\n * @method channels\n * @for p5.SoundFile\n * @return {Number} [channels]\n */\n p5.SoundFile.prototype.channels = function() {\n return this.buffer.numberOfChannels;\n };\n\n /**\n * Return the sample rate of the sound file.\n *\n * @method sampleRate\n * @for p5.SoundFile\n * @return {Number} [sampleRate]\n */\n p5.SoundFile.prototype.sampleRate = function() {\n return this.buffer.sampleRate;\n };\n\n /**\n * Return the number of samples in a sound file.\n * Equal to sampleRate * duration.\n *\n * @method frames\n * @for p5.SoundFile\n * @return {Number} [sampleCount]\n */\n p5.SoundFile.prototype.frames = function() {\n return this.buffer.length;\n };\n\n /**\n * Returns an array of amplitude peaks in a p5.SoundFile that can be\n * used to draw a static waveform. Scans through the p5.SoundFile's\n * audio buffer to find the greatest amplitudes. Accepts one\n * parameter, 'length', which determines size of the array.\n * Larger arrays result in more precise waveform visualizations.\n *\n * Inspired by Wavesurfer.js.\n *\n * @method getPeaks\n * @for p5.SoundFile\n * @params {Number} [length] length is the size of the returned array.\n * Larger length results in more precision.\n * Defaults to 5*width of the browser window.\n * @returns {Float32Array} Array of peaks.\n */\n p5.SoundFile.prototype.getPeaks = function(length) {\n\n if (this.buffer) {\n // set length to window's width if no length is provided\n if (!length) {\n length = window.width*5;\n }\n if (this.buffer) {\n var buffer = this.buffer;\n var sampleSize = buffer.length / length;\n var sampleStep = ~~(sampleSize / 10) || 1;\n var channels = buffer.numberOfChannels;\n var peaks = new Float32Array(Math.round(length));\n\n for (var c = 0; c < channels; c++) {\n var chan = buffer.getChannelData(c);\n for (var i = 0; i < length; i++) {\n var start = ~~(i*sampleSize);\n var end = ~~(start + sampleSize);\n var max = 0;\n for (var j = start; j < end; j+= sampleStep) {\n var value = chan[j];\n if (value > max) {\n max = value;\n // faster than Math.abs\n } else if (-value > max) {\n max = value;\n }\n }\n if (c === 0 || Math.abs(max) > peaks[i]) {\n peaks[i] = max;\n }\n }\n }\n\n return peaks;\n }\n }\n\n else {\n throw 'Cannot load peaks yet, buffer is not loaded';\n }\n };\n\n /**\n * Reverses the p5.SoundFile's buffer source.\n * Playback must be handled separately (see example).\n *\n * @method reverseBuffer\n * @for p5.SoundFile\n * @example\n *
\n * var drum;\n *\n * function preload() {\n * drum = loadSound('assets/drum.mp3');\n * }\n *\n * function setup() {\n * drum.reverseBuffer();\n * drum.play();\n * }\n *\n * \n *
\n */\n p5.SoundFile.prototype.reverseBuffer = function() {\n if (this.buffer) {\n var currentPos = this._lastPos / ac.sampleRate;\n var curVol = this.getVolume();\n this.setVolume(0, 0.001);\n\n const numChannels = this.buffer.numberOfChannels;\n for (var i = 0; i < numChannels; i++) {\n this.buffer.getChannelData(i).reverse();\n }\n // set reversed flag\n this.reversed = !this.reversed;\n\n if (currentPos) {\n this.jump(this.duration() - currentPos);\n }\n this.setVolume(curVol, 0.001);\n } else {\n throw 'SoundFile is not done loading';\n }\n };\n\n /**\n * Schedule an event to be called when the soundfile\n * reaches the end of a buffer. If the soundfile is\n * playing through once, this will be called when it\n * ends. If it is looping, it will be called when\n * stop is called.\n *\n * @method onended\n * @for p5.SoundFile\n * @param {Function} callback function to call when the\n * soundfile has ended.\n */\n p5.SoundFile.prototype.onended = function(callback) {\n this._onended = callback;\n return this;\n };\n\n p5.SoundFile.prototype.add = function() {\n // TO DO\n };\n\n p5.SoundFile.prototype.dispose = function() {\n var now = p5sound.audiocontext.currentTime;\n\n // remove reference to soundfile\n var index = p5sound.soundArray.indexOf(this);\n p5sound.soundArray.splice(index, 1);\n\n this.stop(now);\n if (this.buffer && this.bufferSourceNode) {\n for (var i = 0; i < this.bufferSourceNodes.length - 1; i++) {\n if (this.bufferSourceNodes[i] !== null) {\n this.bufferSourceNodes[i].disconnect();\n try {\n this.bufferSourceNodes[i].stop(now);\n } catch(e) {\n console.warning('no buffer source node to dispose');\n }\n this.bufferSourceNodes[i] = null;\n }\n }\n if ( this.isPlaying() ) {\n try {\n this._counterNode.stop(now);\n } catch(e) {\n console.log(e);\n }\n this._counterNode = null;\n }\n }\n if (this.output) {\n this.output.disconnect();\n this.output = null;\n }\n if (this.panner) {\n this.panner.disconnect();\n this.panner = null;\n }\n };\n\n /**\n * Connects the output of a p5sound object to input of another\n * p5.sound object. For example, you may connect a p5.SoundFile to an\n * FFT or an Effect. If no parameter is given, it will connect to\n * the master output. Most p5sound objects connect to the master\n * output when they are created.\n *\n * @method connect\n * @for p5.SoundFile\n * @param {Object} [object] Audio object that accepts an input\n */\n p5.SoundFile.prototype.connect = function(unit) {\n if (!unit) {\n this.panner.connect(p5sound.input);\n }\n else {\n if (unit.hasOwnProperty('input')) {\n this.panner.connect(unit.input);\n } else {\n this.panner.connect(unit);\n }\n }\n };\n\n /**\n * Disconnects the output of this p5sound object.\n *\n * @method disconnect\n * @for p5.SoundFile\n */\n p5.SoundFile.prototype.disconnect = function() {\n if (this.panner) {\n this.panner.disconnect();\n }\n };\n\n /**\n */\n p5.SoundFile.prototype.getLevel = function() {\n console.warn('p5.SoundFile.getLevel has been removed from the library. Use p5.Amplitude instead');\n };\n\n /**\n * Reset the source for this SoundFile to a\n * new path (URL).\n *\n * @method setPath\n * @for p5.SoundFile\n * @param {String} path path to audio file\n * @param {Function} callback Callback\n */\n p5.SoundFile.prototype.setPath = function(p, callback) {\n var path = p5.prototype._checkFileFormats(p);\n this.url = path;\n this.load(callback);\n };\n\n /**\n * Replace the current Audio Buffer with a new Buffer.\n *\n * @method setBuffer\n * @for p5.SoundFile\n * @param {Array} buf Array of Float32 Array(s). 2 Float32 Arrays\n * will create a stereo source. 1 will create\n * a mono source.\n */\n p5.SoundFile.prototype.setBuffer = function(buf) {\n var numChannels = buf.length;\n var size = buf[0].length;\n var newBuffer = ac.createBuffer(numChannels, size, ac.sampleRate);\n\n if (!(buf[0] instanceof Float32Array)) {\n buf[0] = new Float32Array(buf[0]);\n }\n\n for (var channelNum = 0; channelNum < numChannels; channelNum++) {\n var channel = newBuffer.getChannelData( channelNum );\n channel.set(buf[channelNum]);\n }\n\n this.buffer = newBuffer;\n\n // set numbers of channels on input to the panner\n this.panner.inputChannels(numChannels);\n };\n\n //////////////////////////////////////////////////\n // script processor node with an empty buffer to help\n // keep a sample-accurate position in playback buffer.\n // Inspired by Chinmay Pendharkar's technique for Sonoport --> http://bit.ly/1HwdCsV\n // Copyright [2015] [Sonoport (Asia) Pte. Ltd.],\n // Licensed under the Apache License http://apache.org/licenses/LICENSE-2.0\n ////////////////////////////////////////////////////////////////////////////////////\n\n var _createCounterBuffer = function(buffer) {\n const len = buffer.length;\n const audioBuf = ac.createBuffer( 1, buffer.length, ac.sampleRate );\n const arrayBuffer = audioBuf.getChannelData(0);\n for (var index = 0; index < len; index++) {\n arrayBuffer[index] = index;\n }\n return audioBuf;\n };\n\n // initialize counterNode, set its initial buffer and playbackRate\n p5.SoundFile.prototype._initCounterNode = function() {\n var self = this;\n var now = ac.currentTime;\n var cNode = ac.createBufferSource();\n\n // dispose of worklet node if it already exists\n if (self._workletNode) {\n self._workletNode.disconnect();\n delete self._workletNode;\n }\n self._workletNode = new AudioWorkletNode(ac, processorNames.soundFileProcessor);\n self._workletNode.port.onmessage = event => {\n if (event.data.name === 'position') {\n // event.data.position should only be 0 when paused\n if (event.data.position === 0) {\n return;\n }\n this._lastPos = event.data.position;\n\n // do any callbacks that have been scheduled\n this._onTimeUpdate(self._lastPos);\n }\n };\n\n // create counter buffer of the same length as self.buffer\n cNode.buffer = _createCounterBuffer( self.buffer );\n\n cNode.playbackRate.setValueAtTime(self.playbackRate, now);\n\n cNode.connect(self._workletNode);\n self._workletNode.connect(p5.soundOut._silentNode);\n\n return cNode;\n };\n\n // initialize sourceNode, set its initial buffer and playbackRate\n p5.SoundFile.prototype._initSourceNode = function() {\n var bufferSourceNode = ac.createBufferSource();\n bufferSourceNode.buffer = this.buffer;\n bufferSourceNode.playbackRate.value = this.playbackRate;\n bufferSourceNode.connect(this.output);\n return bufferSourceNode;\n };\n\n /**\n * processPeaks returns an array of timestamps where it thinks there is a beat.\n *\n * This is an asynchronous function that processes the soundfile in an offline audio context,\n * and sends the results to your callback function.\n *\n * The process involves running the soundfile through a lowpass filter, and finding all of the\n * peaks above the initial threshold. If the total number of peaks are below the minimum number of peaks,\n * it decreases the threshold and re-runs the analysis until either minPeaks or minThreshold are reached.\n *\n * @method processPeaks\n * @for p5.SoundFile\n * @param {Function} callback a function to call once this data is returned\n * @param {Number} [initThreshold] initial threshold defaults to 0.9\n * @param {Number} [minThreshold] minimum threshold defaults to 0.22\n * @param {Number} [minPeaks] minimum number of peaks defaults to 200\n * @return {Array} Array of timestamped peaks\n */\n p5.SoundFile.prototype.processPeaks = function(callback, _initThreshold, _minThreshold, _minPeaks) {\n var bufLen = this.buffer.length;\n var sampleRate = this.buffer.sampleRate;\n var buffer = this.buffer;\n var allPeaks = [];\n\n var initialThreshold = _initThreshold || 0.9,\n threshold = initialThreshold,\n minThreshold = _minThreshold || 0.22,\n minPeaks = _minPeaks || 200;\n\n // Create offline context\n var offlineContext = new window.OfflineAudioContext(1, bufLen, sampleRate);\n\n // create buffer source\n var source = offlineContext.createBufferSource();\n source.buffer = buffer;\n\n // Create filter. TO DO: allow custom setting of filter\n var filter = offlineContext.createBiquadFilter();\n filter.type = 'lowpass';\n source.connect(filter);\n filter.connect(offlineContext.destination);\n\n // start playing at time:0\n source.start(0);\n offlineContext.startRendering(); // Render the song\n\n // act on the result\n offlineContext.oncomplete = function(e) {\n if (!self.panner) return;\n var filteredBuffer = e.renderedBuffer;\n var bufferData = filteredBuffer.getChannelData(0);\n\n\n // step 1:\n // create Peak instances, add them to array, with strength and sampleIndex\n do {\n allPeaks = getPeaksAtThreshold(bufferData, threshold);\n threshold -= 0.005;\n } while (Object.keys(allPeaks).length < minPeaks && threshold >= minThreshold);\n\n\n // step 2:\n // find intervals for each peak in the sampleIndex, add tempos array\n var intervalCounts = countIntervalsBetweenNearbyPeaks(allPeaks);\n\n // step 3: find top tempos\n var groups = groupNeighborsByTempo(intervalCounts, filteredBuffer.sampleRate);\n\n // sort top intervals\n var topTempos = groups.sort(function(intA, intB) {\n return intB.count - intA.count;\n\n }).splice(0,5);\n\n // set this SoundFile's tempo to the top tempo ??\n this.tempo = topTempos[0].tempo;\n\n // step 4:\n // new array of peaks at top tempo within a bpmVariance\n var bpmVariance = 5;\n var tempoPeaks = getPeaksAtTopTempo(allPeaks, topTempos[0].tempo, filteredBuffer.sampleRate, bpmVariance);\n\n callback(tempoPeaks);\n };\n };\n\n // process peaks\n var Peak = function(amp, i) {\n this.sampleIndex = i;\n this.amplitude = amp;\n this.tempos = [];\n this.intervals = [];\n };\n\n // 1. for processPeaks() Function to identify peaks above a threshold\n // returns an array of peak indexes as frames (samples) of the original soundfile\n function getPeaksAtThreshold(data, threshold) {\n var peaksObj = {};\n var length = data.length;\n\n for (var i = 0; i < length; i++) {\n if (data[i] > threshold) {\n var amp = data[i];\n var peak = new Peak(amp, i);\n peaksObj[i] = peak;\n // Skip forward ~ 1/8s to get past this peak.\n i += 6000;\n }\n i++;\n }\n return peaksObj;\n }\n\n // 2. for processPeaks()\n function countIntervalsBetweenNearbyPeaks(peaksObj) {\n var intervalCounts = [];\n var peaksArray = Object.keys(peaksObj).sort();\n\n for (var index = 0; index < peaksArray.length; index++) {\n\n // find intervals in comparison to nearby peaks\n for (var i = 0; i < 10; i++) {\n var startPeak = peaksObj[peaksArray[index]];\n var endPeak = peaksObj[peaksArray[index + i]];\n\n if (startPeak && endPeak) {\n var startPos = startPeak.sampleIndex;\n var endPos = endPeak.sampleIndex;\n var interval = endPos - startPos;\n\n // add a sample interval to the startPeak in the allPeaks array\n if (interval > 0) {\n startPeak.intervals.push(interval);\n }\n\n // tally the intervals and return interval counts\n var foundInterval = intervalCounts.some(function(intervalCount) {\n if (intervalCount.interval === interval) {\n intervalCount.count++;\n return intervalCount;\n }\n });\n\n // store with JSON like formatting\n if (!foundInterval) {\n intervalCounts.push({\n interval: interval,\n count: 1,\n });\n }\n }\n }\n }\n\n return intervalCounts;\n }\n\n\n // 3. for processPeaks --> find tempo\n function groupNeighborsByTempo(intervalCounts, sampleRate) {\n var tempoCounts = [];\n\n intervalCounts.forEach(function(intervalCount) {\n\n try {\n // Convert an interval to tempo\n var theoreticalTempo = Math.abs( 60 / (intervalCount.interval / sampleRate ) );\n\n theoreticalTempo = mapTempo(theoreticalTempo);\n\n var foundTempo = tempoCounts.some(function(tempoCount) {\n if (tempoCount.tempo === theoreticalTempo)\n return tempoCount.count += intervalCount.count;\n });\n if (!foundTempo) {\n if (isNaN(theoreticalTempo)) {\n return;\n }\n tempoCounts.push({\n tempo: Math.round(theoreticalTempo),\n count: intervalCount.count\n });\n }\n } catch(e) {\n throw e;\n }\n\n });\n\n return tempoCounts;\n }\n\n // 4. for processPeaks - get peaks at top tempo\n function getPeaksAtTopTempo(peaksObj, tempo, sampleRate, bpmVariance) {\n var peaksAtTopTempo = [];\n var peaksArray = Object.keys(peaksObj).sort();\n\n // TO DO: filter out peaks that have the tempo and return\n for (var i = 0; i < peaksArray.length; i++) {\n var key = peaksArray[i];\n var peak = peaksObj[key];\n\n for (var j = 0; j < peak.intervals.length; j++) {\n var intervalBPM = Math.round(Math.abs( 60 / (peak.intervals[j] / sampleRate) ) );\n\n intervalBPM = mapTempo(intervalBPM);\n\n if ( Math.abs(intervalBPM - tempo) < bpmVariance ) {\n // convert sampleIndex to seconds\n peaksAtTopTempo.push(peak.sampleIndex/sampleRate);\n }\n }\n }\n\n // filter out peaks that are very close to each other\n peaksAtTopTempo = peaksAtTopTempo.filter(function(peakTime, index, arr) {\n var dif = arr[index + 1] - peakTime;\n if (dif > 0.01) {\n return true;\n }\n });\n\n return peaksAtTopTempo;\n }\n\n // helper function for processPeaks\n function mapTempo(theoreticalTempo) {\n // these scenarios create infinite while loop\n if (!isFinite(theoreticalTempo) || theoreticalTempo === 0 ) {\n return;\n }\n\n // Adjust the tempo to fit within the 90-180 BPM range\n while (theoreticalTempo < 90) theoreticalTempo *= 2;\n while (theoreticalTempo > 180 && theoreticalTempo > 90) theoreticalTempo /= 2;\n\n return theoreticalTempo;\n }\n\n\n /*** SCHEDULE EVENTS ***/\n\n // Cue inspired by JavaScript setTimeout, and the\n // Tone.js Transport Timeline Event, MIT License Yotam Mann 2015 tonejs.org\n var Cue = function(callback, time, id, val) {\n this.callback = callback;\n this.time = time;\n this.id = id;\n this.val = val;\n };\n\n /**\n * Schedule events to trigger every time a MediaElement\n * (audio/video) reaches a playback cue point.\n *\n * Accepts a callback function, a time (in seconds) at which to trigger\n * the callback, and an optional parameter for the callback.\n *\n * Time will be passed as the first parameter to the callback function,\n * and param will be the second parameter.\n *\n *\n * @method addCue\n * @for p5.SoundFile\n * @param {Number} time Time in seconds, relative to this media\n * element's playback. For example, to trigger\n * an event every time playback reaches two\n * seconds, pass in the number 2. This will be\n * passed as the first parameter to\n * the callback function.\n * @param {Function} callback Name of a function that will be\n * called at the given time. The callback will\n * receive time and (optionally) param as its\n * two parameters.\n * @param {Object} [value] An object to be passed as the\n * second parameter to the\n * callback function.\n * @return {Number} id ID of this cue,\n * useful for removeCue(id)\n * @example\n *
\n */\n p5.SoundFile.prototype.addCue = function(time, callback, val) {\n var id = this._cueIDCounter++;\n\n var cue = new Cue(callback, time, id, val);\n this._cues.push(cue);\n\n // if (!this.elt.ontimeupdate) {\n // this.elt.ontimeupdate = this._onTimeUpdate.bind(this);\n // }\n\n return id;\n };\n\n /**\n * Remove a callback based on its ID. The ID is returned by the\n * addCue method.\n *\n * @method removeCue\n * @for p5.SoundFile\n * @param {Number} id ID of the cue, as returned by addCue\n */\n p5.SoundFile.prototype.removeCue = function(id) {\n var cueLength = this._cues.length;\n for (var i = 0; i < cueLength; i++) {\n var cue = this._cues[i];\n if (cue.id === id) {\n this._cues.splice(i, 1);\n break;\n }\n }\n\n if (this._cues.length === 0) {\n // TO DO: remove callback\n // this.elt.ontimeupdate = null\n }\n };\n\n /**\n * Remove all of the callbacks that had originally been scheduled\n * via the addCue method.\n *\n * @method clearCues\n */\n p5.SoundFile.prototype.clearCues = function() {\n this._cues = [];\n // this.elt.ontimeupdate = null;\n };\n\n // private method that checks for cues to be fired if events\n // have been scheduled using addCue(callback, time).\n p5.SoundFile.prototype._onTimeUpdate = function(position) {\n var playbackTime = position/this.buffer.sampleRate;\n var cueLength = this._cues.length;\n\n for (var i = 0 ; i < cueLength; i++) {\n var cue = this._cues[i];\n var callbackTime = cue.time;\n var val = cue.val;\n\n if (this._prevTime < callbackTime && callbackTime <= playbackTime) {\n\n // pass the scheduled callbackTime as parameter to the callback\n cue.callback(val);\n }\n\n }\n\n this._prevTime = playbackTime;\n };\n\n /**\n * Save a p5.SoundFile as a .wav file. The browser will prompt the user\n * to download the file to their device. To upload a file to a server, see\n * getBlob\n *\n * @method save\n * @for p5.SoundFile\n * @param {String} [fileName] name of the resulting .wav file.\n * @example\n *
\n * var inp, button, mySound;\n * var fileName = 'cool';\n * function preload() {\n * mySound = loadSound('assets/doorbell.mp3');\n * }\n * function setup() {\n * btn = createButton('click to save file');\n * btn.position(0, 0);\n * btn.mouseClicked(handleMouseClick);\n * }\n *\n * function handleMouseClick() {\n * mySound.save(fileName);\n * }\n *
\n */\n p5.SoundFile.prototype.save = function(fileName) {\n const dataView = convertToWav(this.buffer);\n p5.prototype.saveSound([dataView], fileName, 'wav');\n };\n\n /**\n * This method is useful for sending a SoundFile to a server. It returns the\n * .wav-encoded audio data as a \"Blob\".\n * A Blob is a file-like data object that can be uploaded to a server\n * with an http request. We'll\n * use the `httpDo` options object to send a POST request with some\n * specific options: we encode the request as `multipart/form-data`,\n * and attach the blob as one of the form values using `FormData`.\n *\n *\n * @method getBlob\n * @for p5.SoundFile\n * @returns {Blob} A file-like data object\n * @example\n *
\n *\n * function preload() {\n * mySound = loadSound('assets/doorbell.mp3');\n * }\n *\n * function setup() {\n * noCanvas();\n * var soundBlob = mySound.getBlob();\n *\n * // Now we can send the blob to a server...\n * var serverUrl = 'https://jsonplaceholder.typicode.com/posts';\n * var httpRequestOptions = {\n * method: 'POST',\n * body: new FormData().append('soundBlob', soundBlob),\n * headers: new Headers({\n * 'Content-Type': 'multipart/form-data'\n * })\n * };\n * httpDo(serverUrl, httpRequestOptions);\n *\n * // We can also create an `ObjectURL` pointing to the Blob\n * var blobUrl = URL.createObjectURL(soundBlob);\n *\n * // The `
\n */\n p5.SoundFile.prototype.getBlob = function() {\n const dataView = convertToWav(this.buffer);\n return new Blob([dataView], { type: 'audio/wav' });\n };\n\n // event handler to remove references to the bufferSourceNode when it is done playing\n function _clearOnEnd(e) {\n const thisBufferSourceNode = e.target;\n const soundFile = this;\n\n // delete this.bufferSourceNode from the sources array when it is done playing:\n thisBufferSourceNode._playing = false;\n thisBufferSourceNode.removeEventListener('ended', soundFile._clearOnEnd);\n\n // call the onended callback\n soundFile._onended(soundFile);\n\n soundFile.bufferSourceNodes.forEach(function (n, i) {\n if (n._playing === false) {\n soundFile.bufferSourceNodes.splice(i);\n }\n });\n\n if (soundFile.bufferSourceNodes.length === 0) {\n soundFile._playing = false;\n }\n }\n});\n","'use strict';\n\ndefine(function (require) {\n var p5sound = require('master');\n var processorNames = require('./audioWorklet/processorNames');\n\n /**\n * Amplitude measures volume between 0.0 and 1.0.\n * Listens to all p5sound by default, or use setInput()\n * to listen to a specific sound source. Accepts an optional\n * smoothing value, which defaults to 0.\n *\n * @class p5.Amplitude\n * @constructor\n * @param {Number} [smoothing] between 0.0 and .999 to smooth\n * amplitude readings (defaults to 0)\n * @example\n *
\n * var sound, amplitude, cnv;\n *\n * function preload(){\n * sound = loadSound('assets/beat.mp3');\n * }\n * function setup() {\n * cnv = createCanvas(100,100);\n * amplitude = new p5.Amplitude();\n *\n * // start / stop the sound when canvas is clicked\n * cnv.mouseClicked(function() {\n * if (sound.isPlaying() ){\n * sound.stop();\n * } else {\n * sound.play();\n * }\n * });\n * }\n * function draw() {\n * background(0);\n * fill(255);\n * var level = amplitude.getLevel();\n * var size = map(level, 0, 1, 0, 200);\n * ellipse(width/2, height/2, size, size);\n * }\n *\n *
\n */\n p5.Amplitude = function(smoothing) {\n\n // Set to 2048 for now. In future iterations, this should be inherited or parsed from p5sound's default\n this.bufferSize = 2048;\n\n // set audio context\n this.audiocontext = p5sound.audiocontext;\n this._workletNode = new AudioWorkletNode(this.audiocontext, processorNames.amplitudeProcessor, {\n outputChannelCount: [1],\n processorOptions: {\n normalize: false,\n smoothing: smoothing || 0\n }\n });\n\n this._workletNode.port.onmessage = function(event) {\n if (event.data.name === 'amplitude') {\n this.volume = event.data.volume;\n this.volNorm = event.data.volNorm;\n this.stereoVol = event.data.stereoVol;\n this.stereoVolNorm = event.data.stereoVolNorm;\n }\n }.bind(this);\n\n // for connections\n this.input = this._workletNode;\n\n this.output = this.audiocontext.createGain();\n\n // the variables to return\n this.volume = 0;\n this.volNorm = 0;\n this.stereoVol = [0, 0];\n this.stereoVolNorm = [0, 0];\n\n this.normalize = false;\n\n this._workletNode.connect(this.output);\n this.output.gain.value = 0;\n\n // this may only be necessary because of a Chrome bug\n this.output.connect(this.audiocontext.destination);\n\n // connect to p5sound master output by default, unless set by input()\n p5sound.meter.connect(this._workletNode);\n\n // add this p5.SoundFile to the soundArray\n p5sound.soundArray.push(this);\n };\n\n /**\n * Connects to the p5sound instance (master output) by default.\n * Optionally, you can pass in a specific source (i.e. a soundfile).\n *\n * @method setInput\n * @for p5.Amplitude\n * @param {soundObject|undefined} [snd] set the sound source\n * (optional, defaults to\n * master output)\n * @param {Number|undefined} [smoothing] a range between 0.0 and 1.0\n * to smooth amplitude readings\n * @example\n *
\n * function preload(){\n * sound1 = loadSound('assets/beat.mp3');\n * sound2 = loadSound('assets/drum.mp3');\n * }\n * function setup(){\n * amplitude = new p5.Amplitude();\n * sound1.play();\n * sound2.play();\n * amplitude.setInput(sound2);\n * }\n * function draw() {\n * background(0);\n * fill(255);\n * var level = amplitude.getLevel();\n * var size = map(level, 0, 1, 0, 200);\n * ellipse(width/2, height/2, size, size);\n * }\n * function mouseClicked(){\n * sound1.stop();\n * sound2.stop();\n * }\n *
\n */\n p5.Amplitude.prototype.setInput = function(source, smoothing) {\n\n p5sound.meter.disconnect();\n\n if (smoothing) {\n this._workletNode.parameters.get('smoothing').value = smoothing;\n }\n\n // connect to the master out of p5s instance if no snd is provided\n if (source == null) {\n console.log('Amplitude input source is not ready! Connecting to master output instead');\n p5sound.meter.connect(this._workletNode);\n }\n\n // if it is a p5.Signal\n else if (source instanceof p5.Signal) {\n source.output.connect(this._workletNode);\n }\n // connect to the sound if it is available\n else if (source) {\n source.connect(this._workletNode);\n this._workletNode.disconnect();\n this._workletNode.connect(this.output);\n }\n\n // otherwise, connect to the master out of p5s instance (default)\n else {\n p5sound.meter.connect(this._workletNode);\n }\n };\n\n p5.Amplitude.prototype.connect = function(unit) {\n if (unit) {\n if (unit.hasOwnProperty('input')) {\n this.output.connect(unit.input);\n } else {\n this.output.connect(unit);\n }\n } else {\n this.output.connect(this.panner.connect(p5sound.input));\n }\n };\n\n p5.Amplitude.prototype.disconnect = function() {\n if (this.output) {\n this.output.disconnect();\n }\n };\n\n /**\n * Returns a single Amplitude reading at the moment it is called.\n * For continuous readings, run in the draw loop.\n *\n * @method getLevel\n * @for p5.Amplitude\n * @param {Number} [channel] Optionally return only channel 0 (left) or 1 (right)\n * @return {Number} Amplitude as a number between 0.0 and 1.0\n * @example\n *
\n * function preload(){\n * sound = loadSound('assets/beat.mp3');\n * }\n * function setup() {\n * amplitude = new p5.Amplitude();\n * sound.play();\n * }\n * function draw() {\n * background(0);\n * fill(255);\n * var level = amplitude.getLevel();\n * var size = map(level, 0, 1, 0, 200);\n * ellipse(width/2, height/2, size, size);\n * }\n * function mouseClicked(){\n * sound.stop();\n * }\n *
\n */\n p5.Amplitude.prototype.getLevel = function(channel) {\n if (typeof channel !== 'undefined') {\n if (this.normalize) {\n return this.stereoVolNorm[channel];\n } else {\n return this.stereoVol[channel];\n }\n }\n else if (this.normalize) {\n return this.volNorm;\n }\n else {\n return this.volume;\n }\n };\n\n /**\n * Determines whether the results of Amplitude.process() will be\n * Normalized. To normalize, Amplitude finds the difference the\n * loudest reading it has processed and the maximum amplitude of\n * 1.0. Amplitude adds this difference to all values to produce\n * results that will reliably map between 0.0 and 1.0. However,\n * if a louder moment occurs, the amount that Normalize adds to\n * all the values will change. Accepts an optional boolean parameter\n * (true or false). Normalizing is off by default.\n *\n * @method toggleNormalize\n * @for p5.Amplitude\n * @param {boolean} [boolean] set normalize to true (1) or false (0)\n */\n p5.Amplitude.prototype.toggleNormalize = function(bool) {\n if (typeof bool === 'boolean') {\n this.normalize = bool;\n }\n else {\n this.normalize = !this.normalize;\n }\n this._workletNode.port.postMessage({ name: 'toggleNormalize', normalize: this.normalize });\n };\n\n /**\n * Smooth Amplitude analysis by averaging with the last analysis\n * frame. Off by default.\n *\n * @method smooth\n * @for p5.Amplitude\n * @param {Number} set smoothing from 0.0 <= 1\n */\n p5.Amplitude.prototype.smooth = function(s) {\n if (s >= 0 && s < 1) {\n this._workletNode.port.postMessage({ name: 'smoothing', smoothing: s });\n } else {\n console.log('Error: smoothing must be between 0 and 1');\n }\n };\n\n p5.Amplitude.prototype.dispose = function() {\n // remove reference from soundArray\n var index = p5sound.soundArray.indexOf(this);\n p5sound.soundArray.splice(index, 1);\n\n if (this.input) {\n this.input.disconnect();\n delete this.input;\n }\n if (this.output) {\n this.output.disconnect();\n delete this.output;\n }\n\n this._workletNode.disconnect();\n delete this._workletNode;\n };\n\n});\n","'use strict';\n\ndefine(function(require) {\n var p5sound = require('master');\n\n /**\n *
FFT (Fast Fourier Transform) is an analysis algorithm that\n * isolates individual\n * \n * audio frequencies within a waveform.
\n *\n *
Once instantiated, a p5.FFT object can return an array based on\n * two types of analyses: • FFT.waveform() computes\n * amplitude values along the time domain. The array indices correspond\n * to samples across a brief moment in time. Each value represents\n * amplitude of the waveform at that sample of time. \n * • FFT.analyze() computes amplitude values along the\n * frequency domain. The array indices correspond to frequencies (i.e.\n * pitches), from the lowest to the highest that humans can hear. Each\n * value represents amplitude at that slice of the frequency spectrum.\n * Use with getEnergy() to measure amplitude at specific\n * frequencies, or within a range of frequencies.
\n *\n *
FFT analyzes a very short snapshot of sound called a sample\n * buffer. It returns an array of amplitude measurements, referred\n * to as bins. The array is 1024 bins long by default.\n * You can change the bin array length, but it must be a power of 2\n * between 16 and 1024 in order for the FFT algorithm to function\n * correctly. The actual size of the FFT buffer is twice the\n * number of bins, so given a standard sample rate, the buffer is\n * 2048/44100 seconds long.
\n *\n *\n * @class p5.FFT\n * @constructor\n * @param {Number} [smoothing] Smooth results of Freq Spectrum.\n * 0.0 < smoothing < 1.0.\n * Defaults to 0.8.\n * @param {Number} [bins] Length of resulting array.\n * Must be a power of two between\n * 16 and 1024. Defaults to 1024.\n * @example\n *
\n * function preload(){\n * sound = loadSound('assets/Damscray_DancingTiger.mp3');\n * }\n *\n * function setup(){\n * var cnv = createCanvas(100,100);\n * cnv.mouseClicked(togglePlay);\n * fft = new p5.FFT();\n * sound.amp(0.2);\n * }\n *\n * function draw(){\n * background(0);\n *\n * var spectrum = fft.analyze();\n * noStroke();\n * fill(0,255,0); // spectrum is green\n * for (var i = 0; i< spectrum.length; i++){\n * var x = map(i, 0, spectrum.length, 0, width);\n * var h = -height + map(spectrum[i], 0, 255, height, 0);\n * rect(x, height, width / spectrum.length, h )\n * }\n *\n * var waveform = fft.waveform();\n * noFill();\n * beginShape();\n * stroke(255,0,0); // waveform is red\n * strokeWeight(1);\n * for (var i = 0; i< waveform.length; i++){\n * var x = map(i, 0, waveform.length, 0, width);\n * var y = map( waveform[i], -1, 1, 0, height);\n * vertex(x,y);\n * }\n * endShape();\n *\n * text('click to play/pause', 4, 10);\n * }\n *\n * // fade sound if mouse is over canvas\n * function togglePlay() {\n * if (sound.isPlaying()) {\n * sound.pause();\n * } else {\n * sound.loop();\n * }\n * }\n *
\n */\n p5.FFT = function(smoothing, bins) {\n this.input = this.analyser = p5sound.audiocontext.createAnalyser();\n\n Object.defineProperties(this, {\n bins: {\n get: function() {\n return this.analyser.fftSize / 2;\n },\n set: function(b) {\n this.analyser.fftSize = b * 2;\n },\n configurable: true,\n enumerable: true\n },\n smoothing: {\n get: function() {\n return this.analyser.smoothingTimeConstant;\n },\n set: function(s) {\n this.analyser.smoothingTimeConstant = s;\n },\n configurable: true,\n enumerable: true\n }\n });\n\n // set default smoothing and bins\n this.smooth(smoothing);\n this.bins = bins || 1024;\n\n // default connections to p5sound fftMeter\n p5sound.fftMeter.connect(this.analyser);\n\n this.freqDomain = new Uint8Array(this.analyser.frequencyBinCount);\n this.timeDomain = new Uint8Array(this.analyser.frequencyBinCount);\n\n // predefined frequency ranges, these will be tweakable\n this.bass = [20, 140];\n this.lowMid = [140, 400];\n this.mid = [400, 2600];\n this.highMid = [2600, 5200];\n this.treble = [5200, 14000];\n\n // add this p5.SoundFile to the soundArray\n p5sound.soundArray.push(this);\n };\n\n /**\n * Set the input source for the FFT analysis. If no source is\n * provided, FFT will analyze all sound in the sketch.\n *\n * @method setInput\n * @for p5.FFT\n * @param {Object} [source] p5.sound object (or web audio API source node)\n */\n p5.FFT.prototype.setInput = function(source) {\n if (!source) {\n p5sound.fftMeter.connect(this.analyser);\n } else {\n if (source.output) {\n source.output.connect(this.analyser);\n } else if (source.connect) {\n source.connect(this.analyser);\n }\n p5sound.fftMeter.disconnect();\n }\n };\n\n /**\n * Returns an array of amplitude values (between -1.0 and +1.0) that represent\n * a snapshot of amplitude readings in a single buffer. Length will be\n * equal to bins (defaults to 1024). Can be used to draw the waveform\n * of a sound.\n *\n * @method waveform\n * @for p5.FFT\n * @param {Number} [bins] Must be a power of two between\n * 16 and 1024. Defaults to 1024.\n * @param {String} [precision] If any value is provided, will return results\n * in a Float32 Array which is more precise\n * than a regular array.\n * @return {Array} Array Array of amplitude values (-1 to 1)\n * over time. Array length = bins.\n *\n */\n p5.FFT.prototype.waveform = function() {\n var bins, mode, normalArray;\n\n for (var i = 0; i < arguments.length; i++) {\n if (typeof arguments[i] === 'number') {\n bins = arguments[i];\n this.analyser.fftSize = bins * 2;\n }\n if (typeof arguments[i] === 'string') {\n mode = arguments[i];\n }\n }\n\n // getFloatFrequencyData doesnt work in Safari as of 5/2015\n if (mode && !p5.prototype._isSafari()) {\n timeToFloat(this, this.timeDomain);\n this.analyser.getFloatTimeDomainData(this.timeDomain);\n return this.timeDomain;\n } else {\n timeToInt(this, this.timeDomain);\n this.analyser.getByteTimeDomainData(this.timeDomain);\n var normalArray = new Array();\n for (var j = 0; j < this.timeDomain.length; j++) {\n var scaled = p5.prototype.map(this.timeDomain[j], 0, 255, -1, 1);\n normalArray.push(scaled);\n }\n return normalArray;\n }\n };\n\n /**\n * Returns an array of amplitude values (between 0 and 255)\n * across the frequency spectrum. Length is equal to FFT bins\n * (1024 by default). The array indices correspond to frequencies\n * (i.e. pitches), from the lowest to the highest that humans can\n * hear. Each value represents amplitude at that slice of the\n * frequency spectrum. Must be called prior to using\n * getEnergy().\n *\n * @method analyze\n * @for p5.FFT\n * @param {Number} [bins] Must be a power of two between\n * 16 and 1024. Defaults to 1024.\n * @param {Number} [scale] If \"dB,\" returns decibel\n * float measurements between\n * -140 and 0 (max).\n * Otherwise returns integers from 0-255.\n * @return {Array} spectrum Array of energy (amplitude/volume)\n * values across the frequency spectrum.\n * Lowest energy (silence) = 0, highest\n * possible is 255.\n * @example\n *
\n * var osc;\n * var fft;\n *\n * function setup(){\n * createCanvas(100,100);\n * osc = new p5.Oscillator();\n * osc.amp(0);\n * osc.start();\n * fft = new p5.FFT();\n * }\n *\n * function draw(){\n * background(0);\n *\n * var freq = map(mouseX, 0, 800, 20, 15000);\n * freq = constrain(freq, 1, 20000);\n * osc.freq(freq);\n *\n * var spectrum = fft.analyze();\n * noStroke();\n * fill(0,255,0); // spectrum is green\n * for (var i = 0; i< spectrum.length; i++){\n * var x = map(i, 0, spectrum.length, 0, width);\n * var h = -height + map(spectrum[i], 0, 255, height, 0);\n * rect(x, height, width / spectrum.length, h );\n * }\n *\n * stroke(255);\n * text('Freq: ' + round(freq)+'Hz', 10, 10);\n *\n * isMouseOverCanvas();\n * }\n *\n * // only play sound when mouse is over canvas\n * function isMouseOverCanvas() {\n * var mX = mouseX, mY = mouseY;\n * if (mX > 0 && mX < width && mY < height && mY > 0) {\n * osc.amp(0.5, 0.2);\n * } else {\n * osc.amp(0, 0.2);\n * }\n * }\n *
\n *\n *\n */\n p5.FFT.prototype.analyze = function() {\n var mode;\n\n for (var i = 0; i < arguments.length; i++) {\n if (typeof arguments[i] === 'number') {\n this.bins = arguments[i];\n this.analyser.fftSize = this.bins * 2;\n }\n if (typeof arguments[i] === 'string') {\n mode = arguments[i];\n }\n }\n\n if (mode && mode.toLowerCase() === 'db') {\n freqToFloat(this);\n this.analyser.getFloatFrequencyData(this.freqDomain);\n return this.freqDomain;\n } else {\n freqToInt(this, this.freqDomain);\n this.analyser.getByteFrequencyData(this.freqDomain);\n var normalArray = Array.apply([], this.freqDomain);\n \n return normalArray;\n }\n };\n\n /**\n * Returns the amount of energy (volume) at a specific\n * \n * frequency, or the average amount of energy between two\n * frequencies. Accepts Number(s) corresponding\n * to frequency (in Hz), or a String corresponding to predefined\n * frequency ranges (\"bass\", \"lowMid\", \"mid\", \"highMid\", \"treble\").\n * Returns a range between 0 (no energy/volume at that frequency) and\n * 255 (maximum energy).\n * NOTE: analyze() must be called prior to getEnergy(). Analyze()\n * tells the FFT to analyze frequency data, and getEnergy() uses\n * the results determine the value at a specific frequency or\n * range of frequencies.\n *\n * @method getEnergy\n * @for p5.FFT\n * @param {Number|String} frequency1 Will return a value representing\n * energy at this frequency. Alternately,\n * the strings \"bass\", \"lowMid\" \"mid\",\n * \"highMid\", and \"treble\" will return\n * predefined frequency ranges.\n * @param {Number} [frequency2] If a second frequency is given,\n * will return average amount of\n * energy that exists between the\n * two frequencies.\n * @return {Number} Energy Energy (volume/amplitude) from\n * 0 and 255.\n *\n */\n p5.FFT.prototype.getEnergy = function(frequency1, frequency2) {\n var nyquist = p5sound.audiocontext.sampleRate / 2;\n\n if (frequency1 === 'bass') {\n frequency1 = this.bass[0];\n frequency2 = this.bass[1];\n } else if (frequency1 === 'lowMid') {\n frequency1 = this.lowMid[0];\n frequency2 = this.lowMid[1];\n } else if (frequency1 === 'mid') {\n frequency1 = this.mid[0];\n frequency2 = this.mid[1];\n } else if (frequency1 === 'highMid') {\n frequency1 = this.highMid[0];\n frequency2 = this.highMid[1];\n } else if (frequency1 === 'treble') {\n frequency1 = this.treble[0];\n frequency2 = this.treble[1];\n }\n\n if (typeof frequency1 !== 'number') {\n throw 'invalid input for getEnergy()';\n } else if (!frequency2) {\n // if only one parameter:\n var index = Math.round(frequency1 / nyquist * this.freqDomain.length);\n return this.freqDomain[index];\n } else if (frequency1 && frequency2) {\n // if two parameters:\n // if second is higher than first\n if (frequency1 > frequency2) {\n var swap = frequency2;\n frequency2 = frequency1;\n frequency1 = swap;\n }\n var lowIndex = Math.round(frequency1 / nyquist * this.freqDomain.length);\n var highIndex = Math.round(frequency2 / nyquist * this.freqDomain.length);\n\n var total = 0;\n var numFrequencies = 0;\n // add up all of the values for the frequencies\n for (var i = lowIndex; i <= highIndex; i++) {\n total += this.freqDomain[i];\n numFrequencies += 1;\n }\n // divide by total number of frequencies\n var toReturn = total / numFrequencies;\n return toReturn;\n } else {\n throw 'invalid input for getEnergy()';\n }\n };\n\n // compatability with v.012, changed to getEnergy in v.0121. Will be deprecated...\n p5.FFT.prototype.getFreq = function(freq1, freq2) {\n console.log('getFreq() is deprecated. Please use getEnergy() instead.');\n var x = this.getEnergy(freq1, freq2);\n return x;\n };\n\n /**\n * Returns the\n * \n * spectral centroid of the input signal.\n * NOTE: analyze() must be called prior to getCentroid(). Analyze()\n * tells the FFT to analyze frequency data, and getCentroid() uses\n * the results determine the spectral centroid.\n *\n * @method getCentroid\n * @for p5.FFT\n * @return {Number} Spectral Centroid Frequency Frequency of the spectral centroid in Hz.\n *\n *\n * @example\n *
\n *\n *\n *function setup(){\n * cnv = createCanvas(100,100);\n * sound = new p5.AudioIn();\n * sound.start();\n * fft = new p5.FFT();\n * sound.connect(fft);\n *}\n *\n *\n *function draw(){\n *\n * var centroidplot = 0.0;\n * var spectralCentroid = 0;\n *\n *\n * background(0);\n * stroke(0,255,0);\n * var spectrum = fft.analyze();\n * fill(0,255,0); // spectrum is green\n *\n * //draw the spectrum\n * for (var i = 0; i< spectrum.length; i++){\n * var x = map(log(i), 0, log(spectrum.length), 0, width);\n * var h = map(spectrum[i], 0, 255, 0, height);\n * var rectangle_width = (log(i+1)-log(i))*(width/log(spectrum.length));\n * rect(x, height, rectangle_width, -h )\n * }\n\n * var nyquist = 22050;\n *\n * // get the centroid\n * spectralCentroid = fft.getCentroid();\n *\n * // the mean_freq_index calculation is for the display.\n * var mean_freq_index = spectralCentroid/(nyquist/spectrum.length);\n *\n * centroidplot = map(log(mean_freq_index), 0, log(spectrum.length), 0, width);\n *\n *\n * stroke(255,0,0); // the line showing where the centroid is will be red\n *\n * rect(centroidplot, 0, width / spectrum.length, height)\n * noStroke();\n * fill(255,255,255); // text is white\n * text(\"centroid: \", 10, 20);\n * text(round(spectralCentroid)+\" Hz\", 10, 40);\n *}\n *
\n */\n p5.FFT.prototype.getCentroid = function() {\n var nyquist = p5sound.audiocontext.sampleRate / 2;\n var cumulative_sum = 0;\n var centroid_normalization = 0;\n\n for (var i = 0; i < this.freqDomain.length; i++) {\n cumulative_sum += i * this.freqDomain[i];\n centroid_normalization += this.freqDomain[i];\n }\n\n var mean_freq_index = 0;\n\n if (centroid_normalization !== 0) {\n mean_freq_index = cumulative_sum / centroid_normalization;\n }\n\n var spec_centroid_freq =\n mean_freq_index * (nyquist / this.freqDomain.length);\n return spec_centroid_freq;\n };\n\n /**\n * Smooth FFT analysis by averaging with the last analysis frame.\n *\n * @method smooth\n * @param {Number} smoothing 0.0 < smoothing < 1.0.\n * Defaults to 0.8.\n */\n p5.FFT.prototype.smooth = function(s) {\n if (typeof s !== 'undefined') {\n this.smoothing = s;\n }\n return this.smoothing;\n };\n\n p5.FFT.prototype.dispose = function() {\n // remove reference from soundArray\n var index = p5sound.soundArray.indexOf(this);\n p5sound.soundArray.splice(index, 1);\n\n if (this.analyser) {\n this.analyser.disconnect();\n delete this.analyser;\n }\n };\n\n /**\n * Returns an array of average amplitude values for a given number\n * of frequency bands split equally. N defaults to 16.\n * NOTE: analyze() must be called prior to linAverages(). Analyze()\n * tells the FFT to analyze frequency data, and linAverages() uses\n * the results to group them into a smaller set of averages.\n *\n * @method linAverages\n * @for p5.FFT\n * @param {Number} N Number of returned frequency groups\n * @return {Array} linearAverages Array of average amplitude values for each group\n */\n p5.FFT.prototype.linAverages = function(N) {\n var N = N || 16; // This prevents undefined, null or 0 values of N\n\n var spectrum = this.freqDomain;\n var spectrumLength = spectrum.length;\n var spectrumStep = Math.floor(spectrumLength / N);\n\n var linearAverages = new Array(N);\n // Keep a second index for the current average group and place the values accordingly\n // with only one loop in the spectrum data\n var groupIndex = 0;\n\n for (var specIndex = 0; specIndex < spectrumLength; specIndex++) {\n linearAverages[groupIndex] =\n linearAverages[groupIndex] !== undefined\n ? (linearAverages[groupIndex] + spectrum[specIndex]) / 2\n : spectrum[specIndex];\n\n // Increase the group index when the last element of the group is processed\n if (specIndex % spectrumStep === spectrumStep - 1) {\n groupIndex++;\n }\n }\n\n return linearAverages;\n };\n\n /**\n * Returns an array of average amplitude values of the spectrum, for a given\n * set of \n * Octave Bands\n * NOTE: analyze() must be called prior to logAverages(). Analyze()\n * tells the FFT to analyze frequency data, and logAverages() uses\n * the results to group them into a smaller set of averages.\n *\n * @method logAverages\n * @for p5.FFT\n * @param {Array} octaveBands Array of Octave Bands objects for grouping\n * @return {Array} logAverages Array of average amplitude values for each group\n */\n p5.FFT.prototype.logAverages = function(octaveBands) {\n var nyquist = p5sound.audiocontext.sampleRate / 2;\n var spectrum = this.freqDomain;\n var spectrumLength = spectrum.length;\n\n var logAverages = new Array(octaveBands.length);\n // Keep a second index for the current average group and place the values accordingly\n // With only one loop in the spectrum data\n var octaveIndex = 0;\n\n for (var specIndex = 0; specIndex < spectrumLength; specIndex++) {\n var specIndexFrequency = Math.round(\n specIndex * nyquist / this.freqDomain.length\n );\n\n // Increase the group index if the current frequency exceeds the limits of the band\n if (specIndexFrequency > octaveBands[octaveIndex].hi) {\n octaveIndex++;\n }\n\n logAverages[octaveIndex] =\n logAverages[octaveIndex] !== undefined\n ? (logAverages[octaveIndex] + spectrum[specIndex]) / 2\n : spectrum[specIndex];\n }\n\n return logAverages;\n };\n\n /**\n * Calculates and Returns the 1/N\n * Octave Bands\n * N defaults to 3 and minimum central frequency to 15.625Hz.\n * (1/3 Octave Bands ~= 31 Frequency Bands)\n * Setting fCtr0 to a central value of a higher octave will ignore the lower bands\n * and produce less frequency groups.\n *\n * @method getOctaveBands\n * @for p5.FFT\n * @param {Number} N Specifies the 1/N type of generated octave bands\n * @param {Number} fCtr0 Minimum central frequency for the lowest band\n * @return {Array} octaveBands Array of octave band objects with their bounds\n */\n p5.FFT.prototype.getOctaveBands = function(N, fCtr0) {\n var N = N || 3; // Default to 1/3 Octave Bands\n var fCtr0 = fCtr0 || 15.625; // Minimum central frequency, defaults to 15.625Hz\n\n var octaveBands = [];\n var lastFrequencyBand = {\n lo: fCtr0 / Math.pow(2, 1 / (2 * N)),\n ctr: fCtr0,\n hi: fCtr0 * Math.pow(2, 1 / (2 * N))\n };\n octaveBands.push(lastFrequencyBand);\n\n var nyquist = p5sound.audiocontext.sampleRate / 2;\n while (lastFrequencyBand.hi < nyquist) {\n var newFrequencyBand = {};\n newFrequencyBand.lo = lastFrequencyBand.hi;\n newFrequencyBand.ctr = lastFrequencyBand.ctr * Math.pow(2, 1 / N);\n newFrequencyBand.hi = newFrequencyBand.ctr * Math.pow(2, 1 / (2 * N));\n\n octaveBands.push(newFrequencyBand);\n lastFrequencyBand = newFrequencyBand;\n }\n\n return octaveBands;\n };\n\n // helper methods to convert type from float (dB) to int (0-255)\n var freqToFloat = function(fft) {\n if (fft.freqDomain instanceof Float32Array === false) {\n fft.freqDomain = new Float32Array(fft.analyser.frequencyBinCount);\n }\n };\n var freqToInt = function(fft) {\n if (fft.freqDomain instanceof Uint8Array === false) {\n fft.freqDomain = new Uint8Array(fft.analyser.frequencyBinCount);\n }\n };\n var timeToFloat = function(fft) {\n if (fft.timeDomain instanceof Float32Array === false) {\n fft.timeDomain = new Float32Array(fft.analyser.frequencyBinCount);\n }\n };\n var timeToInt = function(fft) {\n if (fft.timeDomain instanceof Uint8Array === false) {\n fft.timeDomain = new Uint8Array(fft.analyser.frequencyBinCount);\n }\n };\n});\n","'use strict';\n\ndefine(function (require) {\n\n // Signal is built with the Tone.js signal by Yotam Mann\n // https://github.com/TONEnoTONE/Tone.js/\n var Signal = require('Tone/signal/Signal');\n var Add = require('Tone/signal/Add');\n var Mult = require('Tone/signal/Multiply');\n var Scale = require('Tone/signal/Scale');\n\n /**\n *
p5.Signal is a constant audio-rate signal used by p5.Oscillator\n * and p5.Envelope for modulation math.
\n *\n *
This is necessary because Web Audio is processed on a seprate clock.\n * For example, the p5 draw loop runs about 60 times per second. But\n * the audio clock must process samples 44100 times per second. If we\n * want to add a value to each of those samples, we can't do it in the\n * draw loop, but we can do it by adding a constant-rate audio signal.This class mostly functions behind the scenes in p5.sound, and returns\n * a Tone.Signal from the Tone.js library by Yotam Mann.\n * If you want to work directly with audio signals for modular\n * synthesis, check out\n * tone.js.
\n *\n * @class p5.Signal\n * @constructor\n * @return {Tone.Signal} A Signal object from the Tone.js library\n * @example\n *
\n * function setup() {\n * carrier = new p5.Oscillator('sine');\n * carrier.amp(1); // set amplitude\n * carrier.freq(220); // set frequency\n * carrier.start(); // start oscillating\n *\n * modulator = new p5.Oscillator('sawtooth');\n * modulator.disconnect();\n * modulator.amp(1);\n * modulator.freq(4);\n * modulator.start();\n *\n * // Modulator's default amplitude range is -1 to 1.\n * // Multiply it by -200, so the range is -200 to 200\n * // then add 220 so the range is 20 to 420\n * carrier.freq( modulator.mult(-200).add(220) );\n * }\n *
\n */\n p5.Signal = function(value) {\n var s = new Signal(value);\n // p5sound.soundArray.push(s);\n return s; // TODO: is this really a constructor?\n };\n\n /**\n * Fade to value, for smooth transitions\n *\n * @method fade\n * @for p5.Signal\n * @param {Number} value Value to set this signal\n * @param {Number} [secondsFromNow] Length of fade, in seconds from now\n */\n Signal.prototype.fade = Signal.prototype.linearRampToValueAtTime;\n Mult.prototype.fade = Signal.prototype.fade;\n Add.prototype.fade = Signal.prototype.fade;\n Scale.prototype.fade = Signal.prototype.fade;\n\n\n /**\n * Connect a p5.sound object or Web Audio node to this\n * p5.Signal so that its amplitude values can be scaled.\n *\n * @method setInput\n * @for p5.Signal\n * @param {Object} input\n */\n Signal.prototype.setInput = function(_input) {\n _input.connect(this);\n };\n Mult.prototype.setInput = Signal.prototype.setInput;\n Add.prototype.setInput = Signal.prototype.setInput;\n Scale.prototype.setInput = Signal.prototype.setInput;\n\n\n // signals can add / mult / scale themselves\n\n /**\n * Add a constant value to this audio signal,\n * and return the resulting audio signal. Does\n * not change the value of the original signal,\n * instead it returns a new p5.SignalAdd.\n *\n * @method add\n * @for p5.Signal\n * @param {Number} number\n * @return {p5.Signal} object\n */\n Signal.prototype.add = function(num) {\n var add = new Add(num);\n // add.setInput(this);\n this.connect(add);\n return add;\n };\n Mult.prototype.add = Signal.prototype.add;\n Add.prototype.add = Signal.prototype.add;\n Scale.prototype.add = Signal.prototype.add;\n\n /**\n * Multiply this signal by a constant value,\n * and return the resulting audio signal. Does\n * not change the value of the original signal,\n * instead it returns a new p5.SignalMult.\n *\n * @method mult\n * @for p5.Signal\n * @param {Number} number to multiply\n * @return {p5.Signal} object\n */\n Signal.prototype.mult = function(num) {\n var mult = new Mult(num);\n // mult.setInput(this);\n this.connect(mult);\n return mult;\n };\n Mult.prototype.mult = Signal.prototype.mult;\n Add.prototype.mult = Signal.prototype.mult;\n Scale.prototype.mult = Signal.prototype.mult;\n\n /**\n * Scale this signal value to a given range,\n * and return the result as an audio signal. Does\n * not change the value of the original signal,\n * instead it returns a new p5.SignalScale.\n *\n * @method scale\n * @for p5.Signal\n * @param {Number} number to multiply\n * @param {Number} inMin input range minumum\n * @param {Number} inMax input range maximum\n * @param {Number} outMin input range minumum\n * @param {Number} outMax input range maximum\n * @return {p5.Signal} object\n */\n Signal.prototype.scale = function(inMin, inMax, outMin, outMax) {\n var mapOutMin, mapOutMax;\n if (arguments.length === 4) {\n mapOutMin = p5.prototype.map(outMin, inMin, inMax, 0, 1) - 0.5;\n mapOutMax = p5.prototype.map(outMax, inMin, inMax, 0, 1) - 0.5;\n }\n else {\n mapOutMin = arguments[0];\n mapOutMax = arguments[1];\n }\n var scale = new Scale(mapOutMin, mapOutMax);\n this.connect(scale);\n return scale;\n };\n Mult.prototype.scale = Signal.prototype.scale;\n Add.prototype.scale = Signal.prototype.scale;\n Scale.prototype.scale = Signal.prototype.scale;\n\n});\n\n\n","define([\"Tone/core/Tone\", \"Tone/type/TimeBase\"], function (Tone) {\n\n\t/**\n\t * @class Tone.Frequency is a primitive type for encoding Frequency values. \n\t * Eventually all time values are evaluated to hertz\n\t * using the `eval` method. \n\t * @constructor\n\t * @extends {Tone.TimeBase}\n\t * @param {String|Number} val The time value.\n\t * @param {String=} units The units of the value.\n\t * @example\n\t * Tone.Frequency(\"C3\") // 261\n\t * Tone.Frequency(38, \"midi\") //\n\t * Tone.Frequency(\"C3\").transpose(4);\n\t */\n\tTone.Frequency = function(val, units){\n\t\tif (this instanceof Tone.Frequency){\n\t\t\t\n\t\t\tTone.TimeBase.call(this, val, units);\n\n\t\t} else {\n\t\t\treturn new Tone.Frequency(val, units);\n\t\t}\n\t};\n\n\tTone.extend(Tone.Frequency, Tone.TimeBase);\n\n\t///////////////////////////////////////////////////////////////////////////\n\t//\tAUGMENT BASE EXPRESSIONS\n\t///////////////////////////////////////////////////////////////////////////\n\n\t//clone the expressions so that \n\t//we can add more without modifying the original\n\tTone.Frequency.prototype._primaryExpressions = Object.create(Tone.TimeBase.prototype._primaryExpressions);\n\n\t/*\n\t * midi type primary expression\n\t * @type {Object}\n\t * @private\n\t */\n\tTone.Frequency.prototype._primaryExpressions.midi = {\n\t\tregexp : /^(\\d+(?:\\.\\d+)?midi)/,\n\t\tmethod : function(value){\n\t\t\treturn this.midiToFrequency(value);\n\t\t}\t\n\t};\n\n\t/*\n\t * note type primary expression\n\t * @type {Object}\n\t * @private\n\t */\n\tTone.Frequency.prototype._primaryExpressions.note = {\n\t\tregexp : /^([a-g]{1}(?:b|#|x|bb)?)(-?[0-9]+)/i,\n\t\tmethod : function(pitch, octave){\n\t\t\tvar index = noteToScaleIndex[pitch.toLowerCase()];\n\t\t\tvar noteNumber = index + (parseInt(octave) + 1) * 12;\n\t\t\treturn this.midiToFrequency(noteNumber);\n\t\t}\t\n\t};\n\n\t/*\n\t * BeatsBarsSixteenths type primary expression\n\t * @type {Object}\n\t * @private\n\t */\n\tTone.Frequency.prototype._primaryExpressions.tr = {\n\t\t\tregexp : /^(\\d+(?:\\.\\d+)?):(\\d+(?:\\.\\d+)?):?(\\d+(?:\\.\\d+)?)?/,\n\t\t\tmethod : function(m, q, s){\n\t\t\tvar total = 1;\n\t\t\tif (m && m !== \"0\"){\n\t\t\t\ttotal *= this._beatsToUnits(this._timeSignature() * parseFloat(m));\n\t\t\t}\n\t\t\tif (q && q !== \"0\"){\n\t\t\t\ttotal *= this._beatsToUnits(parseFloat(q));\n\t\t\t}\n\t\t\tif (s && s !== \"0\"){\n\t\t\t\ttotal *= this._beatsToUnits(parseFloat(s) / 4);\n\t\t\t}\n\t\t\treturn total;\n\t\t}\n\t};\n\n\t///////////////////////////////////////////////////////////////////////////\n\t//\tEXPRESSIONS\n\t///////////////////////////////////////////////////////////////////////////\n\n\t/**\n\t * Transposes the frequency by the given number of semitones.\n\t * @param {Interval} interval\n\t * @return {Tone.Frequency} this\n\t * @example\n\t * Tone.Frequency(\"A4\").transpose(3); //\"C5\"\n\t */\n\tTone.Frequency.prototype.transpose = function(interval){\n\t\tthis._expr = function(expr, interval){\n\t\t\tvar val = expr();\n\t\t\treturn val * this.intervalToFrequencyRatio(interval);\n\t\t}.bind(this, this._expr, interval);\n\t\treturn this;\n\t};\n\n\t/**\n\t * Takes an array of semitone intervals and returns\n\t * an array of frequencies transposed by those intervals.\n\t * @param {Array} intervals\n\t * @return {Tone.Frequency} this\n\t * @example\n\t * Tone.Frequency(\"A4\").harmonize([0, 3, 7]); //[\"A4\", \"C5\", \"E5\"]\n\t */\n\tTone.Frequency.prototype.harmonize = function(intervals){\n\t\tthis._expr = function(expr, intervals){\n\t\t\tvar val = expr();\n\t\t\tvar ret = [];\n\t\t\tfor (var i = 0; i < intervals.length; i++){\n\t\t\t\tret[i] = val * this.intervalToFrequencyRatio(intervals[i]);\n\t\t\t}\n\t\t\treturn ret;\n\t\t}.bind(this, this._expr, intervals);\n\t\treturn this;\n\t};\n\n\t///////////////////////////////////////////////////////////////////////////\n\t//\tUNIT CONVERSIONS\n\t///////////////////////////////////////////////////////////////////////////\n\n\t/**\n\t * Return the value of the frequency as a MIDI note\n\t * @return {MIDI}\n\t * @example\n\t * Tone.Frequency(\"C4\").toMidi(); //60\n\t */\n\tTone.Frequency.prototype.toMidi = function(){\n\t\treturn this.frequencyToMidi(this.valueOf());\n\t};\n\n\t/**\n\t * Return the value of the frequency in Scientific Pitch Notation\n\t * @return {Note}\n\t * @example\n\t * Tone.Frequency(69, \"midi\").toNote(); //\"A4\"\n\t */\n\tTone.Frequency.prototype.toNote = function(){\n\t\tvar freq = this.valueOf();\n\t\tvar log = Math.log(freq / Tone.Frequency.A4) / Math.LN2;\n\t\tvar noteNumber = Math.round(12 * log) + 57;\n\t\tvar octave = Math.floor(noteNumber/12);\n\t\tif(octave < 0){\n\t\t\tnoteNumber += -12 * octave;\n\t\t}\n\t\tvar noteName = scaleIndexToNote[noteNumber % 12];\n\t\treturn noteName + octave.toString();\n\t};\n\n\t/**\n\t * Return the duration of one cycle in seconds.\n\t * @return {Seconds}\n\t */\n\tTone.Frequency.prototype.toSeconds = function(){\n\t\treturn 1 / this.valueOf();\n\t};\n\n\t/**\n\t * Return the value in Hertz\n\t * @return {Frequency}\n\t */\n\tTone.Frequency.prototype.toFrequency = function(){\n\t\treturn this.valueOf();\n\t};\n\n\t/**\n\t * Return the duration of one cycle in ticks\n\t * @return {Ticks}\n\t */\n\tTone.Frequency.prototype.toTicks = function(){\n\t\tvar quarterTime = this._beatsToUnits(1);\n\t\tvar quarters = this.valueOf() / quarterTime;\n\t\treturn Math.floor(quarters * Tone.Transport.PPQ);\n\t};\n\n\t///////////////////////////////////////////////////////////////////////////\n\t//\tUNIT CONVERSIONS HELPERS\n\t///////////////////////////////////////////////////////////////////////////\n\n\t/**\n\t * Returns the value of a frequency in the current units\n\t * @param {Frequency} freq\n\t * @return {Number}\n\t * @private\n\t */\n\tTone.Frequency.prototype._frequencyToUnits = function(freq){\n\t\treturn freq;\n\t};\n\n\t/**\n\t * Returns the value of a tick in the current time units\n\t * @param {Ticks} ticks\n\t * @return {Number}\n\t * @private\n\t */\n\tTone.Frequency.prototype._ticksToUnits = function(ticks){\n\t\treturn 1 / ((ticks * 60) / (Tone.Transport.bpm.value * Tone.Transport.PPQ));\n\t};\n\n\t/**\n\t * Return the value of the beats in the current units\n\t * @param {Number} beats\n\t * @return {Number}\n\t * @private\n\t */\n\tTone.Frequency.prototype._beatsToUnits = function(beats){\n\t\treturn 1 / Tone.TimeBase.prototype._beatsToUnits.call(this, beats);\n\t};\n\n\t/**\n\t * Returns the value of a second in the current units\n\t * @param {Seconds} seconds\n\t * @return {Number}\n\t * @private\n\t */\n\tTone.Frequency.prototype._secondsToUnits = function(seconds){\n\t\treturn 1 / seconds;\n\t};\n\n\t/**\n\t * The default units if none are given.\n\t * @private\n\t */\n\tTone.Frequency.prototype._defaultUnits = \"hz\";\n\n\t///////////////////////////////////////////////////////////////////////////\n\t//\tFREQUENCY CONVERSIONS\n\t///////////////////////////////////////////////////////////////////////////\n\n\t/**\n\t * Note to scale index\n\t * @type {Object}\n\t */\n\tvar noteToScaleIndex = {\n\t\t\"cbb\" : -2, \"cb\" : -1, \"c\" : 0, \"c#\" : 1, \"cx\" : 2, \n\t\t\"dbb\" : 0, \"db\" : 1, \"d\" : 2, \"d#\" : 3, \"dx\" : 4,\n\t\t\"ebb\" : 2, \"eb\" : 3, \"e\" : 4, \"e#\" : 5, \"ex\" : 6, \n\t\t\"fbb\" : 3, \"fb\" : 4, \"f\" : 5, \"f#\" : 6, \"fx\" : 7,\n\t\t\"gbb\" : 5, \"gb\" : 6, \"g\" : 7, \"g#\" : 8, \"gx\" : 9,\n\t\t\"abb\" : 7, \"ab\" : 8, \"a\" : 9, \"a#\" : 10, \"ax\" : 11,\n\t\t\"bbb\" : 9, \"bb\" : 10, \"b\" : 11, \"b#\" : 12, \"bx\" : 13,\n\t};\n\n\t/**\n\t * scale index to note (sharps)\n\t * @type {Array}\n\t */\n\tvar scaleIndexToNote = [\"C\", \"C#\", \"D\", \"D#\", \"E\", \"F\", \"F#\", \"G\", \"G#\", \"A\", \"A#\", \"B\"];\n\n\t/**\n\t * The [concert pitch](https://en.wikipedia.org/wiki/Concert_pitch)\n\t * A4's values in Hertz. \n\t * @type {Frequency}\n\t * @static\n\t */\n\tTone.Frequency.A4 = 440;\n\n\t/**\n\t * Convert a MIDI note to frequency value. \n\t * @param {MIDI} midi The midi number to convert.\n\t * @return {Frequency} the corresponding frequency value\n\t * @example\n\t * tone.midiToFrequency(69); // returns 440\n\t */\n\tTone.Frequency.prototype.midiToFrequency = function(midi){\n\t\treturn Tone.Frequency.A4 * Math.pow(2, (midi - 69) / 12);\n\t};\n\n\t/**\n\t * Convert a frequency value to a MIDI note.\n\t * @param {Frequency} frequency The value to frequency value to convert.\n\t * @returns {MIDI}\n\t * @example\n\t * tone.midiToFrequency(440); // returns 69\n\t */\n\tTone.Frequency.prototype.frequencyToMidi = function(frequency){\n\t\treturn 69 + 12 * Math.log(frequency / Tone.Frequency.A4) / Math.LN2;\n\t};\n\n\treturn Tone.Frequency;\n});","define([\"Tone/core/Tone\", \"Tone/type/Time\"], function (Tone) {\n\n\t/**\n\t * @class Tone.TransportTime is a the time along the Transport's\n\t * timeline. It is similar to Tone.Time, but instead of evaluating\n\t * against the AudioContext's clock, it is evaluated against\n\t * the Transport's position. See [TransportTime wiki](https://github.com/Tonejs/Tone.js/wiki/TransportTime).\n\t * @constructor\n\t * @param {Time} val The time value as a number or string\n\t * @param {String=} units Unit values\n\t * @extends {Tone.Time}\n\t */\n\tTone.TransportTime = function(val, units){\n\t\tif (this instanceof Tone.TransportTime){\n\t\t\t\n\t\t\tTone.Time.call(this, val, units);\n\n\t\t} else {\n\t\t\treturn new Tone.TransportTime(val, units);\n\t\t}\n\t};\n\n\tTone.extend(Tone.TransportTime, Tone.Time);\n\n\t//clone the expressions so that \n\t//we can add more without modifying the original\n\tTone.TransportTime.prototype._unaryExpressions = Object.create(Tone.Time.prototype._unaryExpressions);\n\n\t/**\n\t * Adds an additional unary expression\n\t * which quantizes values to the next subdivision\n\t * @type {Object}\n\t * @private\n\t */\n\tTone.TransportTime.prototype._unaryExpressions.quantize = {\n\t\tregexp : /^@/,\n\t\tmethod : function(rh){\n\t\t\tvar subdivision = this._secondsToTicks(rh());\n\t\t\tvar multiple = Math.ceil(Tone.Transport.ticks / subdivision);\n\t\t\treturn this._ticksToUnits(multiple * subdivision);\n\t\t}\n\t};\n\n\t/**\n\t * Convert seconds into ticks\n\t * @param {Seconds} seconds\n\t * @return {Ticks}\n\t * @private\n\t */\n\tTone.TransportTime.prototype._secondsToTicks = function(seconds){\n\t\tvar quarterTime = this._beatsToUnits(1);\n\t\tvar quarters = seconds / quarterTime;\n\t\treturn Math.round(quarters * Tone.Transport.PPQ);\n\t};\n\n\t/**\n\t * Evaluate the time expression. Returns values in ticks\n\t * @return {Ticks}\n\t */\n\tTone.TransportTime.prototype.valueOf = function(){\n\t\tvar val = this._secondsToTicks(this._expr());\n\t\treturn val + (this._plusNow ? Tone.Transport.ticks : 0);\n\t};\n\n\t/**\n\t * Return the time in ticks.\n\t * @return {Ticks}\n\t */\n\tTone.TransportTime.prototype.toTicks = function(){\n\t\treturn this.valueOf();\n\t};\n\n\t/**\n\t * Return the time in seconds.\n\t * @return {Seconds}\n\t */\n\tTone.TransportTime.prototype.toSeconds = function(){\n\t\tvar val = this._expr();\n\t\treturn val + (this._plusNow ? Tone.Transport.seconds : 0);\n\t};\n\n\t/**\n\t * Return the time as a frequency value\n\t * @return {Frequency} \n\t */\n\tTone.TransportTime.prototype.toFrequency = function(){\n\t\treturn 1/this.toSeconds();\n\t};\n\n\treturn Tone.TransportTime;\n});","'use strict';\n\ndefine(function (require) {\n\n var p5sound = require('master');\n var Add = require('Tone/signal/Add');\n var Mult = require('Tone/signal/Multiply');\n var Scale = require('Tone/signal/Scale');\n var TimelineSignal = require('Tone/signal/TimelineSignal');\n\n /**\n *
Envelopes are pre-defined amplitude distribution over time.\n * Typically, envelopes are used to control the output volume\n * of an object, a series of fades referred to as Attack, Decay,\n * Sustain and Release (\n * ADSR\n * ). Envelopes can also control other Web Audio Parameters—for example, a p5.Envelope can\n * control an Oscillator's frequency like this: osc.freq(env).
\n *
Use setRange to change the attack/release level.\n * Use setADSR to change attackTime, decayTime, sustainPercent and releaseTime.
\n *
Use the play method to play the entire envelope,\n * the ramp method for a pingable trigger,\n * or triggerAttack/\n * triggerRelease to trigger noteOn/noteOff.
\n * var attackLevel = 1.0;\n * var releaseLevel = 0;\n *\n * var attackTime = 0.001;\n * var decayTime = 0.2;\n * var susPercent = 0.2;\n * var releaseTime = 0.5;\n *\n * var env, triOsc;\n *\n * function setup() {\n * var cnv = createCanvas(100, 100);\n *\n * textAlign(CENTER);\n * text('click to play', width/2, height/2);\n *\n * env = new p5.Envelope();\n * env.setADSR(attackTime, decayTime, susPercent, releaseTime);\n * env.setRange(attackLevel, releaseLevel);\n *\n * triOsc = new p5.Oscillator('triangle');\n * triOsc.amp(env);\n * triOsc.start();\n * triOsc.freq(220);\n *\n * cnv.mousePressed(playEnv);\n * }\n *\n * function playEnv() {\n * env.play();\n * }\n *
\n */\n p5.Envelope = function(t1, l1, t2, l2, t3, l3) {\n /**\n * Time until envelope reaches attackLevel\n * @property attackTime\n */\n this.aTime = t1 || 0.1;\n /**\n * Level once attack is complete.\n * @property attackLevel\n */\n this.aLevel = l1 || 1;\n /**\n * Time until envelope reaches decayLevel.\n * @property decayTime\n */\n this.dTime = t2 || 0.5;\n /**\n * Level after decay. The envelope will sustain here until it is released.\n * @property decayLevel\n */\n this.dLevel = l2 || 0;\n /**\n * Duration of the release portion of the envelope.\n * @property releaseTime\n */\n this.rTime = t3 || 0;\n /**\n * Level at the end of the release.\n * @property releaseLevel\n */\n this.rLevel = l3 || 0;\n\n this._rampHighPercentage = 0.98;\n\n this._rampLowPercentage = 0.02;\n\n\n this.output = p5sound.audiocontext.createGain();\n\n this.control = new TimelineSignal();\n\n this._init(); // this makes sure the envelope starts at zero\n\n this.control.connect(this.output); // connect to the output\n\n this.connection = null; // store connection\n\n //array of math operation signal chaining\n this.mathOps = [this.control];\n\n //whether envelope should be linear or exponential curve\n this.isExponential = false;\n\n // oscillator or buffer source to clear on env complete\n // to save resources if/when it is retriggered\n this.sourceToClear = null;\n\n // set to true if attack is set, then false on release\n this.wasTriggered = false;\n\n\n // add to the soundArray so we can dispose of the env later\n p5sound.soundArray.push(this);\n };\n\n // this init function just smooths the starting value to zero and gives a start point for the timeline\n // - it was necessary to remove glitches at the beginning.\n p5.Envelope.prototype._init = function () {\n var now = p5sound.audiocontext.currentTime;\n var t = now;\n this.control.setTargetAtTime(0.00001, t, .001);\n //also, compute the correct time constants\n this._setRampAD(this.aTime, this.dTime);\n };\n\n /**\n * Reset the envelope with a series of time/value pairs.\n *\n * @method set\n * @for p5.Envelope\n * @param {Number} attackTime Time (in seconds) before level\n * reaches attackLevel\n * @param {Number} attackLevel Typically an amplitude between\n * 0.0 and 1.0\n * @param {Number} decayTime Time\n * @param {Number} decayLevel Amplitude (In a standard ADSR envelope,\n * decayLevel = sustainLevel)\n * @param {Number} releaseTime Release Time (in seconds)\n * @param {Number} releaseLevel Amplitude\n * @example\n *
\n * var t1 = 0.1; // attack time in seconds\n * var l1 = 0.7; // attack level 0.0 to 1.0\n * var t2 = 0.3; // decay time in seconds\n * var l2 = 0.1; // decay level 0.0 to 1.0\n * var t3 = 0.2; // sustain time in seconds\n * var l3 = 0.5; // sustain level 0.0 to 1.0\n * // release level defaults to zero\n *\n * var env;\n * var triOsc;\n *\n * function setup() {\n * background(0);\n * noStroke();\n * fill(255);\n * textAlign(CENTER);\n * text('click to play', width/2, height/2);\n *\n * env = new p5.Envelope(t1, l1, t2, l2, t3, l3);\n * triOsc = new p5.Oscillator('triangle');\n * triOsc.amp(env); // give the env control of the triOsc's amp\n * triOsc.start();\n * }\n *\n * // mouseClick triggers envelope if over canvas\n * function mouseClicked() {\n * // is mouse over canvas?\n * if (mouseX > 0 && mouseX < width && mouseY > 0 && mouseY < height) {\n * env.play(triOsc);\n * }\n * }\n *
\n *\n */\n p5.Envelope.prototype.set = function(t1, l1, t2, l2, t3, l3) {\n this.aTime = t1;\n this.aLevel = l1;\n this.dTime = t2 || 0;\n this.dLevel = l2 || 0;\n this.rTime = t3 || 0;\n this.rLevel = l3 || 0;\n\n // set time constants for ramp\n this._setRampAD(t1, t2);\n };\n\n /**\n * Set values like a traditional\n * \n * ADSR envelope\n * .\n *\n * @method setADSR\n * @for p5.Envelope\n * @param {Number} attackTime Time (in seconds before envelope\n * reaches Attack Level\n * @param {Number} [decayTime] Time (in seconds) before envelope\n * reaches Decay/Sustain Level\n * @param {Number} [susRatio] Ratio between attackLevel and releaseLevel, on a scale from 0 to 1,\n * where 1.0 = attackLevel, 0.0 = releaseLevel.\n * The susRatio determines the decayLevel and the level at which the\n * sustain portion of the envelope will sustain.\n * For example, if attackLevel is 0.4, releaseLevel is 0,\n * and susAmt is 0.5, the decayLevel would be 0.2. If attackLevel is\n * increased to 1.0 (using setRange),\n * then decayLevel would increase proportionally, to become 0.5.\n * @param {Number} [releaseTime] Time in seconds from now (defaults to 0)\n * @example\n *
\n * var attackLevel = 1.0;\n * var releaseLevel = 0;\n *\n * var attackTime = 0.001;\n * var decayTime = 0.2;\n * var susPercent = 0.2;\n * var releaseTime = 0.5;\n *\n * var env, triOsc;\n *\n * function setup() {\n * var cnv = createCanvas(100, 100);\n *\n * textAlign(CENTER);\n * text('click to play', width/2, height/2);\n *\n * env = new p5.Envelope();\n * env.setADSR(attackTime, decayTime, susPercent, releaseTime);\n * env.setRange(attackLevel, releaseLevel);\n *\n * triOsc = new p5.Oscillator('triangle');\n * triOsc.amp(env);\n * triOsc.start();\n * triOsc.freq(220);\n *\n * cnv.mousePressed(playEnv);\n * }\n *\n * function playEnv() {\n * env.play();\n * }\n *
\n */\n p5.Envelope.prototype.setADSR = function(aTime, dTime, sPercent, rTime) {\n this.aTime = aTime;\n this.dTime = dTime || 0;\n\n // lerp\n this.sPercent = sPercent || 0;\n this.dLevel = typeof sPercent !== 'undefined' ? sPercent * (this.aLevel - this.rLevel) + this.rLevel : 0;\n\n this.rTime = rTime || 0;\n\n // also set time constants for ramp\n this._setRampAD(aTime, dTime);\n };\n\n /**\n * Set max (attackLevel) and min (releaseLevel) of envelope.\n *\n * @method setRange\n * @for p5.Envelope\n * @param {Number} aLevel attack level (defaults to 1)\n * @param {Number} rLevel release level (defaults to 0)\n * @example\n *
\n * var attackLevel = 1.0;\n * var releaseLevel = 0;\n *\n * var attackTime = 0.001;\n * var decayTime = 0.2;\n * var susPercent = 0.2;\n * var releaseTime = 0.5;\n *\n * var env, triOsc;\n *\n * function setup() {\n * var cnv = createCanvas(100, 100);\n *\n * textAlign(CENTER);\n * text('click to play', width/2, height/2);\n *\n * env = new p5.Envelope();\n * env.setADSR(attackTime, decayTime, susPercent, releaseTime);\n * env.setRange(attackLevel, releaseLevel);\n *\n * triOsc = new p5.Oscillator('triangle');\n * triOsc.amp(env);\n * triOsc.start();\n * triOsc.freq(220);\n *\n * cnv.mousePressed(playEnv);\n * }\n *\n * function playEnv() {\n * env.play();\n * }\n *
\n */\n p5.Envelope.prototype.setRange = function(aLevel, rLevel) {\n this.aLevel = aLevel || 1;\n this.rLevel = rLevel || 0;\n\n // not sure if this belongs here:\n\n // {Number} [dLevel] decay/sustain level (optional)\n // if (typeof(dLevel) !== 'undefined') {\n // this.dLevel = dLevel\n // } else if (this.sPercent) {\n // this.dLevel = this.sPercent ? this.sPercent * (this.aLevel - this.rLevel) + this.rLevel : 0;\n // }\n };\n\n // private (undocumented) method called when ADSR is set to set time constants for ramp\n //\n // Set the \n // time constants for simple exponential ramps.\n // The larger the time constant value, the slower the\n // transition will be.\n //\n // method _setRampAD\n // param {Number} attackTimeConstant attack time constant\n // param {Number} decayTimeConstant decay time constant\n //\n p5.Envelope.prototype._setRampAD = function(t1, t2) {\n this._rampAttackTime = this.checkExpInput(t1);\n this._rampDecayTime = this.checkExpInput(t2);\n\n var TCDenominator = 1.0;\n /// Aatish Bhatia's calculation for time constant for rise(to adjust 1/1-e calculation to any percentage)\n TCDenominator = Math.log(1.0 / this.checkExpInput(1.0 - this._rampHighPercentage));\n this._rampAttackTC = t1 / this.checkExpInput(TCDenominator);\n TCDenominator = Math.log(1.0 / this._rampLowPercentage);\n this._rampDecayTC = t2 / this.checkExpInput(TCDenominator);\n };\n\n // private method\n p5.Envelope.prototype.setRampPercentages = function(p1, p2) {\n //set the percentages that the simple exponential ramps go to\n this._rampHighPercentage = this.checkExpInput(p1);\n this._rampLowPercentage = this.checkExpInput(p2);\n var TCDenominator = 1.0;\n //now re-compute the time constants based on those percentages\n /// Aatish Bhatia's calculation for time constant for rise(to adjust 1/1-e calculation to any percentage)\n TCDenominator = Math.log(1.0 / this.checkExpInput(1.0 - this._rampHighPercentage));\n this._rampAttackTC = this._rampAttackTime / this.checkExpInput(TCDenominator);\n TCDenominator = Math.log(1.0 / this._rampLowPercentage);\n this._rampDecayTC = this._rampDecayTime / this.checkExpInput(TCDenominator);\n };\n\n\n /**\n * Assign a parameter to be controlled by this envelope.\n * If a p5.Sound object is given, then the p5.Envelope will control its\n * output gain. If multiple inputs are provided, the env will\n * control all of them.\n *\n * @method setInput\n * @for p5.Envelope\n * @param {Object} [...inputs] A p5.sound object or\n * Web Audio Param.\n */\n p5.Envelope.prototype.setInput = function() {\n for (var i = 0; i\n * Web Audio Audio Param.\n *\n * @method play\n * @for p5.Envelope\n * @param {Object} unit A p5.sound object or\n * Web Audio Param.\n * @param {Number} [startTime] time from now (in seconds) at which to play\n * @param {Number} [sustainTime] time to sustain before releasing the envelope\n * @example\n *
\n * var attackLevel = 1.0;\n * var releaseLevel = 0;\n *\n * var attackTime = 0.001;\n * var decayTime = 0.2;\n * var susPercent = 0.2;\n * var releaseTime = 0.5;\n *\n * var env, triOsc;\n *\n * function setup() {\n * var cnv = createCanvas(100, 100);\n *\n * textAlign(CENTER);\n * text('click to play', width/2, height/2);\n *\n * env = new p5.Envelope();\n * env.setADSR(attackTime, decayTime, susPercent, releaseTime);\n * env.setRange(attackLevel, releaseLevel);\n *\n * triOsc = new p5.Oscillator('triangle');\n * triOsc.amp(env);\n * triOsc.start();\n * triOsc.freq(220);\n *\n * cnv.mousePressed(playEnv);\n * }\n *\n * function playEnv() {\n * // trigger env on triOsc, 0 seconds from now\n * // After decay, sustain for 0.2 seconds before release\n * env.play(triOsc, 0, 0.2);\n * }\n *
\n */\n p5.Envelope.prototype.play = function(unit, secondsFromNow, susTime) {\n var tFromNow = secondsFromNow || 0;\n var susTime = susTime || 0;\n\n if (unit) {\n if (this.connection !== unit) {\n this.connect(unit);\n }\n }\n\n this.triggerAttack(unit, tFromNow);\n\n this.triggerRelease(unit, tFromNow + this.aTime + this.dTime + susTime);\n\n };\n\n /**\n * Trigger the Attack, and Decay portion of the Envelope.\n * Similar to holding down a key on a piano, but it will\n * hold the sustain level until you let go. Input can be\n * any p5.sound object, or a \n * Web Audio Param.\n *\n * @method triggerAttack\n * @for p5.Envelope\n * @param {Object} unit p5.sound Object or Web Audio Param\n * @param {Number} secondsFromNow time from now (in seconds)\n * @example\n *
\n *\n * var attackLevel = 1.0;\n * var releaseLevel = 0;\n *\n * var attackTime = 0.001;\n * var decayTime = 0.3;\n * var susPercent = 0.4;\n * var releaseTime = 0.5;\n *\n * var env, triOsc;\n *\n * function setup() {\n * var cnv = createCanvas(100, 100);\n * background(200);\n * textAlign(CENTER);\n * text('click to play', width/2, height/2);\n *\n * env = new p5.Envelope();\n * env.setADSR(attackTime, decayTime, susPercent, releaseTime);\n * env.setRange(attackLevel, releaseLevel);\n *\n * triOsc = new p5.Oscillator('triangle');\n * triOsc.amp(env);\n * triOsc.start();\n * triOsc.freq(220);\n *\n * cnv.mousePressed(envAttack);\n * }\n *\n * function envAttack() {\n * console.log('trigger attack');\n * env.triggerAttack();\n *\n * background(0,255,0);\n * text('attack!', width/2, height/2);\n * }\n *\n * function mouseReleased() {\n * env.triggerRelease();\n *\n * background(200);\n * text('click to play', width/2, height/2);\n * }\n *
\n */\n p5.Envelope.prototype.triggerAttack = function(unit, secondsFromNow) {\n var now = p5sound.audiocontext.currentTime;\n var tFromNow = secondsFromNow || 0;\n var t = now + tFromNow;\n this.lastAttack = t;\n this.wasTriggered = true;\n\n if (unit) {\n if (this.connection !== unit) {\n this.connect(unit);\n }\n }\n\n // get and set value (with linear ramp) to anchor automation\n var valToSet = this.control.getValueAtTime(t);\n\n if (this.isExponential === true)\n {\n this.control.exponentialRampToValueAtTime(this.checkExpInput(valToSet), t);\n }\n else\n {\n this.control.linearRampToValueAtTime(valToSet, t);\n }\n\n // after each ramp completes, cancel scheduled values\n // (so they can be overridden in case env has been re-triggered)\n // then, set current value (with linearRamp to avoid click)\n // then, schedule the next automation...\n\n // attack\n t += this.aTime;\n if (this.isExponential === true)\n {\n this.control.exponentialRampToValueAtTime(this.checkExpInput(this.aLevel), t);\n valToSet = this.checkExpInput(this.control.getValueAtTime(t));\n this.control.cancelScheduledValues(t);\n this.control.exponentialRampToValueAtTime(valToSet, t);\n }\n else\n {\n this.control.linearRampToValueAtTime(this.aLevel, t);\n valToSet = this.control.getValueAtTime(t);\n this.control.cancelScheduledValues(t);\n this.control.linearRampToValueAtTime(valToSet, t);\n\n }\n\n // decay to decay level (if using ADSR, then decay level == sustain level)\n t += this.dTime;\n if (this.isExponential === true)\n {\n this.control.exponentialRampToValueAtTime(this.checkExpInput(this.dLevel), t);\n valToSet = this.checkExpInput(this.control.getValueAtTime(t));\n this.control.cancelScheduledValues(t);\n this.control.exponentialRampToValueAtTime(valToSet, t);\n }\n else\n {\n this.control.linearRampToValueAtTime(this.dLevel, t);\n valToSet = this.control.getValueAtTime(t);\n this.control.cancelScheduledValues(t);\n this.control.linearRampToValueAtTime(valToSet, t);\n }\n };\n\n /**\n * Trigger the Release of the Envelope. This is similar to releasing\n * the key on a piano and letting the sound fade according to the\n * release level and release time.\n *\n * @method triggerRelease\n * @for p5.Envelope\n * @param {Object} unit p5.sound Object or Web Audio Param\n * @param {Number} secondsFromNow time to trigger the release\n * @example\n *
\n *\n * var attackLevel = 1.0;\n * var releaseLevel = 0;\n *\n * var attackTime = 0.001;\n * var decayTime = 0.3;\n * var susPercent = 0.4;\n * var releaseTime = 0.5;\n *\n * var env, triOsc;\n *\n * function setup() {\n * var cnv = createCanvas(100, 100);\n * background(200);\n * textAlign(CENTER);\n * text('click to play', width/2, height/2);\n *\n * env = new p5.Envelope();\n * env.setADSR(attackTime, decayTime, susPercent, releaseTime);\n * env.setRange(attackLevel, releaseLevel);\n *\n * triOsc = new p5.Oscillator('triangle');\n * triOsc.amp(env);\n * triOsc.start();\n * triOsc.freq(220);\n *\n * cnv.mousePressed(envAttack);\n * }\n *\n * function envAttack() {\n * console.log('trigger attack');\n * env.triggerAttack();\n *\n * background(0,255,0);\n * text('attack!', width/2, height/2);\n * }\n *\n * function mouseReleased() {\n * env.triggerRelease();\n *\n * background(200);\n * text('click to play', width/2, height/2);\n * }\n *
\n */\n p5.Envelope.prototype.triggerRelease = function(unit, secondsFromNow) {\n\n // only trigger a release if an attack was triggered\n if (!this.wasTriggered) {\n // this currently causes a bit of trouble:\n // if a later release has been scheduled (via the play function)\n // a new earlier release won't interrupt it, because\n // this.wasTriggered has already been set to false.\n // If we want new earlier releases to override, then we need to\n // keep track of the last release time, and if the new release time is\n // earlier, then use it.\n return;\n }\n\n var now = p5sound.audiocontext.currentTime;\n var tFromNow = secondsFromNow || 0;\n var t = now + tFromNow;\n\n if (unit) {\n if (this.connection !== unit) {\n this.connect(unit);\n }\n }\n\n // get and set value (with linear or exponential ramp) to anchor automation\n var valToSet = this.control.getValueAtTime(t);\n if (this.isExponential === true)\n {\n this.control.exponentialRampToValueAtTime(this.checkExpInput(valToSet), t);\n }\n else\n {\n this.control.linearRampToValueAtTime(valToSet, t);\n }\n\n // release\n t += this.rTime;\n\n if (this.isExponential === true)\n {\n this.control.exponentialRampToValueAtTime(this.checkExpInput(this.rLevel), t);\n valToSet = this.checkExpInput(this.control.getValueAtTime(t));\n this.control.cancelScheduledValues(t);\n this.control.exponentialRampToValueAtTime(valToSet, t);\n }\n else\n {\n this.control.linearRampToValueAtTime(this.rLevel, t);\n valToSet = this.control.getValueAtTime(t);\n this.control.cancelScheduledValues(t);\n this.control.linearRampToValueAtTime(valToSet, t);\n }\n\n this.wasTriggered = false;\n };\n\n /**\n * Exponentially ramp to a value using the first two\n * values from setADSR(attackTime, decayTime)\n * as \n * time constants for simple exponential ramps.\n * If the value is higher than current value, it uses attackTime,\n * while a decrease uses decayTime.\n *\n * @method ramp\n * @for p5.Envelope\n * @param {Object} unit p5.sound Object or Web Audio Param\n * @param {Number} secondsFromNow When to trigger the ramp\n * @param {Number} v Target value\n * @param {Number} [v2] Second target value (optional)\n * @example\n *
\n * var env, osc, amp, cnv;\n *\n * var attackTime = 0.001;\n * var decayTime = 0.2;\n * var attackLevel = 1;\n * var decayLevel = 0;\n *\n * function setup() {\n * cnv = createCanvas(100, 100);\n * fill(0,255,0);\n * noStroke();\n *\n * env = new p5.Envelope();\n * env.setADSR(attackTime, decayTime);\n *\n * osc = new p5.Oscillator();\n * osc.amp(env);\n * osc.start();\n *\n * amp = new p5.Amplitude();\n *\n * cnv.mousePressed(triggerRamp);\n * }\n *\n * function triggerRamp() {\n * env.ramp(osc, 0, attackLevel, decayLevel);\n * }\n *\n * function draw() {\n * background(20,20,20);\n * text('click me', 10, 20);\n * var h = map(amp.getLevel(), 0, 0.4, 0, height);;\n *\n * rect(0, height, width, -h);\n * }\n *
\n */\n p5.Envelope.prototype.ramp = function(unit, secondsFromNow, v1, v2) {\n\n var now = p5sound.audiocontext.currentTime;\n var tFromNow = secondsFromNow || 0;\n var t = now + tFromNow;\n var destination1 = this.checkExpInput(v1);\n var destination2 = typeof v2 !== 'undefined' ? this.checkExpInput(v2) : undefined;\n\n // connect env to unit if not already connected\n if (unit) {\n if (this.connection !== unit) {\n this.connect(unit);\n }\n }\n\n //get current value\n var currentVal = this.checkExpInput(this.control.getValueAtTime(t));\n // this.control.cancelScheduledValues(t);\n\n //if it's going up\n if (destination1 > currentVal) {\n this.control.setTargetAtTime(destination1, t, this._rampAttackTC);\n t += this._rampAttackTime;\n }\n\n //if it's going down\n else if (destination1 < currentVal) {\n this.control.setTargetAtTime(destination1, t, this._rampDecayTC);\n t += this._rampDecayTime;\n }\n\n // Now the second part of envelope begins\n if (destination2 === undefined) return;\n\n //if it's going up\n if (destination2 > destination1) {\n this.control.setTargetAtTime(destination2, t, this._rampAttackTC);\n }\n\n //if it's going down\n else if (destination2 < destination1) {\n this.control.setTargetAtTime(destination2, t, this._rampDecayTC);\n }\n };\n\n\n p5.Envelope.prototype.connect = function(unit) {\n this.connection = unit;\n\n // assume we're talking about output gain\n // unless given a different audio param\n if (unit instanceof p5.Oscillator ||\n unit instanceof p5.SoundFile ||\n unit instanceof p5.AudioIn ||\n unit instanceof p5.Reverb ||\n unit instanceof p5.Noise ||\n unit instanceof p5.Filter ||\n unit instanceof p5.Delay\n ) {\n unit = unit.output.gain;\n }\n if (unit instanceof AudioParam) {\n //set the initial value\n unit.setValueAtTime(0, p5sound.audiocontext.currentTime);\n }\n if (unit instanceof p5.Signal) {\n unit.setValue(0);\n }\n this.output.connect(unit);\n };\n\n p5.Envelope.prototype.disconnect = function() {\n if (this.output) {\n this.output.disconnect();\n }\n };\n\n\n // Signal Math\n\n /**\n * Add a value to the p5.Oscillator's output amplitude,\n * and return the oscillator. Calling this method\n * again will override the initial add() with new values.\n *\n * @method add\n * @for p5.Envelope\n * @param {Number} number Constant number to add\n * @return {p5.Envelope} Envelope Returns this envelope\n * with scaled output\n */\n p5.Envelope.prototype.add = function(num) {\n var add = new Add(num);\n var thisChain = this.mathOps.length;\n var nextChain = this.output;\n return p5.prototype._mathChain(this, add, thisChain, nextChain, Add);\n };\n\n /**\n * Multiply the p5.Envelope's output amplitude\n * by a fixed value. Calling this method\n * again will override the initial mult() with new values.\n *\n * @method mult\n * @for p5.Envelope\n * @param {Number} number Constant number to multiply\n * @return {p5.Envelope} Envelope Returns this envelope\n * with scaled output\n */\n p5.Envelope.prototype.mult = function(num) {\n var mult = new Mult(num);\n var thisChain = this.mathOps.length;\n var nextChain = this.output;\n return p5.prototype._mathChain(this, mult, thisChain, nextChain, Mult);\n };\n\n /**\n * Scale this envelope's amplitude values to a given\n * range, and return the envelope. Calling this method\n * again will override the initial scale() with new values.\n *\n * @method scale\n * @for p5.Envelope\n * @param {Number} inMin input range minumum\n * @param {Number} inMax input range maximum\n * @param {Number} outMin input range minumum\n * @param {Number} outMax input range maximum\n * @return {p5.Envelope} Envelope Returns this envelope\n * with scaled output\n */\n p5.Envelope.prototype.scale = function(inMin, inMax, outMin, outMax) {\n var scale = new Scale(inMin, inMax, outMin, outMax);\n var thisChain = this.mathOps.length;\n var nextChain = this.output;\n return p5.prototype._mathChain(this, scale, thisChain, nextChain, Scale);\n };\n\n\n // get rid of the oscillator\n p5.Envelope.prototype.dispose = function() {\n // remove reference from soundArray\n var index = p5sound.soundArray.indexOf(this);\n p5sound.soundArray.splice(index, 1);\n\n this.disconnect();\n if (this.control) {\n this.control.dispose();\n this.control = null;\n }\n for (var i = 1; i < this.mathOps.length; i++) {\n this.mathOps[i].dispose();\n }\n };\n\n // Different name for backwards compatibility, replicates p5.Envelope class\n p5.Env = function(t1, l1, t2, l2, t3, l3) {\n console.warn('WARNING: p5.Env is now deprecated and may be removed in future versions. ' +\n 'Please use the new p5.Envelope instead.');\n p5.Envelope.call(this, t1, l1, t2, l2, t3, l3);\n };\n p5.Env.prototype = Object.create(p5.Envelope.prototype);\n\n});\n","'use strict';\n\ndefine(function (require) {\n\n var p5sound = require('master');\n require('oscillator');\n\n /**\n * Creates a Pulse object, an oscillator that implements\n * Pulse Width Modulation.\n * The pulse is created with two oscillators.\n * Accepts a parameter for frequency, and to set the\n * width between the pulses. See \n * p5.Oscillator for a full list of methods.\n *\n * @class p5.Pulse\n * @extends p5.Oscillator\n * @constructor\n * @param {Number} [freq] Frequency in oscillations per second (Hz)\n * @param {Number} [w] Width between the pulses (0 to 1.0,\n * defaults to 0)\n * @example\n *
Note: This uses the getUserMedia/\n * Stream API, which is not supported by certain browsers. Access in Chrome browser\n * is limited to localhost and https, but access over http may be limited.
\n *\n * @class p5.AudioIn\n * @constructor\n * @param {Function} [errorCallback] A function to call if there is an error\n * accessing the AudioIn. For example,\n * Safari and iOS devices do not\n * currently allow microphone access.\n * @example\n *
\n * var mic;\n * function setup(){\n * mic = new p5.AudioIn()\n * mic.start();\n * }\n * function draw(){\n * background(0);\n * micLevel = mic.getLevel();\n * ellipse(width/2, constrain(height-micLevel*height*5, 0, height), 10, 10);\n * }\n *
\n */\n p5.AudioIn = function(errorCallback) {\n // set up audio input\n /**\n * @property {GainNode} input\n */\n this.input = p5sound.audiocontext.createGain();\n /**\n * @property {GainNode} output\n */\n this.output = p5sound.audiocontext.createGain();\n\n /**\n * @property {MediaStream|null} stream\n */\n this.stream = null;\n /**\n * @property {MediaStreamAudioSourceNode|null} mediaStream\n */\n this.mediaStream = null;\n /**\n * @property {Number|null} currentSource\n */\n this.currentSource = null;\n\n /**\n * Client must allow browser to access their microphone / audioin source.\n * Default: false. Will become true when the client enables acces.\n *\n * @property {Boolean} enabled\n */\n this.enabled = false;\n\n /**\n * Input amplitude, connect to it by default but not to master out\n *\n * @property {p5.Amplitude} amplitude\n */\n this.amplitude = new p5.Amplitude();\n this.output.connect(this.amplitude.input);\n\n if (!window.MediaStreamTrack || !window.navigator.mediaDevices || !window.navigator.mediaDevices.getUserMedia) {\n errorCallback ? errorCallback() : window.alert('This browser does not support MediaStreamTrack and mediaDevices');\n }\n\n // add to soundArray so we can dispose on close\n p5sound.soundArray.push(this);\n };\n\n /**\n * Start processing audio input. This enables the use of other\n * AudioIn methods like getLevel(). Note that by default, AudioIn\n * is not connected to p5.sound's output. So you won't hear\n * anything unless you use the connect() method. \n *\n * Certain browsers limit access to the user's microphone. For example,\n * Chrome only allows access from localhost and over https. For this reason,\n * you may want to include an errorCallback—a function that is called in case\n * the browser won't provide mic access.\n *\n * @method start\n * @for p5.AudioIn\n * @param {Function} [successCallback] Name of a function to call on\n * success.\n * @param {Function} [errorCallback] Name of a function to call if\n * there was an error. For example,\n * some browsers do not support\n * getUserMedia.\n */\n p5.AudioIn.prototype.start = function(successCallback, errorCallback) {\n var self = this;\n\n if (this.stream) {\n this.stop();\n }\n\n // set the audio source\n var audioSource = p5sound.inputSources[self.currentSource];\n var constraints = {\n audio: {\n sampleRate: p5sound.audiocontext.sampleRate,\n echoCancellation: false\n }\n };\n\n // if developers determine which source to use\n if (p5sound.inputSources[this.currentSource]) {\n constraints.audio.deviceId = audioSource.deviceId;\n }\n\n window.navigator.mediaDevices.getUserMedia( constraints )\n .then( function(stream) {\n self.stream = stream;\n self.enabled = true;\n // Wrap a MediaStreamSourceNode around the live input\n self.mediaStream = p5sound.audiocontext.createMediaStreamSource(stream);\n self.mediaStream.connect(self.output);\n // only send to the Amplitude reader, so we can see it but not hear it.\n self.amplitude.setInput(self.output);\n if (successCallback) successCallback();\n })\n .catch( function(err) {\n if (errorCallback) errorCallback(err);\n else console.error(err);\n });\n };\n\n /**\n * Turn the AudioIn off. If the AudioIn is stopped, it cannot getLevel().\n * If re-starting, the user may be prompted for permission access.\n *\n * @method stop\n * @for p5.AudioIn\n */\n p5.AudioIn.prototype.stop = function() {\n if (this.stream) {\n this.stream.getTracks().forEach(function(track) {\n track.stop();\n });\n\n this.mediaStream.disconnect();\n\n delete this.mediaStream;\n delete this.stream;\n }\n };\n\n /**\n * Connect to an audio unit. If no parameter is provided, will\n * connect to the master output (i.e. your speakers). \n *\n * @method connect\n * @for p5.AudioIn\n * @param {Object} [unit] An object that accepts audio input,\n * such as an FFT\n */\n p5.AudioIn.prototype.connect = function(unit) {\n if (unit) {\n if (unit.hasOwnProperty('input')) {\n this.output.connect(unit.input);\n }\n else if (unit.hasOwnProperty('analyser')) {\n this.output.connect(unit.analyser);\n }\n else {\n this.output.connect(unit);\n }\n }\n else {\n this.output.connect(p5sound.input);\n }\n };\n\n /**\n * Disconnect the AudioIn from all audio units. For example, if\n * connect() had been called, disconnect() will stop sending\n * signal to your speakers. \n *\n * @method disconnect\n * @for p5.AudioIn\n */\n p5.AudioIn.prototype.disconnect = function() {\n if (this.output) {\n this.output.disconnect();\n // stay connected to amplitude even if not outputting to p5\n this.output.connect(this.amplitude.input);\n }\n };\n\n /**\n * Read the Amplitude (volume level) of an AudioIn. The AudioIn\n * class contains its own instance of the Amplitude class to help\n * make it easy to get a microphone's volume level. Accepts an\n * optional smoothing value (0.0 < 1.0). NOTE: AudioIn must\n * .start() before using .getLevel(). \n *\n * @method getLevel\n * @for p5.AudioIn\n * @param {Number} [smoothing] Smoothing is 0.0 by default.\n * Smooths values based on previous values.\n * @return {Number} Volume level (between 0.0 and 1.0)\n */\n p5.AudioIn.prototype.getLevel = function(smoothing) {\n if (smoothing) {\n this.amplitude.smoothing = smoothing;\n }\n return this.amplitude.getLevel();\n };\n\n /**\n * Set amplitude (volume) of a mic input between 0 and 1.0. \n *\n * @method amp\n * @for p5.AudioIn\n * @param {Number} vol between 0 and 1.0\n * @param {Number} [time] ramp time (optional)\n */\n p5.AudioIn.prototype.amp = function(vol, t) {\n if (t) {\n var rampTime = t || 0;\n var currentVol = this.output.gain.value;\n this.output.gain.cancelScheduledValues(p5sound.audiocontext.currentTime);\n this.output.gain.setValueAtTime(currentVol, p5sound.audiocontext.currentTime);\n this.output.gain.linearRampToValueAtTime(vol, rampTime + p5sound.audiocontext.currentTime);\n } else {\n this.output.gain.cancelScheduledValues(p5sound.audiocontext.currentTime);\n this.output.gain.setValueAtTime(vol, p5sound.audiocontext.currentTime);\n }\n };\n\n /**\n * Returns a list of available input sources. This is a wrapper\n * for and it returns a Promise.\n *\n * @method getSources\n * @for p5.AudioIn\n * @param {Function} [successCallback] This callback function handles the sources when they\n * have been enumerated. The callback function\n * receives the deviceList array as its only argument\n * @param {Function} [errorCallback] This optional callback receives the error\n * message as its argument.\n * @returns {Promise} Returns a Promise that can be used in place of the callbacks, similar\n * to the enumerateDevices() method\n * @example\n *
\n */\n p5.AudioIn.prototype.getSources = function (onSuccess, onError) {\n return new Promise( function(resolve, reject) {\n window.navigator.mediaDevices.enumerateDevices()\n .then( function(devices) {\n p5sound.inputSources = devices.filter(function(device) {\n return device.kind === 'audioinput';\n });\n resolve(p5sound.inputSources);\n if (onSuccess) {\n onSuccess(p5sound.inputSources);\n }\n })\n .catch( function(error) {\n reject(error);\n if (onError) {\n onError(error);\n } else {\n console.error('This browser does not support MediaStreamTrack.getSources()');\n }\n });\n });\n };\n\n /**\n * Set the input source. Accepts a number representing a\n * position in the array returned by getSources().\n * This is only available in browsers that support\n * navigator.mediaDevices.enumerateDevices(). \n *\n * @method setSource\n * @for p5.AudioIn\n * @param {number} num position of input source in the array\n */\n p5.AudioIn.prototype.setSource = function(num) {\n if (p5sound.inputSources.length > 0 && num < p5sound.inputSources.length) {\n // set the current source\n this.currentSource = num;\n console.log('set source to ', p5sound.inputSources[this.currentSource]);\n } else {\n console.log('unable to set input source');\n }\n\n // restart stream if currently active\n if (this.stream && this.stream.active) {\n this.start();\n }\n };\n\n // private method\n p5.AudioIn.prototype.dispose = function() {\n // remove reference from soundArray\n var index = p5sound.soundArray.indexOf(this);\n p5sound.soundArray.splice(index, 1);\n\n this.stop();\n\n if (this.output) {\n this.output.disconnect();\n }\n if (this.amplitude) {\n this.amplitude.disconnect();\n }\n delete this.amplitude;\n delete this.output;\n };\n\n});\n","define([\"Tone/core/Tone\", \"Tone/signal/Signal\", \"Tone/signal/Expr\", \n\t\"Tone/signal/EqualPowerGain\", \"Tone/core/Gain\"], function(Tone){\n\n\t\"use strict\";\n\n\t/**\n\t * @class Tone.Crossfade provides equal power fading between two inputs. \n\t * More on crossfading technique [here](https://en.wikipedia.org/wiki/Fade_(audio_engineering)#Crossfading).\n\t *\n\t * @constructor\n\t * @extends {Tone}\n\t * @param {NormalRange} [initialFade=0.5]\n\t * @example\n\t * var crossFade = new Tone.CrossFade(0.5);\n\t * //connect effect A to crossfade from\n\t * //effect output 0 to crossfade input 0\n\t * effectA.connect(crossFade, 0, 0);\n\t * //connect effect B to crossfade from\n\t * //effect output 0 to crossfade input 1\n\t * effectB.connect(crossFade, 0, 1);\n\t * crossFade.fade.value = 0;\n\t * // ^ only effectA is output\n\t * crossFade.fade.value = 1;\n\t * // ^ only effectB is output\n\t * crossFade.fade.value = 0.5;\n\t * // ^ the two signals are mixed equally. \n\t */\t\t\n\tTone.CrossFade = function(initialFade){\n\n\t\tthis.createInsOuts(2, 1);\n\n\t\t/**\n\t\t * Alias for input[0]. \n\t\t * @type {Tone.Gain}\n\t\t */\n\t\tthis.a = this.input[0] = new Tone.Gain();\n\n\t\t/**\n\t\t * Alias for input[1]. \n\t\t * @type {Tone.Gain}\n\t\t */\n\t\tthis.b = this.input[1] = new Tone.Gain();\n\n\t\t/**\n\t\t * \tThe mix between the two inputs. A fade value of 0\n\t\t * \twill output 100% input[0] and \n\t\t * \ta value of 1 will output 100% input[1]. \n\t\t * @type {NormalRange}\n\t\t * @signal\n\t\t */\n\t\tthis.fade = new Tone.Signal(this.defaultArg(initialFade, 0.5), Tone.Type.NormalRange);\n\n\t\t/**\n\t\t * equal power gain cross fade\n\t\t * @private\n\t\t * @type {Tone.EqualPowerGain}\n\t\t */\n\t\tthis._equalPowerA = new Tone.EqualPowerGain();\n\n\t\t/**\n\t\t * equal power gain cross fade\n\t\t * @private\n\t\t * @type {Tone.EqualPowerGain}\n\t\t */\n\t\tthis._equalPowerB = new Tone.EqualPowerGain();\n\t\t\n\t\t/**\n\t\t * invert the incoming signal\n\t\t * @private\n\t\t * @type {Tone}\n\t\t */\n\t\tthis._invert = new Tone.Expr(\"1 - $0\");\n\n\t\t//connections\n\t\tthis.a.connect(this.output);\n\t\tthis.b.connect(this.output);\n\t\tthis.fade.chain(this._equalPowerB, this.b.gain);\n\t\tthis.fade.chain(this._invert, this._equalPowerA, this.a.gain);\n\t\tthis._readOnly(\"fade\");\n\t};\n\n\tTone.extend(Tone.CrossFade);\n\n\t/**\n\t * clean up\n\t * @returns {Tone.CrossFade} this\n\t */\n\tTone.CrossFade.prototype.dispose = function(){\n\t\tTone.prototype.dispose.call(this);\n\t\tthis._writable(\"fade\");\n\t\tthis._equalPowerA.dispose();\n\t\tthis._equalPowerA = null;\n\t\tthis._equalPowerB.dispose();\n\t\tthis._equalPowerB = null;\n\t\tthis.fade.dispose();\n\t\tthis.fade = null;\n\t\tthis._invert.dispose();\n\t\tthis._invert = null;\n\t\tthis.a.dispose();\n\t\tthis.a = null;\n\t\tthis.b.dispose();\n\t\tthis.b = null;\n\t\treturn this;\n\t};\n\n\treturn Tone.CrossFade;\n});\n","define([\"Tone/core/Tone\", \"Tone/signal/Add\", \"Tone/signal/Subtract\", \"Tone/signal/Multiply\", \n\t\"Tone/signal/GreaterThan\", \"Tone/signal/GreaterThanZero\", \"Tone/signal/Abs\", \"Tone/signal/Negate\", \n\t\"Tone/signal/Modulo\", \"Tone/signal/Pow\", \"Tone/signal/AudioToGain\"], \n\tfunction(Tone){\n\n\t\"use strict\";\n\n\t/**\n\t * @class Evaluate an expression at audio rate.
\n\t * Parsing code modified from https://code.google.com/p/tapdigit/\n\t * Copyright 2011 2012 Ariya Hidayat, New BSD License\n\t *\n\t * @extends {Tone.SignalBase}\n\t * @constructor\n\t * @param {string} expr the expression to generate\n\t * @example\n\t * //adds the signals from input[0] and input[1].\n\t * var expr = new Tone.Expr(\"$0 + $1\");\n\t */\n\tTone.Expr = function(){\n\n\t\tvar expr = this._replacements(Array.prototype.slice.call(arguments));\n\t\tvar inputCount = this._parseInputs(expr);\n\n\t\t/**\n\t\t * hold onto all of the nodes for disposal\n\t\t * @type {Array}\n\t\t * @private\n\t\t */\n\t\tthis._nodes = [];\n\n\t\t/**\n\t\t * The inputs. The length is determined by the expression. \n\t\t * @type {Array}\n\t\t */\n\t\tthis.input = new Array(inputCount);\n\n\t\t//create a gain for each input\n\t\tfor (var i = 0; i < inputCount; i++){\n\t\t\tthis.input[i] = this.context.createGain();\n\t\t}\n\n\t\t//parse the syntax tree\n\t\tvar tree = this._parseTree(expr);\n\t\t//evaluate the results\n\t\tvar result;\n\t\ttry {\n\t\t\tresult = this._eval(tree);\n\t\t} catch (e){\n\t\t\tthis._disposeNodes();\n\t\t\tthrow new Error(\"Tone.Expr: Could evaluate expression: \"+expr);\n\t\t}\n\n\t\t/**\n\t\t * The output node is the result of the expression\n\t\t * @type {Tone}\n\t\t */\n\t\tthis.output = result;\n\t};\n\n\tTone.extend(Tone.Expr, Tone.SignalBase);\n\n\t//some helpers to cut down the amount of code\n\tfunction applyBinary(Constructor, args, self){\n\t\tvar op = new Constructor();\n\t\tself._eval(args[0]).connect(op, 0, 0);\n\t\tself._eval(args[1]).connect(op, 0, 1);\n\t\treturn op;\n\t}\n\tfunction applyUnary(Constructor, args, self){\n\t\tvar op = new Constructor();\n\t\tself._eval(args[0]).connect(op, 0, 0);\n\t\treturn op;\n\t}\n\tfunction getNumber(arg){\n\t\treturn arg ? parseFloat(arg) : undefined;\n\t}\n\tfunction literalNumber(arg){\n\t\treturn arg && arg.args ? parseFloat(arg.args) : undefined;\n\t}\n\n\t/*\n\t * the Expressions that Tone.Expr can parse.\n\t *\n\t * each expression belongs to a group and contains a regexp \n\t * for selecting the operator as well as that operators method\n\t * \n\t * @type {Object}\n\t * @private\n\t */\n\tTone.Expr._Expressions = {\n\t\t//values\n\t\t\"value\" : {\n\t\t\t\"signal\" : {\n\t\t\t\tregexp : /^\\d+\\.\\d+|^\\d+/,\n\t\t\t\tmethod : function(arg){\n\t\t\t\t\tvar sig = new Tone.Signal(getNumber(arg));\n\t\t\t\t\treturn sig;\n\t\t\t\t}\n\t\t\t},\n\t\t\t\"input\" : {\n\t\t\t\tregexp : /^\\$\\d/,\n\t\t\t\tmethod : function(arg, self){\n\t\t\t\t\treturn self.input[getNumber(arg.substr(1))];\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\t\t//syntactic glue\n\t\t\"glue\" : {\n\t\t\t\"(\" : {\n\t\t\t\tregexp : /^\\(/,\n\t\t\t},\n\t\t\t\")\" : {\n\t\t\t\tregexp : /^\\)/,\n\t\t\t},\n\t\t\t\",\" : {\n\t\t\t\tregexp : /^,/,\n\t\t\t}\n\t\t},\n\t\t//functions\n\t\t\"func\" : {\n\t\t\t\"abs\" : {\n\t\t\t\tregexp : /^abs/,\n\t\t\t\tmethod : applyUnary.bind(this, Tone.Abs)\n\t\t\t},\n\t\t\t\"mod\" : {\n\t\t\t\tregexp : /^mod/,\n\t\t\t\tmethod : function(args, self){\n\t\t\t\t\tvar modulus = literalNumber(args[1]);\n\t\t\t\t\tvar op = new Tone.Modulo(modulus);\n\t\t\t\t\tself._eval(args[0]).connect(op);\n\t\t\t\t\treturn op;\n\t\t\t\t}\n\t\t\t},\n\t\t\t\"pow\" : {\n\t\t\t\tregexp : /^pow/,\n\t\t\t\tmethod : function(args, self){\n\t\t\t\t\tvar exp = literalNumber(args[1]);\n\t\t\t\t\tvar op = new Tone.Pow(exp);\n\t\t\t\t\tself._eval(args[0]).connect(op);\n\t\t\t\t\treturn op;\n\t\t\t\t}\n\t\t\t},\n\t\t\t\"a2g\" : {\n\t\t\t\tregexp : /^a2g/,\n\t\t\t\tmethod : function(args, self){\n\t\t\t\t\tvar op = new Tone.AudioToGain();\n\t\t\t\t\tself._eval(args[0]).connect(op);\n\t\t\t\t\treturn op;\n\t\t\t\t}\n\t\t\t},\n\t\t},\n\t\t//binary expressions\n\t\t\"binary\" : {\n\t\t\t\"+\" : {\n\t\t\t\tregexp : /^\\+/,\n\t\t\t\tprecedence : 1,\n\t\t\t\tmethod : applyBinary.bind(this, Tone.Add)\n\t\t\t},\n\t\t\t\"-\" : {\n\t\t\t\tregexp : /^\\-/,\n\t\t\t\tprecedence : 1,\n\t\t\t\tmethod : function(args, self){\n\t\t\t\t\t//both unary and binary op\n\t\t\t\t\tif (args.length === 1){\n\t\t\t\t\t\treturn applyUnary(Tone.Negate, args, self);\n\t\t\t\t\t} else {\n\t\t\t\t\t\treturn applyBinary(Tone.Subtract, args, self);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t},\n\t\t\t\"*\" : {\n\t\t\t\tregexp : /^\\*/,\n\t\t\t\tprecedence : 0,\n\t\t\t\tmethod : applyBinary.bind(this, Tone.Multiply)\n\t\t\t}\n\t\t},\n\t\t//unary expressions\n\t\t\"unary\" : {\n\t\t\t\"-\" : {\n\t\t\t\tregexp : /^\\-/,\n\t\t\t\tmethod : applyUnary.bind(this, Tone.Negate)\n\t\t\t},\n\t\t\t\"!\" : {\n\t\t\t\tregexp : /^\\!/,\n\t\t\t\tmethod : applyUnary.bind(this, Tone.NOT)\n\t\t\t},\n\t\t},\n\t};\n\t\t\n\t/**\n\t * @param {string} expr the expression string\n\t * @return {number} the input count\n\t * @private\n\t */\n\tTone.Expr.prototype._parseInputs = function(expr){\n\t\tvar inputArray = expr.match(/\\$\\d/g);\n\t\tvar inputMax = 0;\n\t\tif (inputArray !== null){\n\t\t\tfor (var i = 0; i < inputArray.length; i++){\n\t\t\t\tvar inputNum = parseInt(inputArray[i].substr(1)) + 1;\n\t\t\t\tinputMax = Math.max(inputMax, inputNum);\n\t\t\t}\n\t\t}\n\t\treturn inputMax;\n\t};\n\n\t/**\n\t * @param {Array} args \tan array of arguments\n\t * @return {string} the results of the replacements being replaced\n\t * @private\n\t */\n\tTone.Expr.prototype._replacements = function(args){\n\t\tvar expr = args.shift();\n\t\tfor (var i = 0; i < args.length; i++){\n\t\t\texpr = expr.replace(/\\%/i, args[i]);\n\t\t}\n\t\treturn expr;\n\t};\n\n\t/**\n\t * tokenize the expression based on the Expressions object\n\t * @param {string} expr \n\t * @return {Object} returns two methods on the tokenized list, next and peek\n\t * @private\n\t */\n\tTone.Expr.prototype._tokenize = function(expr){\n\t\tvar position = -1;\n\t\tvar tokens = [];\n\n\t\twhile(expr.length > 0){\n\t\t\texpr = expr.trim();\n\t\t\tvar token = getNextToken(expr);\n\t\t\ttokens.push(token);\n\t\t\texpr = expr.substr(token.value.length);\n\t\t}\n\n\t\tfunction getNextToken(expr){\n\t\t\tfor (var type in Tone.Expr._Expressions){\n\t\t\t\tvar group = Tone.Expr._Expressions[type];\n\t\t\t\tfor (var opName in group){\n\t\t\t\t\tvar op = group[opName];\n\t\t\t\t\tvar reg = op.regexp;\n\t\t\t\t\tvar match = expr.match(reg);\n\t\t\t\t\tif (match !== null){\n\t\t\t\t\t\treturn {\n\t\t\t\t\t\t\ttype : type,\n\t\t\t\t\t\t\tvalue : match[0],\n\t\t\t\t\t\t\tmethod : op.method\n\t\t\t\t\t\t};\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\tthrow new SyntaxError(\"Tone.Expr: Unexpected token \"+expr);\n\t\t}\n\n\t\treturn {\n\t\t\tnext : function(){\n\t\t\t\treturn tokens[++position];\n\t\t\t},\n\t\t\tpeek : function(){\n\t\t\t\treturn tokens[position + 1];\n\t\t\t}\n\t\t};\n\t};\n\n\t/**\n\t * recursively parse the string expression into a syntax tree\n\t * \n\t * @param {string} expr \n\t * @return {Object}\n\t * @private\n\t */\n\tTone.Expr.prototype._parseTree = function(expr){\n\t\tvar lexer = this._tokenize(expr);\n\t\tvar isUndef = this.isUndef.bind(this);\n\n\t\tfunction matchSyntax(token, syn) {\n\t\t\treturn !isUndef(token) && \n\t\t\t\ttoken.type === \"glue\" &&\n\t\t\t\ttoken.value === syn;\n\t\t}\n\n\t\tfunction matchGroup(token, groupName, prec) {\n\t\t\tvar ret = false;\n\t\t\tvar group = Tone.Expr._Expressions[groupName];\n\t\t\tif (!isUndef(token)){\n\t\t\t\tfor (var opName in group){\n\t\t\t\t\tvar op = group[opName];\n\t\t\t\t\tif (op.regexp.test(token.value)){\n\t\t\t\t\t\tif (!isUndef(prec)){\n\t\t\t\t\t\t\tif(op.precedence === prec){\t\n\t\t\t\t\t\t\t\treturn true;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\treturn true;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn ret;\n\t\t}\n\n\t\tfunction parseExpression(precedence) {\n\t\t\tif (isUndef(precedence)){\n\t\t\t\tprecedence = 5;\n\t\t\t}\n\t\t\tvar expr;\n\t\t\tif (precedence < 0){\n\t\t\t\texpr = parseUnary();\n\t\t\t} else {\n\t\t\t\texpr = parseExpression(precedence-1);\n\t\t\t}\n\t\t\tvar token = lexer.peek();\n\t\t\twhile (matchGroup(token, \"binary\", precedence)) {\n\t\t\t\ttoken = lexer.next();\n\t\t\t\texpr = {\n\t\t\t\t\toperator: token.value,\n\t\t\t\t\tmethod : token.method,\n\t\t\t\t\targs : [\n\t\t\t\t\t\texpr,\n\t\t\t\t\t\tparseExpression(precedence-1)\n\t\t\t\t\t]\n\t\t\t\t};\n\t\t\t\ttoken = lexer.peek();\n\t\t\t}\n\t\t\treturn expr;\n\t\t}\n\n\t\tfunction parseUnary() {\n\t\t\tvar token, expr;\n\t\t\ttoken = lexer.peek();\n\t\t\tif (matchGroup(token, \"unary\")) {\n\t\t\t\ttoken = lexer.next();\n\t\t\t\texpr = parseUnary();\n\t\t\t\treturn {\n\t\t\t\t\toperator: token.value,\n\t\t\t\t\tmethod : token.method,\n\t\t\t\t\targs : [expr]\n\t\t\t\t};\n\t\t\t}\n\t\t\treturn parsePrimary();\n\t\t}\n\n\t\tfunction parsePrimary() {\n\t\t\tvar token, expr;\n\t\t\ttoken = lexer.peek();\n\t\t\tif (isUndef(token)) {\n\t\t\t\tthrow new SyntaxError(\"Tone.Expr: Unexpected termination of expression\");\n\t\t\t}\n\t\t\tif (token.type === \"func\") {\n\t\t\t\ttoken = lexer.next();\n\t\t\t\treturn parseFunctionCall(token);\n\t\t\t}\n\t\t\tif (token.type === \"value\") {\n\t\t\t\ttoken = lexer.next();\n\t\t\t\treturn {\n\t\t\t\t\tmethod : token.method,\n\t\t\t\t\targs : token.value\n\t\t\t\t};\n\t\t\t}\n\t\t\tif (matchSyntax(token, \"(\")) {\n\t\t\t\tlexer.next();\n\t\t\t\texpr = parseExpression();\n\t\t\t\ttoken = lexer.next();\n\t\t\t\tif (!matchSyntax(token, \")\")) {\n\t\t\t\t\tthrow new SyntaxError(\"Expected )\");\n\t\t\t\t}\n\t\t\t\treturn expr;\n\t\t\t}\n\t\t\tthrow new SyntaxError(\"Tone.Expr: Parse error, cannot process token \" + token.value);\n\t\t}\n\n\t\tfunction parseFunctionCall(func) {\n\t\t\tvar token, args = [];\n\t\t\ttoken = lexer.next();\n\t\t\tif (!matchSyntax(token, \"(\")) {\n\t\t\t\tthrow new SyntaxError(\"Tone.Expr: Expected ( in a function call \\\"\" + func.value + \"\\\"\");\n\t\t\t}\n\t\t\ttoken = lexer.peek();\n\t\t\tif (!matchSyntax(token, \")\")) {\n\t\t\t\targs = parseArgumentList();\n\t\t\t}\n\t\t\ttoken = lexer.next();\n\t\t\tif (!matchSyntax(token, \")\")) {\n\t\t\t\tthrow new SyntaxError(\"Tone.Expr: Expected ) in a function call \\\"\" + func.value + \"\\\"\");\n\t\t\t}\n\t\t\treturn {\n\t\t\t\tmethod : func.method,\n\t\t\t\targs : args,\n\t\t\t\tname : name\n\t\t\t};\n\t\t}\n\n\t\tfunction parseArgumentList() {\n\t\t\tvar token, expr, args = [];\n\t\t\twhile (true) {\n\t\t\t\texpr = parseExpression();\n\t\t\t\tif (isUndef(expr)) {\n\t\t\t\t\t// TODO maybe throw exception?\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\targs.push(expr);\n\t\t\t\ttoken = lexer.peek();\n\t\t\t\tif (!matchSyntax(token, \",\")) {\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tlexer.next();\n\t\t\t}\n\t\t\treturn args;\n\t\t}\n\n\t\treturn parseExpression();\n\t};\n\n\t/**\n\t * recursively evaluate the expression tree\n\t * @param {Object} tree \n\t * @return {AudioNode} the resulting audio node from the expression\n\t * @private\n\t */\n\tTone.Expr.prototype._eval = function(tree){\n\t\tif (!this.isUndef(tree)){\n\t\t\tvar node = tree.method(tree.args, this);\n\t\t\tthis._nodes.push(node);\n\t\t\treturn node;\n\t\t} \n\t};\n\n\t/**\n\t * dispose all the nodes\n\t * @private\n\t */\n\tTone.Expr.prototype._disposeNodes = function(){\n\t\tfor (var i = 0; i < this._nodes.length; i++){\n\t\t\tvar node = this._nodes[i];\n\t\t\tif (this.isFunction(node.dispose)) {\n\t\t\t\tnode.dispose();\n\t\t\t} else if (this.isFunction(node.disconnect)) {\n\t\t\t\tnode.disconnect();\n\t\t\t}\n\t\t\tnode = null;\n\t\t\tthis._nodes[i] = null;\n\t\t}\n\t\tthis._nodes = null;\n\t};\n\n\t/**\n\t * clean up\n\t */\n\tTone.Expr.prototype.dispose = function(){\n\t\tTone.prototype.dispose.call(this);\n\t\tthis._disposeNodes();\n\t};\n\n\treturn Tone.Expr;\n});","define([\"Tone/core/Tone\", \"Tone/signal/GreaterThanZero\", \"Tone/signal/Subtract\", \"Tone/signal/Signal\"], \n\tfunction(Tone){\n\n\t\"use strict\";\n\n\t/**\n\t * @class Output 1 if the signal is greater than the value, otherwise outputs 0.\n\t * can compare two signals or a signal and a number. \n\t * \n\t * @constructor\n\t * @extends {Tone.Signal}\n\t * @param {number} [value=0] the value to compare to the incoming signal\n\t * @example\n\t * var gt = new Tone.GreaterThan(2);\n\t * var sig = new Tone.Signal(4).connect(gt);\n\t * //output of gt is equal 1. \n\t */\n\tTone.GreaterThan = function(value){\n\n\t\tthis.createInsOuts(2, 0);\n\t\t\n\t\t/**\n\t\t * subtract the amount from the incoming signal\n\t\t * @type {Tone.Subtract}\n\t\t * @private\n\t\t */\n\t\tthis._param = this.input[0] = new Tone.Subtract(value);\n\t\tthis.input[1] = this._param.input[1];\n\n\t\t/**\n\t\t * compare that amount to zero\n\t\t * @type {Tone.GreaterThanZero}\n\t\t * @private\n\t\t */\n\t\tthis._gtz = this.output = new Tone.GreaterThanZero();\n\n\t\t//connect\n\t\tthis._param.connect(this._gtz);\n\t};\n\n\tTone.extend(Tone.GreaterThan, Tone.Signal);\n\n\t/**\n\t * dispose method\n\t * @returns {Tone.GreaterThan} this\n\t */\n\tTone.GreaterThan.prototype.dispose = function(){\n\t\tTone.prototype.dispose.call(this);\n\t\tthis._param.dispose();\n\t\tthis._param = null;\n\t\tthis._gtz.dispose();\n\t\tthis._gtz = null;\n\t\treturn this;\n\t};\n\n\treturn Tone.GreaterThan;\n});","define([\"Tone/core/Tone\", \"Tone/signal/WaveShaper\", \"Tone/signal/SignalBase\"], \nfunction(Tone){\n\n\t\"use strict\";\n\n\t/**\n\t * @class Return the absolute value of an incoming signal. \n\t * \n\t * @constructor\n\t * @extends {Tone.SignalBase}\n\t * @example\n\t * var signal = new Tone.Signal(-1);\n\t * var abs = new Tone.Abs();\n\t * signal.connect(abs);\n\t * //the output of abs is 1. \n\t */\n\tTone.Abs = function(){\n\t\t/**\n\t\t * @type {Tone.LessThan}\n\t\t * @private\n\t\t */\n\t\tthis._abs = this.input = this.output = new Tone.WaveShaper(function(val){\n\t\t\tif (val === 0){\n\t\t\t\treturn 0;\n\t\t\t} else {\n\t\t\t\treturn Math.abs(val);\n\t\t\t}\n\t\t}, 127);\n\t};\n\n\tTone.extend(Tone.Abs, Tone.SignalBase);\n\n\t/**\n\t * dispose method\n\t * @returns {Tone.Abs} this\n\t */\n\tTone.Abs.prototype.dispose = function(){\n\t\tTone.prototype.dispose.call(this);\n\t\tthis._abs.dispose();\n\t\tthis._abs = null;\n\t\treturn this;\n\t}; \n\n\treturn Tone.Abs;\n});","define([\"Tone/core/Tone\", \"Tone/signal/WaveShaper\", \"Tone/signal/Multiply\", \"Tone/signal/Subtract\"], \nfunction(Tone){\n\n\t\"use strict\";\n\n\t/**\n\t * @class Signal-rate modulo operator. Only works in AudioRange [-1, 1] and for modulus\n\t * values in the NormalRange. \n\t *\n\t * @constructor\n\t * @extends {Tone.SignalBase}\n\t * @param {NormalRange} modulus The modulus to apply.\n\t * @example\n\t * var mod = new Tone.Modulo(0.2)\n\t * var sig = new Tone.Signal(0.5).connect(mod);\n\t * //mod outputs 0.1\n\t */\n\tTone.Modulo = function(modulus){\n\n\t\tthis.createInsOuts(1, 0);\n\n\t\t/**\n\t\t * A waveshaper gets the integer multiple of \n\t\t * the input signal and the modulus.\n\t\t * @private\n\t\t * @type {Tone.WaveShaper}\n\t\t */\n\t\tthis._shaper = new Tone.WaveShaper(Math.pow(2, 16));\n\n\t\t/**\n\t\t * the integer multiple is multiplied by the modulus\n\t\t * @type {Tone.Multiply}\n\t\t * @private\n\t\t */\n\t\tthis._multiply = new Tone.Multiply();\n\n\t\t/**\n\t\t * and subtracted from the input signal\n\t\t * @type {Tone.Subtract}\n\t\t * @private\n\t\t */\n\t\tthis._subtract = this.output = new Tone.Subtract();\n\n\t\t/**\n\t\t * the modulus signal\n\t\t * @type {Tone.Signal}\n\t\t * @private\n\t\t */\n\t\tthis._modSignal = new Tone.Signal(modulus);\n\n\t\t//connections\n\t\tthis.input.fan(this._shaper, this._subtract);\n\t\tthis._modSignal.connect(this._multiply, 0, 0);\n\t\tthis._shaper.connect(this._multiply, 0, 1);\n\t\tthis._multiply.connect(this._subtract, 0, 1);\n\t\tthis._setWaveShaper(modulus);\n\t};\n\n\tTone.extend(Tone.Modulo, Tone.SignalBase);\n\n\t/**\n\t * @param {number} mod the modulus to apply\n\t * @private\n\t */\n\tTone.Modulo.prototype._setWaveShaper = function(mod){\n\t\tthis._shaper.setMap(function(val){\n\t\t\tvar multiple = Math.floor((val + 0.0001) / mod);\n\t\t\treturn multiple;\n\t\t});\n\t};\n\n\t/**\n\t * The modulus value.\n\t * @memberOf Tone.Modulo#\n\t * @type {NormalRange}\n\t * @name value\n\t */\n\tObject.defineProperty(Tone.Modulo.prototype, \"value\", {\n\t\tget : function(){\n\t\t\treturn this._modSignal.value;\n\t\t},\n\t\tset : function(mod){\n\t\t\tthis._modSignal.value = mod;\n\t\t\tthis._setWaveShaper(mod);\n\t\t}\n\t});\n\n\t/**\n\t * clean up\n\t * @returns {Tone.Modulo} this\n\t */\n\tTone.Modulo.prototype.dispose = function(){\n\t\tTone.prototype.dispose.call(this);\n\t\tthis._shaper.dispose();\n\t\tthis._shaper = null;\n\t\tthis._multiply.dispose();\n\t\tthis._multiply = null;\n\t\tthis._subtract.dispose();\n\t\tthis._subtract = null;\n\t\tthis._modSignal.dispose();\n\t\tthis._modSignal = null;\n\t\treturn this;\n\t};\n\n\treturn Tone.Modulo;\n});","define([\"Tone/core/Tone\", \"Tone/signal/WaveShaper\"], function(Tone){\n\n\t\"use strict\";\n\n\t/**\n\t * @class Pow applies an exponent to the incoming signal. The incoming signal\n\t * must be AudioRange.\n\t *\n\t * @extends {Tone.SignalBase}\n\t * @constructor\n\t * @param {Positive} exp The exponent to apply to the incoming signal, must be at least 2. \n\t * @example\n\t * var pow = new Tone.Pow(2);\n\t * var sig = new Tone.Signal(0.5).connect(pow);\n\t * //output of pow is 0.25. \n\t */\n\tTone.Pow = function(exp){\n\n\t\t/**\n\t\t * the exponent\n\t\t * @private\n\t\t * @type {number}\n\t\t */\n\t\tthis._exp = this.defaultArg(exp, 1);\n\n\t\t/**\n\t\t * @type {WaveShaperNode}\n\t\t * @private\n\t\t */\n\t\tthis._expScaler = this.input = this.output = new Tone.WaveShaper(this._expFunc(this._exp), 8192);\n\t};\n\n\tTone.extend(Tone.Pow, Tone.SignalBase);\n\n\t/**\n\t * The value of the exponent.\n\t * @memberOf Tone.Pow#\n\t * @type {number}\n\t * @name value\n\t */\n\tObject.defineProperty(Tone.Pow.prototype, \"value\", {\n\t\tget : function(){\n\t\t\treturn this._exp;\n\t\t},\n\t\tset : function(exp){\n\t\t\tthis._exp = exp;\n\t\t\tthis._expScaler.setMap(this._expFunc(this._exp));\n\t\t}\n\t});\n\n\n\t/**\n\t * the function which maps the waveshaper\n\t * @param {number} exp\n\t * @return {function}\n\t * @private\n\t */\n\tTone.Pow.prototype._expFunc = function(exp){\n\t\treturn function(val){\n\t\t\treturn Math.pow(Math.abs(val), exp);\n\t\t};\n\t};\n\n\t/**\n\t * Clean up.\n\t * @returns {Tone.Pow} this\n\t */\n\tTone.Pow.prototype.dispose = function(){\n\t\tTone.prototype.dispose.call(this);\n\t\tthis._expScaler.dispose();\n\t\tthis._expScaler = null;\n\t\treturn this;\n\t};\n\n\treturn Tone.Pow;\n});","define([\"Tone/core/Tone\", \"Tone/signal/WaveShaper\", \"Tone/signal/Signal\"], function(Tone){\n\n\t\"use strict\";\n\n\t/**\n\t * @class AudioToGain converts an input in AudioRange [-1,1] to NormalRange [0,1]. \n\t * See Tone.GainToAudio.\n\t *\n\t * @extends {Tone.SignalBase}\n\t * @constructor\n\t * @example\n\t * var a2g = new Tone.AudioToGain();\n\t */\n\tTone.AudioToGain = function(){\n\n\t\t/**\n\t\t * @type {WaveShaperNode}\n\t\t * @private\n\t\t */\n\t\tthis._norm = this.input = this.output = new Tone.WaveShaper(function(x){\n\t\t\treturn (x + 1) / 2;\n\t\t});\n\t};\n\n\tTone.extend(Tone.AudioToGain, Tone.SignalBase);\n\n\t/**\n\t * clean up\n\t * @returns {Tone.AudioToGain} this\n\t */\n\tTone.AudioToGain.prototype.dispose = function(){\n\t\tTone.prototype.dispose.call(this);\n\t\tthis._norm.dispose();\n\t\tthis._norm = null;\n\t\treturn this;\n\t};\n\n\treturn Tone.AudioToGain;\n});","define([\"Tone/core/Tone\", \"Tone/signal/WaveShaper\"], function(Tone){\n\n\t\"use strict\";\n\n\t/**\n\t * @class Convert an incoming signal between 0, 1 to an equal power gain scale.\n\t *\n\t * @extends {Tone.SignalBase}\n\t * @constructor\n\t * @example\n\t * var eqPowGain = new Tone.EqualPowerGain();\n\t */\n\tTone.EqualPowerGain = function(){\n\n\t\t/**\n\t\t * @type {Tone.WaveShaper}\n\t\t * @private\n\t\t */\n\t\tthis._eqPower = this.input = this.output = new Tone.WaveShaper(function(val){\n\t\t\tif (Math.abs(val) < 0.001){\n\t\t\t\t//should output 0 when input is 0\n\t\t\t\treturn 0;\n\t\t\t} else {\n\t\t\t\treturn this.equalPowerScale(val);\n\t\t\t}\n\t\t}.bind(this), 4096);\n\t};\n\n\tTone.extend(Tone.EqualPowerGain, Tone.SignalBase);\n\n\t/**\n\t * clean up\n\t * @returns {Tone.EqualPowerGain} this\n\t */\n\tTone.EqualPowerGain.prototype.dispose = function(){\n\t\tTone.prototype.dispose.call(this);\n\t\tthis._eqPower.dispose();\n\t\tthis._eqPower = null;\n\t\treturn this;\n\t};\n\n\treturn Tone.EqualPowerGain;\n});","'use strict';\n\ndefine(function (require) {\n\n var Effect = require('effect');\n var EQFilter = require('eqFilter');\n\n /**\n * p5.EQ is an audio effect that performs the function of a multiband\n * audio equalizer. Equalization is used to adjust the balance of\n * frequency compoenents of an audio signal. This process is commonly used\n * in sound production and recording to change the waveform before it reaches\n * a sound output device. EQ can also be used as an audio effect to create\n * interesting distortions by filtering out parts of the spectrum. p5.EQ is\n * built using a chain of Web Audio Biquad Filter Nodes and can be\n * instantiated with 3 or 8 bands. Bands can be added or removed from\n * the EQ by directly modifying p5.EQ.bands (the array that stores filters).\n *\n * This class extends p5.Effect.\n * Methods amp(), chain(),\n * drywet(), connect(), and\n * disconnect() are available.\n *\n * @class p5.EQ\n * @constructor\n * @extends p5.Effect\n * @param {Number} [_eqsize] Constructor will accept 3 or 8, defaults to 3\n * @return {Object} p5.EQ object\n *\n * @example\n *
\n * var eq;\n * var band_names;\n * var band_index;\n *\n * var soundFile, play;\n *\n * function preload() {\n * soundFormats('mp3', 'ogg');\n * soundFile = loadSound('assets/beat');\n * }\n *\n * function setup() {\n * eq = new p5.EQ(3);\n * soundFile.disconnect();\n * eq.process(soundFile);\n *\n * band_names = ['lows','mids','highs'];\n * band_index = 0;\n * play = false;\n * textAlign(CENTER);\n * }\n *\n * function draw() {\n * background(30);\n * noStroke();\n * fill(255);\n * text('click to kill',50,25);\n *\n * fill(255, 40, 255);\n * textSize(26);\n * text(band_names[band_index],50,55);\n *\n * fill(255);\n * textSize(9);\n * text('space = play/pause',50,80);\n * }\n *\n * //If mouse is over canvas, cycle to the next band and kill the frequency\n * function mouseClicked() {\n * for (var i = 0; i < eq.bands.length; i++) {\n * eq.bands[i].gain(0);\n * }\n * eq.bands[band_index].gain(-40);\n * if (mouseX > 0 && mouseX < width && mouseY < height && mouseY > 0) {\n * band_index === 2 ? band_index = 0 : band_index++;\n * }\n * }\n *\n * //use space bar to trigger play / pause\n * function keyPressed() {\n * if (key===' ') {\n * play = !play\n * play ? soundFile.loop() : soundFile.pause();\n * }\n * }\n *
\n */\n p5.EQ = function(_eqsize) {\n Effect.call(this);\n\n //p5.EQ can be of size (3) or (8), defaults to 3\n _eqsize = _eqsize === 3 || _eqsize === 8 ? _eqsize : 3;\n\n var factor;\n _eqsize === 3 ? factor = Math.pow(2,3) : factor = 2;\n\n /**\n * The p5.EQ is built with abstracted p5.Filter objects.\n * To modify any bands, use methods of the \n * p5.Filter API, especially `gain` and `freq`.\n * Bands are stored in an array, with indices 0 - 3, or 0 - 7\n * @property {Array} bands\n *\n */\n this.bands = [];\n\n\n var freq, res;\n for (var i = 0; i < _eqsize; i++) {\n if (i === _eqsize - 1) {\n freq = 21000;\n res = .01;\n } else if (i === 0) {\n freq = 100;\n res = .1;\n }\n else if (i===1) {\n freq = _eqsize === 3 ? 360 * factor : 360;\n res = 1;\n }else {\n freq = this.bands[i-1].freq() * factor;\n res = 1;\n }\n this.bands[i] = this._newBand(freq, res);\n\n if (i>0) {\n this.bands[i-1].connect(this.bands[i].biquad);\n } else {\n this.input.connect(this.bands[i].biquad);\n }\n }\n this.bands[_eqsize-1].connect(this.output);\n };\n p5.EQ.prototype = Object.create(Effect.prototype);\n\n /**\n * Process an input by connecting it to the EQ\n * @method process\n * @param {Object} src Audio source\n */\n p5.EQ.prototype.process = function (src) {\n src.connect(this.input);\n };\n\n // /**\n // * Set the frequency and gain of each band in the EQ. This method should be\n // * called with 3 or 8 frequency and gain pairs, depending on the size of the EQ.\n // * ex. eq.set(freq0, gain0, freq1, gain1, freq2, gain2);\n // *\n // * @method set\n // * @for p5.EQ\n // * @param {Number} [freq0] Frequency value for band with index 0\n // * @param {Number} [gain0] Gain value for band with index 0\n // * @param {Number} [freq1] Frequency value for band with index 1\n // * @param {Number} [gain1] Gain value for band with index 1\n // * @param {Number} [freq2] Frequency value for band with index 2\n // * @param {Number} [gain2] Gain value for band with index 2\n // * @param {Number} [freq3] Frequency value for band with index 3\n // * @param {Number} [gain3] Gain value for band with index 3\n // * @param {Number} [freq4] Frequency value for band with index 4\n // * @param {Number} [gain4] Gain value for band with index 4\n // * @param {Number} [freq5] Frequency value for band with index 5\n // * @param {Number} [gain5] Gain value for band with index 5\n // * @param {Number} [freq6] Frequency value for band with index 6\n // * @param {Number} [gain6] Gain value for band with index 6\n // * @param {Number} [freq7] Frequency value for band with index 7\n // * @param {Number} [gain7] Gain value for band with index 7\n // */\n p5.EQ.prototype.set = function() {\n if (arguments.length === this.bands.length * 2) {\n for (var i = 0; i < arguments.length; i+=2) {\n this.bands[i/2].freq(arguments[i]);\n this.bands[i/2].gain(arguments[i+1]);\n }\n }\n else {\n console.error('Argument mismatch. .set() should be called with ' + this.bands.length*2 +\n ' arguments. (one frequency and gain value pair for each band of the eq)');\n }\n };\n\n /**\n * Add a new band. Creates a p5.Filter and strips away everything but\n * the raw biquad filter. This method returns an abstracted p5.Filter,\n * which can be added to p5.EQ.bands, in order to create new EQ bands.\n * @private\n * @for p5.EQ\n * @method _newBand\n * @param {Number} freq\n * @param {Number} res\n * @return {Object} Abstracted Filter\n */\n p5.EQ.prototype._newBand = function(freq, res) {\n return new EQFilter(freq, res);\n };\n\n p5.EQ.prototype.dispose = function () {\n Effect.prototype.dispose.apply(this);\n\n if (this.bands) {\n while (this.bands.length > 0) {\n delete this.bands.pop().dispose();\n }\n delete this.bands;\n }\n };\n\n return p5.EQ;\n});\n","'use strict';\n\ndefine(function (require) {\n var Filter = require('filter');\n var p5sound = require('master');\n\n /**\n * EQFilter extends p5.Filter with constraints\n * necessary for the p5.EQ\n *\n * @private\n */\n var EQFilter = function(freq, res) {\n Filter.call(this, 'peaking');\n this.disconnect();\n this.set(freq, res);\n this.biquad.gain.value = 0;\n delete this.input;\n delete this.output;\n delete this._drywet;\n delete this.wet;\n\n };\n EQFilter.prototype = Object.create(Filter.prototype);\n\n EQFilter.prototype.amp = function() {\n console.warn('`amp()` is not available for p5.EQ bands. Use `.gain()`');\n };\n EQFilter.prototype.drywet = function() {\n console.warn('`drywet()` is not available for p5.EQ bands.');\n };\n EQFilter.prototype.connect = function(unit) {\n var u = unit || p5.soundOut.input;\n if (this.biquad) {\n this.biquad.connect(u.input ? u.input : u);\n } else {\n this.output.connect(u.input ? u.input : u);\n }\n };\n\n EQFilter.prototype.disconnect = function() {\n if (this.biquad) {\n this.biquad.disconnect();\n }\n };\n EQFilter.prototype.dispose = function() {\n // remove reference form soundArray\n var index = p5sound.soundArray.indexOf(this);\n p5sound.soundArray.splice(index, 1);\n this.disconnect();\n delete this.biquad;\n };\n\n return EQFilter;\n});\n","'use strict'\n\ndefine(function (require) {\n var p5sound = require('master');\n var Effect = require('effect');\n\n /**\n * Panner3D is based on the \n * Web Audio Spatial Panner Node.\n * This panner is a spatial processing node that allows audio to be positioned\n * and oriented in 3D space.\n *\n * The position is relative to an \n * Audio Context Listener, which can be accessed\n * by p5.soundOut.audiocontext.listener\n *\n *\n * @class p5.Panner3D\n * @constructor\n */\n\tp5.Panner3D = function() {\n Effect.call(this);\n\n /**\n * \n * Web Audio Spatial Panner Node\n *\n * Properties include\n * - panningModel: \"equal power\" or \"HRTF\"\n * - distanceModel: \"linear\", \"inverse\", or \"exponential\"\n *\n * @property {AudioNode} panner\n *\n */\n this.panner = this.ac.createPanner();\n this.panner.panningModel = 'HRTF';\n this.panner.distanceModel = 'linear';\n this.panner.connect(this.output);\n this.input.connect(this.panner);\n\t};\n\n p5.Panner3D.prototype = Object.create(Effect.prototype);\n\n\n /**\n * Connect an audio sorce\n *\n * @method process\n * @for p5.Panner3D\n * @param {Object} src Input source\n */\n p5.Panner3D.prototype.process = function(src) {\n src.connect(this.input);\n }\n /**\n * Set the X,Y,Z position of the Panner\n * @method set\n * @for p5.Panner3D\n * @param {Number} xVal\n * @param {Number} yVal\n * @param {Number} zVal\n * @param {Number} time\n * @return {Array} Updated x, y, z values as an array\n */\n p5.Panner3D.prototype.set = function(xVal, yVal, zVal, time) {\n this.positionX(xVal,time);\n this.positionY(yVal,time);\n this.positionZ(zVal,time);\n return [this.panner.positionX.value,\n this.panner.positionY.value,\n this.panner.positionZ.value];\n };\n\n /**\n * Getter and setter methods for position coordinates\n * @method positionX\n * @for p5.Panner3D\n * @return {Number} updated coordinate value\n */\n /**\n * Getter and setter methods for position coordinates\n * @method positionY\n * @for p5.Panner3D\n * @return {Number} updated coordinate value\n */\n /**\n * Getter and setter methods for position coordinates\n * @method positionZ\n * @for p5.Panner3D\n * @return {Number} updated coordinate value\n */\n p5.Panner3D.prototype.positionX = function(xVal, time) {\n var t = time || 0;\n if (typeof xVal === 'number') {\n this.panner.positionX.value = xVal;\n this.panner.positionX.cancelScheduledValues(this.ac.currentTime + 0.01 + t);\n this.panner.positionX.linearRampToValueAtTime(xVal, this.ac.currentTime + 0.02 + t);\n } else if (xVal) {\n xVal.connect(this.panner.positionX);\n }\n return this.panner.positionX.value;\n };\n p5.Panner3D.prototype.positionY = function(yVal, time) {\n var t = time || 0;\n if (typeof yVal === 'number') {\n this.panner.positionY.value = yVal;\n this.panner.positionY.cancelScheduledValues(this.ac.currentTime + 0.01 + t);\n this.panner.positionY.linearRampToValueAtTime(yVal, this.ac.currentTime + 0.02 + t);\n } else if (yVal) {\n yVal.connect(this.panner.positionY);\n }\n return this.panner.positionY.value;\n };\n p5.Panner3D.prototype.positionZ = function(zVal, time) {\n var t = time || 0;\n if (typeof zVal === 'number') {\n this.panner.positionZ.value = zVal;\n this.panner.positionZ.cancelScheduledValues(this.ac.currentTime + 0.01 + t);\n this.panner.positionZ.linearRampToValueAtTime(zVal, this.ac.currentTime + 0.02 + t);\n } else if (zVal) {\n zVal.connect(this.panner.positionZ);\n }\n return this.panner.positionZ.value;\n };\n\n /**\n * Set the X,Y,Z position of the Panner\n * @method orient\n * @for p5.Panner3D\n * @param {Number} xVal\n * @param {Number} yVal\n * @param {Number} zVal\n * @param {Number} time\n * @return {Array} Updated x, y, z values as an array\n */\n p5.Panner3D.prototype.orient = function(xVal, yVal, zVal, time) {\n this.orientX(xVal,time);\n this.orientY(yVal,time);\n this.orientZ(zVal,time);\n return [this.panner.orientationX.value,\n this.panner.orientationY.value,\n this.panner.orientationZ.value];\n };\n\n /**\n * Getter and setter methods for orient coordinates\n * @method orientX\n * @for p5.Panner3D\n * @return {Number} updated coordinate value\n */\n /**\n * Getter and setter methods for orient coordinates\n * @method orientY\n * @for p5.Panner3D\n * @return {Number} updated coordinate value\n */\n /**\n * Getter and setter methods for orient coordinates\n * @method orientZ\n * @for p5.Panner3D\n * @return {Number} updated coordinate value\n */\n p5.Panner3D.prototype.orientX = function(xVal, time) {\n var t = time || 0;\n if (typeof xVal === 'number') {\n this.panner.orientationX.value = xVal;\n this.panner.orientationX.cancelScheduledValues(this.ac.currentTime + 0.01 + t);\n this.panner.orientationX.linearRampToValueAtTime(xVal, this.ac.currentTime + 0.02 + t);\n } else if (xVal) {\n xVal.connect(this.panner.orientationX);\n }\n return this.panner.orientationX.value;\n };\n p5.Panner3D.prototype.orientY = function(yVal, time) {\n var t = time || 0;\n if (typeof yVal === 'number') {\n this.panner.orientationY.value = yVal;\n this.panner.orientationY.cancelScheduledValues(this.ac.currentTime + 0.01 + t);\n this.panner.orientationY.linearRampToValueAtTime(yVal, this.ac.currentTime + 0.02 + t);\n } else if (yVal) {\n yVal.connect(this.panner.orientationY);\n }\n return this.panner.orientationY.value;\n };\n p5.Panner3D.prototype.orientZ = function(zVal, time) {\n var t = time || 0;\n if (typeof zVal === 'number') {\n this.panner.orientationZ.value = zVal;\n this.panner.orientationZ.cancelScheduledValues(this.ac.currentTime + 0.01 + t);\n this.panner.orientationZ.linearRampToValueAtTime(zVal, this.ac.currentTime + 0.02 + t);\n } else if (zVal) {\n zVal.connect(this.panner.orientationZ);\n }\n return this.panner.orientationZ.value;\n };\n\n /**\n * Set the rolloff factor and max distance\n * @method setFalloff\n * @for p5.Panner3D\n * @param {Number} [maxDistance]\n * @param {Number} [rolloffFactor]\n */\n p5.Panner3D.prototype.setFalloff = function(maxDistance, rolloffFactor) {\n this.maxDist(maxDistance);\n this.rolloff(rolloffFactor);\n };\n /**\n * Maxium distance between the source and the listener\n * @method maxDist\n * @for p5.Panner3D\n * @param {Number} maxDistance\n * @return {Number} updated value\n */\n p5.Panner3D.prototype.maxDist = function(maxDistance){\n if (typeof maxDistance === 'number') {\n this.panner.maxDistance = maxDistance;\n }\n return this.panner.maxDistance;\n };\n\n /**\n * How quickly the volume is reduced as the source moves away from the listener\n * @method rollof\n * @for p5.Panner3D\n * @param {Number} rolloffFactor\n * @return {Number} updated value\n */\n p5.Panner3D.prototype.rolloff = function(rolloffFactor){\n if (typeof rolloffFactor === 'number') {\n this.panner.rolloffFactor = rolloffFactor;\n }\n return this.panner.rolloffFactor;\n };\n\n p5.Panner3D.dispose = function() {\n Effect.prototype.dispose.apply(this);\n if (this.panner) {\n this.panner.disconnect();\n delete this.panner;\n }\n };\n\n return p5.Panner3D;\n\n});\n","'use strict'\n\ndefine(function (require) {\n var p5sound = require('master');\n var Effect = require('effect');\n\n// /**\n// * listener is a class that can construct both a Spatial Panner\n// * and a Spatial Listener. The panner is based on the \n// * Web Audio Spatial Panner Node\n// * https://www.w3.org/TR/webaudio/#the-listenernode-interface\n// * This panner is a spatial processing node that allows audio to be positioned\n// * and oriented in 3D space. \n// *\n// * The Listener modifies the properties of the Audio Context Listener. \n// * Both objects types use the same methods. The default is a spatial panner.\n// *\n// * p5.Panner3D - Constructs a Spatial Panner \n// * p5.Listener3D - Constructs a Spatial Listener \n// *\n// * @class listener\n// * @constructor\n// * @return {Object} p5.Listener3D Object\n// *\n// * @param {Web Audio Node} listener Web Audio Spatial Panning Node\n// * @param {AudioParam} listener.panningModel \"equal power\" or \"HRTF\"\n// * @param {AudioParam} listener.distanceModel \"linear\", \"inverse\", or \"exponential\"\n// * @param {String} [type] [Specify construction of a spatial panner or listener]\n// */\n \n\tp5.Listener3D = function(type) {\n this.ac = p5sound.audiocontext;\n this.listener = this.ac.listener;\n\t}; \n\n// /**\n// * Connect an audio sorce\n// * @param {Object} src Input source\n// */\n p5.Listener3D.prototype.process = function(src) {\n src.connect(this.input);\n }\n// /**\n// * Set the X,Y,Z position of the Panner\n// * @param {[Number]} xVal\n// * @param {[Number]} yVal\n// * @param {[Number]} zVal\n// * @param {[Number]} time\n// * @return {[Array]} [Updated x, y, z values as an array]\n// */\n p5.Listener3D.prototype.position = function(xVal, yVal, zVal, time) {\n this.positionX(xVal,time);\n this.positionY(yVal,time);\n this.positionZ(zVal,time);\n return [this.listener.positionX.value, \n this.listener.positionY.value,\n this.listener.positionZ.value];\n };\n\n// /**\n// * Getter and setter methods for position coordinates\n// * @return {Number} [updated coordinate value]\n// */\n p5.Listener3D.prototype.positionX = function(xVal, time) {\n var t = time || 0;\n if (typeof xVal === 'number') {\n this.listener.positionX.value = xVal;\n this.listener.positionX.cancelScheduledValues(this.ac.currentTime + 0.01 + t);\n this.listener.positionX.linearRampToValueAtTime(xVal, this.ac.currentTime + 0.02 + t);\n } else if (xVal) {\n xVal.connect(this.listener.positionX);\n }\n return this.listener.positionX.value;\n };\n p5.Listener3D.prototype.positionY = function(yVal, time) {\n var t = time || 0;\n if (typeof yVal === 'number') {\n this.listener.positionY.value = yVal;\n this.listener.positionY.cancelScheduledValues(this.ac.currentTime + 0.01 + t);\n this.listener.positionY.linearRampToValueAtTime(yVal, this.ac.currentTime + 0.02 + t);\n } else if (yVal) {\n yVal.connect(this.listener.positionY);\n }\n return this.listener.positionY.value;\n };\n p5.Listener3D.prototype.positionZ = function(zVal, time) {\n var t = time || 0;\n if (typeof zVal === 'number') {\n this.listener.positionZ.value = zVal;\n this.listener.positionZ.cancelScheduledValues(this.ac.currentTime + 0.01 + t);\n this.listener.positionZ.linearRampToValueAtTime(zVal, this.ac.currentTime + 0.02 + t);\n } else if (zVal) {\n zVal.connect(this.listener.positionZ);\n }\n return this.listener.positionZ.value;\n };\n\n// cannot define method when class definition is commented\n// /**\n// * Overrides the listener orient() method because Listener has slightly\n// * different params. In human terms, Forward vectors are the direction the \n// * nose is pointing. Up vectors are the direction of the top of the head.\n// *\n// * @method orient\n// * @param {Number} xValF Forward vector X direction\n// * @param {Number} yValF Forward vector Y direction\n// * @param {Number} zValF Forward vector Z direction\n// * @param {Number} xValU Up vector X direction\n// * @param {Number} yValU Up vector Y direction\n// * @param {Number} zValU Up vector Z direction\n// * @param {Number} time \n// * @return {Array} All orienation params\n// */\n p5.Listener3D.prototype.orient = function(xValF, yValF, zValF, \n xValU, yValU, zValU, time) {\n\n if (arguments.length === 3 || arguments.length === 4) {\n time = arguments[3];\n this.orientForward(xValF, yValF, zValF, time);\n } else if (arguments.length === 6 || arguments === 7) {\n this.orientForward(xValF, yValF, zValF);\n this.orientUp(xValU, yValU, zValU, time);\n }\n \n return [this.listener.forwardX.value, \n this.listener.forwardY.value,\n this.listener.forwardZ.value,\n this.listener.upX.value,\n this.listener.upY.value,\n this.listener.upZ.value];\n };\n\n\n p5.Listener3D.prototype.orientForward = function(xValF, yValF, zValF, time) {\n this.forwardX(xValF,time);\n this.forwardY(yValF,time);\n this.forwardZ(zValF,time);\n\n return [this.listener.forwardX, \n this.listener.forwardY,\n this.listener.forwardZ];\n };\n\n p5.Listener3D.prototype.orientUp = function(xValU, yValU, zValU, time) {\n this.upX(xValU,time);\n this.upY(yValU,time);\n this.upZ(zValU,time);\n\n return [this.listener.upX, \n this.listener.upY,\n this.listener.upZ];\n };\n// /**\n// * Getter and setter methods for orient coordinates\n// * @return {Number} [updated coordinate value]\n// */\n p5.Listener3D.prototype.forwardX = function(xVal, time) {\n var t = time || 0;\n if (typeof xVal === 'number') {\n this.listener.forwardX.value = xVal;\n this.listener.forwardX.cancelScheduledValues(this.ac.currentTime + 0.01 + t);\n this.listener.forwardX.linearRampToValueAtTime(xVal, this.ac.currentTime + 0.02 + t);\n } else if (xVal) {\n xVal.connect(this.listener.forwardX);\n }\n return this.listener.forwardX.value;\n };\n p5.Listener3D.prototype.forwardY = function(yVal, time) {\n var t = time || 0;\n if (typeof yVal === 'number') {\n this.listener.forwardY.value = yVal;\n this.listener.forwardY.cancelScheduledValues(this.ac.currentTime + 0.01 + t);\n this.listener.forwardY.linearRampToValueAtTime(yVal, this.ac.currentTime + 0.02 + t);\n } else if (yVal) {\n yVal.connect(this.listener.forwardY);\n }\n return this.listener.forwardY.value;\n };\n p5.Listener3D.prototype.forwardZ = function(zVal, time) {\n var t = time || 0;\n if (typeof zVal === 'number') {\n this.listener.forwardZ.value = zVal;\n this.listener.forwardZ.cancelScheduledValues(this.ac.currentTime + 0.01 + t);\n this.listener.forwardZ.linearRampToValueAtTime(zVal, this.ac.currentTime + 0.02 + t);\n } else if (zVal) {\n zVal.connect(this.listener.forwardZ);\n }\n return this.listener.forwardZ.value;\n };\n p5.Listener3D.prototype.upX = function(xVal, time) {\n var t = time || 0;\n if (typeof xVal === 'number') {\n this.listener.upX.value = xVal;\n this.listener.upX.cancelScheduledValues(this.ac.currentTime + 0.01 + t);\n this.listener.upX.linearRampToValueAtTime(xVal, this.ac.currentTime + 0.02 + t);\n } else if (xVal) {\n xVal.connect(this.listener.upX);\n }\n return this.listener.upX.value;\n };\n p5.Listener3D.prototype.upY = function(yVal, time) {\n var t = time || 0;\n if (typeof yVal === 'number') {\n this.listener.upY.value = yVal;\n this.listener.upY.cancelScheduledValues(this.ac.currentTime + 0.01 + t);\n this.listener.upY.linearRampToValueAtTime(yVal, this.ac.currentTime + 0.02 + t);\n } else if (yVal) {\n yVal.connect(this.listener.upY);\n }\n return this.listener.upY.value;\n };\n p5.Listener3D.prototype.upZ = function(zVal, time) {\n var t = time || 0;\n if (typeof zVal === 'number') {\n this.listener.upZ.value = zVal;\n this.listener.upZ.cancelScheduledValues(this.ac.currentTime + 0.01 + t);\n this.listener.upZ.linearRampToValueAtTime(zVal, this.ac.currentTime + 0.02 + t);\n } else if (zVal) {\n zVal.connect(this.listener.upZ);\n }\n return this.listener.upZ.value;\n };\n \n return p5.Listener3D;\n\n});","'use strict';\n\ndefine(function (require) {\n var Filter = require('filter');\n var Effect = require('effect');\n\n /**\n * Delay is an echo effect. It processes an existing sound source,\n * and outputs a delayed version of that sound. The p5.Delay can\n * produce different effects depending on the delayTime, feedback,\n * filter, and type. In the example below, a feedback of 0.5 (the\n * defaul value) will produce a looping delay that decreases in\n * volume by 50% each repeat. A filter will cut out the high\n * frequencies so that the delay does not sound as piercing as the\n * original source.\n *\n *\n * This class extends p5.Effect.\n * Methods amp(), chain(),\n * drywet(), connect(), and\n * disconnect() are available.\n * @class p5.Delay\n * @extends p5.Effect\n * @constructor\n * @example\n *
\n * var noise, env, delay;\n *\n * function setup() {\n * background(0);\n * noStroke();\n * fill(255);\n * textAlign(CENTER);\n * text('click to play', width/2, height/2);\n *\n * noise = new p5.Noise('brown');\n * noise.amp(0);\n * noise.start();\n *\n * delay = new p5.Delay();\n *\n * // delay.process() accepts 4 parameters:\n * // source, delayTime, feedback, filter frequency\n * // play with these numbers!!\n * delay.process(noise, .12, .7, 2300);\n *\n * // play the noise with an envelope,\n * // a series of fades ( time / value pairs )\n * env = new p5.Envelope(.01, 0.2, .2, .1);\n * }\n *\n * // mouseClick triggers envelope\n * function mouseClicked() {\n * // is mouse over canvas?\n * if (mouseX > 0 && mouseX < width && mouseY > 0 && mouseY < height) {\n * env.play(noise);\n * }\n * }\n *
\n */\n p5.Delay = function() {\n \tEffect.call(this);\n\n this._split = this.ac.createChannelSplitter(2);\n this._merge = this.ac.createChannelMerger(2);\n\n this._leftGain = this.ac.createGain();\n this._rightGain = this.ac.createGain();\n\n /**\n * The p5.Delay is built with two\n * \n * Web Audio Delay Nodes, one for each stereo channel.\n *\n * @property {DelayNode} leftDelay\n */\n this.leftDelay = this.ac.createDelay();\n /**\n * The p5.Delay is built with two\n * \n * Web Audio Delay Nodes, one for each stereo channel.\n *\n * @property {DelayNode} rightDelay\n */\n this.rightDelay = this.ac.createDelay();\n\n this._leftFilter = new Filter();\n this._rightFilter = new Filter();\n this._leftFilter.disconnect();\n this._rightFilter.disconnect();\n\n this._leftFilter.biquad.frequency.setValueAtTime(1200, this.ac.currentTime);\n this._rightFilter.biquad.frequency.setValueAtTime(1200, this.ac.currentTime);\n this._leftFilter.biquad.Q.setValueAtTime(0.3, this.ac.currentTime);\n this._rightFilter.biquad.Q.setValueAtTime(0.3, this.ac.currentTime);\n\n // graph routing\n this.input.connect(this._split);\n this.leftDelay.connect(this._leftGain);\n this.rightDelay.connect(this._rightGain);\n this._leftGain.connect(this._leftFilter.input);\n this._rightGain.connect(this._rightFilter.input);\n this._merge.connect(this.wet);\n\n\n this._leftFilter.biquad.gain.setValueAtTime(1, this.ac.currentTime);\n this._rightFilter.biquad.gain.setValueAtTime(1, this.ac.currentTime);\n\n // default routing\n this.setType(0);\n\n this._maxDelay = this.leftDelay.delayTime.maxValue;\n\n // set initial feedback to 0.5\n this.feedback(0.5);\n\n\n };\n\n p5.Delay.prototype = Object.create(Effect.prototype);\n /**\n * Add delay to an audio signal according to a set\n * of delay parameters.\n *\n * @method process\n * @for p5.Delay\n * @param {Object} Signal An object that outputs audio\n * @param {Number} [delayTime] Time (in seconds) of the delay/echo.\n * Some browsers limit delayTime to\n * 1 second.\n * @param {Number} [feedback] sends the delay back through itself\n * in a loop that decreases in volume\n * each time.\n * @param {Number} [lowPass] Cutoff frequency. Only frequencies\n * below the lowPass will be part of the\n * delay.\n */\n p5.Delay.prototype.process = function(src, _delayTime, _feedback, _filter) {\n var feedback = _feedback || 0;\n var delayTime = _delayTime || 0;\n if (feedback >= 1.0) {\n throw new Error('Feedback value will force a positive feedback loop.');\n }\n if (delayTime >= this._maxDelay) {\n throw new Error('Delay Time exceeds maximum delay time of ' + this._maxDelay + ' second.');\n }\n\n src.connect(this.input);\n this.leftDelay.delayTime.setValueAtTime(delayTime, this.ac.currentTime);\n this.rightDelay.delayTime.setValueAtTime(delayTime, this.ac.currentTime);\n this._leftGain.gain.value = feedback;\n this._rightGain.gain.value = feedback;\n\n if (_filter) {\n this._leftFilter.freq(_filter);\n this._rightFilter.freq(_filter);\n }\n };\n\n /**\n * Set the delay (echo) time, in seconds. Usually this value will be\n * a floating point number between 0.0 and 1.0.\n *\n * @method delayTime\n * @for p5.Delay\n * @param {Number} delayTime Time (in seconds) of the delay\n */\n p5.Delay.prototype.delayTime = function(t) {\n // if t is an audio node...\n if (typeof t !== 'number') {\n t.connect(this.leftDelay.delayTime);\n t.connect(this.rightDelay.delayTime);\n }\n\n else {\n this.leftDelay.delayTime.cancelScheduledValues(this.ac.currentTime);\n this.rightDelay.delayTime.cancelScheduledValues(this.ac.currentTime);\n this.leftDelay.delayTime.linearRampToValueAtTime(t, this.ac.currentTime);\n this.rightDelay.delayTime.linearRampToValueAtTime(t, this.ac.currentTime);\n }\n };\n\n /**\n * Feedback occurs when Delay sends its signal back through its input\n * in a loop. The feedback amount determines how much signal to send each\n * time through the loop. A feedback greater than 1.0 is not desirable because\n * it will increase the overall output each time through the loop,\n * creating an infinite feedback loop. The default value is 0.5\n *\n * @method feedback\n * @for p5.Delay\n * @param {Number|Object} feedback 0.0 to 1.0, or an object such as an\n * Oscillator that can be used to\n * modulate this param\n * @returns {Number} Feedback value\n *\n */\n p5.Delay.prototype.feedback = function(f) {\n // if f is an audio node...\n if (f && typeof f !== 'number') {\n f.connect(this._leftGain.gain);\n f.connect(this._rightGain.gain);\n }\n else if (f >= 1.0) {\n throw new Error('Feedback value will force a positive feedback loop.');\n }\n else if (typeof f === 'number') {\n this._leftGain.gain.value = f;\n this._rightGain.gain.value = f;\n }\n\n // return value of feedback\n return this._leftGain.gain.value;\n };\n\n /**\n * Set a lowpass filter frequency for the delay. A lowpass filter\n * will cut off any frequencies higher than the filter frequency.\n *\n * @method filter\n * @for p5.Delay\n * @param {Number|Object} cutoffFreq A lowpass filter will cut off any\n * frequencies higher than the filter frequency.\n * @param {Number|Object} res Resonance of the filter frequency\n * cutoff, or an object (i.e. a p5.Oscillator)\n * that can be used to modulate this parameter.\n * High numbers (i.e. 15) will produce a resonance,\n * low numbers (i.e. .2) will produce a slope.\n */\n p5.Delay.prototype.filter = function(freq, q) {\n this._leftFilter.set(freq, q);\n this._rightFilter.set(freq, q);\n };\n\n\n /**\n * Choose a preset type of delay. 'pingPong' bounces the signal\n * from the left to the right channel to produce a stereo effect.\n * Any other parameter will revert to the default delay setting.\n *\n * @method setType\n * @for p5.Delay\n * @param {String|Number} type 'pingPong' (1) or 'default' (0)\n */\n p5.Delay.prototype.setType = function(t) {\n if (t === 1) {\n t = 'pingPong';\n }\n this._split.disconnect();\n this._leftFilter.disconnect();\n this._rightFilter.disconnect();\n this._split.connect(this.leftDelay, 0);\n this._split.connect(this.rightDelay, 1);\n switch(t) {\n case 'pingPong':\n this._rightFilter.setType( this._leftFilter.biquad.type );\n this._leftFilter.output.connect(this._merge, 0, 0);\n this._rightFilter.output.connect(this._merge, 0, 1);\n this._leftFilter.output.connect(this.rightDelay);\n this._rightFilter.output.connect(this.leftDelay);\n break;\n default:\n this._leftFilter.output.connect(this._merge, 0, 0);\n this._rightFilter.output.connect(this._merge, 0, 1);\n this._leftFilter.output.connect(this.leftDelay);\n this._rightFilter.output.connect(this.rightDelay);\n }\n };\n\n // DocBlocks for methods inherited from p5.Effect\n /**\n * Set the output level of the delay effect.\n *\n * @method amp\n * @for p5.Delay\n * @param {Number} volume amplitude between 0 and 1.0\n * @param {Number} [rampTime] create a fade that lasts rampTime\n * @param {Number} [timeFromNow] schedule this event to happen\n * seconds from now\n */\n /**\n * Send output to a p5.sound or web audio object\n *\n * @method connect\n * @for p5.Delay\n * @param {Object} unit\n */\n /**\n * Disconnect all output.\n *\n * @method disconnect\n * @for p5.Delay\n */\n\n p5.Delay.prototype.dispose = function() {\n\n Effect.prototype.dispose.apply(this);\n\n this._split.disconnect();\n this._leftFilter.dispose();\n this._rightFilter.dispose();\n this._merge.disconnect();\n this._leftGain.disconnect();\n this._rightGain.disconnect();\n this.leftDelay.disconnect();\n this.rightDelay.disconnect();\n\n this._split = undefined;\n this._leftFilter = undefined;\n this._rightFilter = undefined;\n this._merge = undefined;\n this._leftGain = undefined;\n this._rightGain = undefined;\n this.leftDelay = undefined;\n this.rightDelay = undefined;\n };\n\n});\n","'use strict';\n\ndefine(function (require) {\n var CustomError = require('errorHandler');\n var Effect = require('effect');\n\n /**\n * Reverb adds depth to a sound through a large number of decaying\n * echoes. It creates the perception that sound is occurring in a\n * physical space. The p5.Reverb has paramters for Time (how long does the\n * reverb last) and decayRate (how much the sound decays with each echo)\n * that can be set with the .set() or .process() methods. The p5.Convolver\n * extends p5.Reverb allowing you to recreate the sound of actual physical\n * spaces through convolution.\n *\n * This class extends p5.Effect.\n * Methods amp(), chain(),\n * drywet(), connect(), and\n * disconnect() are available.\n *\n * @class p5.Reverb\n * @extends p5.Effect\n * @constructor\n * @example\n *
\n * var soundFile, reverb;\n * function preload() {\n * soundFile = loadSound('assets/Damscray_DancingTiger.mp3');\n * }\n *\n * function setup() {\n * reverb = new p5.Reverb();\n * soundFile.disconnect(); // so we'll only hear reverb...\n *\n * // connect soundFile to reverb, process w/\n * // 3 second reverbTime, decayRate of 2%\n * reverb.process(soundFile, 3, 2);\n * soundFile.play();\n * }\n *
\n */\n\n\n p5.Reverb = function() {\n Effect.call(this);\n\n this._initConvolverNode();\n\n // otherwise, Safari distorts\n this.input.gain.value = 0.5;\n\n // default params\n this._seconds = 3;\n this._decay = 2;\n this._reverse = false;\n\n this._buildImpulse();\n\n };\n\n p5.Reverb.prototype = Object.create(Effect.prototype);\n\n p5.Reverb.prototype._initConvolverNode = function() {\n this.convolverNode = this.ac.createConvolver();\n this.input.connect(this.convolverNode);\n this.convolverNode.connect(this.wet);\n };\n\n p5.Reverb.prototype._teardownConvolverNode = function() {\n if (this.convolverNode) {\n this.convolverNode.disconnect();\n delete this.convolverNode;\n }\n };\n\n p5.Reverb.prototype._setBuffer = function(audioBuffer) {\n this._teardownConvolverNode();\n this._initConvolverNode();\n this.convolverNode.buffer = audioBuffer;\n };\n /**\n * Connect a source to the reverb, and assign reverb parameters.\n *\n * @method process\n * @for p5.Reverb\n * @param {Object} src p5.sound / Web Audio object with a sound\n * output.\n * @param {Number} [seconds] Duration of the reverb, in seconds.\n * Min: 0, Max: 10. Defaults to 3.\n * @param {Number} [decayRate] Percentage of decay with each echo.\n * Min: 0, Max: 100. Defaults to 2.\n * @param {Boolean} [reverse] Play the reverb backwards or forwards.\n */\n p5.Reverb.prototype.process = function(src, seconds, decayRate, reverse) {\n src.connect(this.input);\n var rebuild = false;\n if (seconds) {\n this._seconds = seconds;\n rebuild = true;\n }\n if (decayRate) {\n this._decay = decayRate;\n }\n if (reverse) {\n this._reverse = reverse;\n }\n if (rebuild) {\n this._buildImpulse();\n }\n };\n\n /**\n * Set the reverb settings. Similar to .process(), but without\n * assigning a new input.\n *\n * @method set\n * @for p5.Reverb\n * @param {Number} [seconds] Duration of the reverb, in seconds.\n * Min: 0, Max: 10. Defaults to 3.\n * @param {Number} [decayRate] Percentage of decay with each echo.\n * Min: 0, Max: 100. Defaults to 2.\n * @param {Boolean} [reverse] Play the reverb backwards or forwards.\n */\n p5.Reverb.prototype.set = function(seconds, decayRate, reverse) {\n var rebuild = false;\n if (seconds) {\n this._seconds = seconds;\n rebuild = true;\n }\n if (decayRate) {\n this._decay = decayRate;\n }\n if (reverse) {\n this._reverse = reverse;\n }\n if (rebuild) {\n this._buildImpulse();\n }\n };\n\n // DocBlocks for methods inherited from p5.Effect\n /**\n * Set the output level of the reverb effect.\n *\n * @method amp\n * @for p5.Reverb\n * @param {Number} volume amplitude between 0 and 1.0\n * @param {Number} [rampTime] create a fade that lasts rampTime\n * @param {Number} [timeFromNow] schedule this event to happen\n * seconds from now\n */\n /**\n * Send output to a p5.sound or web audio object\n *\n * @method connect\n * @for p5.Reverb\n * @param {Object} unit\n */\n /**\n * Disconnect all output.\n *\n * @method disconnect\n * @for p5.Reverb\n */\n\n /**\n * Inspired by Simple Reverb by Jordan Santell\n * https://github.com/web-audio-components/simple-reverb/blob/master/index.js\n *\n * Utility function for building an impulse response\n * based on the module parameters.\n *\n * @private\n */\n p5.Reverb.prototype._buildImpulse = function() {\n var rate = this.ac.sampleRate;\n var length = rate*this._seconds;\n var decay = this._decay;\n var impulse = this.ac.createBuffer(2, length, rate);\n var impulseL = impulse.getChannelData(0);\n var impulseR = impulse.getChannelData(1);\n var n, i;\n for (i = 0; i < length; i++) {\n n = this._reverse ? length - i : i;\n impulseL[i] = (Math.random() * 2 - 1) * Math.pow(1 - n / length, decay);\n impulseR[i] = (Math.random() * 2 - 1) * Math.pow(1 - n / length, decay);\n }\n this._setBuffer(impulse);\n };\n\n p5.Reverb.prototype.dispose = function() {\n Effect.prototype.dispose.apply(this);\n this._teardownConvolverNode();\n };\n\n // =======================================================================\n // *** p5.Convolver ***\n // =======================================================================\n\n /**\n *
p5.Convolver extends p5.Reverb. It can emulate the sound of real\n * physical spaces through a process called \n * convolution.
\n *\n *
Convolution multiplies any audio input by an \"impulse response\"\n * to simulate the dispersion of sound over time. The impulse response is\n * generated from an audio file that you provide. One way to\n * generate an impulse response is to pop a balloon in a reverberant space\n * and record the echo. Convolution can also be used to experiment with\n * sound.
\n *\n *
Use the method createConvolution(path) to instantiate a\n * p5.Convolver with a path to your impulse response audio file.
\n *\n * @class p5.Convolver\n * @extends p5.Effect\n * @constructor\n * @param {String} path path to a sound file\n * @param {Function} [callback] function to call when loading succeeds\n * @param {Function} [errorCallback] function to call if loading fails.\n * This function will receive an error or\n * XMLHttpRequest object with information\n * about what went wrong.\n * @example\n *
\n * var cVerb, sound;\n * function preload() {\n * // We have both MP3 and OGG versions of all sound assets\n * soundFormats('ogg', 'mp3');\n *\n * // Try replacing 'bx-spring' with other soundfiles like\n * // 'concrete-tunnel' 'small-plate' 'drum' 'beatbox'\n * cVerb = createConvolver('assets/bx-spring.mp3');\n *\n * // Try replacing 'Damscray_DancingTiger' with\n * // 'beat', 'doorbell', lucky_dragons_-_power_melody'\n * sound = loadSound('assets/Damscray_DancingTiger.mp3');\n * }\n *\n * function setup() {\n * // disconnect from master output...\n * sound.disconnect();\n *\n * // ...and process with cVerb\n * // so that we only hear the convolution\n * cVerb.process(sound);\n *\n * sound.play();\n * }\n *
\n */\n p5.Convolver = function(path, callback, errorCallback) {\n \t p5.Reverb.call(this);\n\n /**\n * Internally, the p5.Convolver uses the a\n * \n * Web Audio Convolver Node.\n *\n * @property {ConvolverNode} convolverNode\n */\n this._initConvolverNode();\n\n // otherwise, Safari distorts\n this.input.gain.value = 0.5;\n\n if (path) {\n this.impulses = [];\n this._loadBuffer(path, callback, errorCallback);\n }\n else {\n // parameters\n this._seconds = 3;\n this._decay = 2;\n this._reverse = false;\n\n this._buildImpulse();\n }\n\n };\n\n p5.Convolver.prototype = Object.create(p5.Reverb.prototype);\n\n p5.prototype.registerPreloadMethod('createConvolver', p5.prototype);\n\n /**\n * Create a p5.Convolver. Accepts a path to a soundfile\n * that will be used to generate an impulse response.\n *\n * @method createConvolver\n * @for p5\n * @param {String} path path to a sound file\n * @param {Function} [callback] function to call if loading is successful.\n * The object will be passed in as the argument\n * to the callback function.\n * @param {Function} [errorCallback] function to call if loading is not successful.\n * A custom error will be passed in as the argument\n * to the callback function.\n * @return {p5.Convolver}\n * @example\n *
\n * var cVerb, sound;\n * function preload() {\n * // We have both MP3 and OGG versions of all sound assets\n * soundFormats('ogg', 'mp3');\n *\n * // Try replacing 'bx-spring' with other soundfiles like\n * // 'concrete-tunnel' 'small-plate' 'drum' 'beatbox'\n * cVerb = createConvolver('assets/bx-spring.mp3');\n *\n * // Try replacing 'Damscray_DancingTiger' with\n * // 'beat', 'doorbell', lucky_dragons_-_power_melody'\n * sound = loadSound('assets/Damscray_DancingTiger.mp3');\n * }\n *\n * function setup() {\n * // disconnect from master output...\n * sound.disconnect();\n *\n * // ...and process with cVerb\n * // so that we only hear the convolution\n * cVerb.process(sound);\n *\n * sound.play();\n * }\n *
\n */\n p5.prototype.createConvolver = function(path, callback, errorCallback) {\n // if loading locally without a server\n if (window.location.origin.indexOf('file://') > -1 && window.cordova === 'undefined') {\n alert('This sketch may require a server to load external files. Please see http://bit.ly/1qcInwS');\n }\n var self = this;\n var cReverb = new p5.Convolver(path, function(buffer) {\n if (typeof callback === 'function') {\n callback(buffer);\n }\n\n if (typeof self._decrementPreload === 'function') {\n self._decrementPreload();\n }\n }, errorCallback);\n cReverb.impulses = [];\n return cReverb;\n };\n\n /**\n * Private method to load a buffer as an Impulse Response,\n * assign it to the convolverNode, and add to the Array of .impulses.\n *\n * @param {String} path\n * @param {Function} callback\n * @param {Function} errorCallback\n * @private\n */\n p5.Convolver.prototype._loadBuffer = function(path, callback, errorCallback) {\n var path = p5.prototype._checkFileFormats(path);\n var self = this;\n var errorTrace = new Error().stack;\n var ac = p5.prototype.getAudioContext();\n\n var request = new XMLHttpRequest();\n request.open('GET', path, true);\n request.responseType = 'arraybuffer';\n\n request.onload = function() {\n if (request.status === 200) {\n // on success loading file:\n ac.decodeAudioData(request.response,\n function(buff) {\n var buffer = {};\n var chunks = path.split('/');\n buffer.name = chunks[chunks.length - 1];\n buffer.audioBuffer = buff;\n self.impulses.push(buffer);\n self._setBuffer(buffer.audioBuffer);\n if (callback) {\n callback(buffer);\n }\n },\n // error decoding buffer. \"e\" is undefined in Chrome 11/22/2015\n function() {\n var err = new CustomError('decodeAudioData', errorTrace, self.url);\n var msg = 'AudioContext error at decodeAudioData for ' + self.url;\n if (errorCallback) {\n err.msg = msg;\n errorCallback(err);\n } else {\n console.error(msg +'\\n The error stack trace includes: \\n' + err.stack);\n }\n }\n );\n }\n // if request status != 200, it failed\n else {\n var err = new CustomError('loadConvolver', errorTrace, self.url);\n var msg = 'Unable to load ' + self.url +\n '. The request status was: ' + request.status + ' (' + request.statusText + ')';\n\n if (errorCallback) {\n err.message = msg;\n errorCallback(err);\n } else {\n console.error(msg +'\\n The error stack trace includes: \\n' + err.stack);\n }\n }\n };\n\n // if there is another error, aside from 404...\n request.onerror = function() {\n var err = new CustomError('loadConvolver', errorTrace, self.url);\n var msg = 'There was no response from the server at ' + self.url + '. Check the url and internet connectivity.';\n\n if (errorCallback) {\n err.message = msg;\n errorCallback(err);\n } else {\n console.error(msg +'\\n The error stack trace includes: \\n' + err.stack);\n }\n };\n request.send();\n };\n\n p5.Convolver.prototype.set = null;\n\n /**\n * Connect a source to the reverb, and assign reverb parameters.\n *\n * @method process\n * @for p5.Convolver\n * @param {Object} src p5.sound / Web Audio object with a sound\n * output.\n * @example\n *
\n * var cVerb, sound;\n * function preload() {\n * soundFormats('ogg', 'mp3');\n *\n * cVerb = createConvolver('assets/concrete-tunnel.mp3');\n *\n * sound = loadSound('assets/beat.mp3');\n * }\n *\n * function setup() {\n * // disconnect from master output...\n * sound.disconnect();\n *\n * // ...and process with (i.e. connect to) cVerb\n * // so that we only hear the convolution\n * cVerb.process(sound);\n *\n * sound.play();\n * }\n *
\n */\n p5.Convolver.prototype.process = function(src) {\n src.connect(this.input);\n };\n\n /**\n * If you load multiple impulse files using the .addImpulse method,\n * they will be stored as Objects in this Array. Toggle between them\n * with the toggleImpulse(id) method.\n *\n * @property {Array} impulses\n * @for p5.Convolver\n */\n p5.Convolver.prototype.impulses = [];\n\n /**\n * Load and assign a new Impulse Response to the p5.Convolver.\n * The impulse is added to the .impulses array. Previous\n * impulses can be accessed with the .toggleImpulse(id)\n * method.\n *\n * @method addImpulse\n * @for p5.Convolver\n * @param {String} path path to a sound file\n * @param {Function} callback function (optional)\n * @param {Function} errorCallback function (optional)\n */\n p5.Convolver.prototype.addImpulse = function(path, callback, errorCallback) {\n // if loading locally without a server\n if (window.location.origin.indexOf('file://') > -1 && window.cordova === 'undefined') {\n alert('This sketch may require a server to load external files. Please see http://bit.ly/1qcInwS');\n }\n this._loadBuffer(path, callback, errorCallback);\n };\n\n /**\n * Similar to .addImpulse, except that the .impulses\n * Array is reset to save memory. A new .impulses\n * array is created with this impulse as the only item.\n *\n * @method resetImpulse\n * @for p5.Convolver\n * @param {String} path path to a sound file\n * @param {Function} callback function (optional)\n * @param {Function} errorCallback function (optional)\n */\n p5.Convolver.prototype.resetImpulse = function(path, callback, errorCallback) {\n // if loading locally without a server\n if (window.location.origin.indexOf('file://') > -1 && window.cordova === 'undefined') {\n alert('This sketch may require a server to load external files. Please see http://bit.ly/1qcInwS');\n }\n this.impulses = [];\n this._loadBuffer(path, callback, errorCallback);\n };\n\n /**\n * If you have used .addImpulse() to add multiple impulses\n * to a p5.Convolver, then you can use this method to toggle between\n * the items in the .impulses Array. Accepts a parameter\n * to identify which impulse you wish to use, identified either by its\n * original filename (String) or by its position in the .impulses\n * Array (Number). \n * You can access the objects in the .impulses Array directly. Each\n * Object has two attributes: an .audioBuffer (type:\n * Web Audio \n * AudioBuffer) and a .name, a String that corresponds\n * with the original filename.\n *\n * @method toggleImpulse\n * @for p5.Convolver\n * @param {String|Number} id Identify the impulse by its original filename\n * (String), or by its position in the\n * .impulses Array (Number).\n */\n p5.Convolver.prototype.toggleImpulse = function(id) {\n if (typeof id === 'number' && id < this.impulses.length) {\n this._setBuffer(this.impulses[id].audioBuffer);\n }\n if (typeof id === 'string') {\n for (var i = 0; i < this.impulses.length; i++) {\n if (this.impulses[i].name === id) {\n this._setBuffer(this.impulses[i].audioBuffer);\n break;\n }\n }\n }\n };\n\n p5.Convolver.prototype.dispose = function() {\n p5.Reverb.prototype.dispose.apply(this);\n\n // remove all the Impulse Response buffers\n for (var i in this.impulses) {\n if (this.impulses[i]) {\n this.impulses[i] = null;\n }\n }\n };\n\n});\n","'use strict';\n\ndefine(function (require) {\n var p5sound = require('master');\n\n // requires the Tone.js library's Clock (MIT license, Yotam Mann)\n // https://github.com/TONEnoTONE/Tone.js/\n var Clock = require('Tone/core/Clock');\n\n p5.Metro = function() {\n this.clock = new Clock({\n 'callback': this.ontick.bind(this)\n });\n this.syncedParts = [];\n this.bpm = 120; // gets overridden by p5.Part\n this._init();\n\n this.prevTick = 0;\n this.tatumTime = 0;\n\n this.tickCallback = function() {};\n };\n\n p5.Metro.prototype.ontick = function(tickTime) {\n var elapsedTime = tickTime - this.prevTick;\n var secondsFromNow = tickTime - p5sound.audiocontext.currentTime;\n if (elapsedTime - this.tatumTime <= -0.02) {\n return;\n } else {\n // console.log('ok', this.syncedParts[0].phrases[0].name);\n this.prevTick = tickTime;\n\n // for all of the active things on the metro:\n var self = this;\n this.syncedParts.forEach(function(thisPart) {\n if (!thisPart.isPlaying) return;\n thisPart.incrementStep(secondsFromNow);\n // each synced source keeps track of its own beat number\n thisPart.phrases.forEach(function(thisPhrase) {\n var phraseArray = thisPhrase.sequence;\n var bNum = self.metroTicks % phraseArray.length;\n if (phraseArray[bNum] !== 0 && (self.metroTicks < phraseArray.length || !thisPhrase.looping) ) {\n thisPhrase.callback(secondsFromNow, phraseArray[bNum]);\n }\n });\n });\n this.metroTicks += 1;\n this.tickCallback(secondsFromNow);\n }\n };\n\n p5.Metro.prototype.setBPM = function(bpm, rampTime) {\n var beatTime = 60 / (bpm*this.tatums);\n var now = p5sound.audiocontext.currentTime;\n this.tatumTime = beatTime;\n\n var rampTime = rampTime || 0;\n this.clock.frequency.setValueAtTime(this.clock.frequency.value, now);\n this.clock.frequency.linearRampToValueAtTime(bpm, now + rampTime);\n this.bpm = bpm;\n };\n\n p5.Metro.prototype.getBPM = function() {\n return this.clock.getRate() / this.tatums * 60;\n };\n\n p5.Metro.prototype._init = function() {\n this.metroTicks = 0;\n // this.setBPM(120);\n };\n\n // clear existing synced parts, add only this one\n p5.Metro.prototype.resetSync = function(part) {\n this.syncedParts = [part];\n };\n\n // push a new synced part to the array\n p5.Metro.prototype.pushSync = function(part) {\n this.syncedParts.push(part);\n };\n\n p5.Metro.prototype.start = function(timeFromNow) {\n var t = timeFromNow || 0;\n var now = p5sound.audiocontext.currentTime;\n this.clock.start(now + t);\n this.setBPM(this.bpm);\n };\n\n p5.Metro.prototype.stop = function(timeFromNow) {\n var t = timeFromNow || 0;\n var now = p5sound.audiocontext.currentTime;\n this.clock.stop(now + t);\n };\n\n p5.Metro.prototype.beatLength = function(tatums) {\n this.tatums = 1/tatums / 4; // lowest possible division of a beat\n };\n\n});\n","define([\"Tone/core/Tone\", \"Tone/core/Timeline\", \"Tone/type/Type\"], function (Tone) {\n\n\t\"use strict\";\n\n\t/**\n\t * @class A Timeline State. Provides the methods: setStateAtTime(\"state\", time)\n\t * and getValueAtTime(time).\n\t *\n\t * @extends {Tone.Timeline}\n\t * @param {String} initial The initial state of the TimelineState. \n\t * Defaults to undefined\n\t */\n\tTone.TimelineState = function(initial){\n\n\t\tTone.Timeline.call(this);\n\n\t\t/**\n\t\t * The initial state\n\t\t * @private\n\t\t * @type {String}\n\t\t */\n\t\tthis._initial = initial;\n\t};\n\n\tTone.extend(Tone.TimelineState, Tone.Timeline);\n\n\t/**\n\t * Returns the scheduled state scheduled before or at\n\t * the given time.\n\t * @param {Number} time The time to query.\n\t * @return {String} The name of the state input in setStateAtTime.\n\t */\n\tTone.TimelineState.prototype.getValueAtTime = function(time){\n\t\tvar event = this.get(time);\n\t\tif (event !== null){\n\t\t\treturn event.state;\n\t\t} else {\n\t\t\treturn this._initial;\n\t\t}\n\t};\n\n\t/**\n\t * Returns the scheduled state scheduled before or at\n\t * the given time.\n\t * @param {String} state The name of the state to set.\n\t * @param {Number} time The time to query.\n\t */\n\tTone.TimelineState.prototype.setStateAtTime = function(state, time){\n\t\tthis.add({\n\t\t\t\"state\" : state,\n\t\t\t\"time\" : time\n\t\t});\n\t};\n\n\treturn Tone.TimelineState;\n});","'use strict';\n\ndefine(function(require) {\n var p5sound = require('master');\n\n var BPM = 120;\n\n /**\n * Set the global tempo, in beats per minute, for all\n * p5.Parts. This method will impact all active p5.Parts.\n *\n * @method setBPM\n * @for p5\n * @param {Number} BPM Beats Per Minute\n * @param {Number} rampTime Seconds from now\n */\n p5.prototype.setBPM = function(bpm, rampTime) {\n BPM = bpm;\n for (var i in p5sound.parts) {\n if (p5sound.parts[i]) {\n p5sound.parts[i].setBPM(bpm, rampTime);\n }\n }\n };\n\n /**\n *
A phrase is a pattern of musical events over time, i.e.\n * a series of notes and rests.
\n *\n *
Phrases must be added to a p5.Part for playback, and\n * each part can play multiple phrases at the same time.\n * For example, one Phrase might be a kick drum, another\n * could be a snare, and another could be the bassline.
\n *\n *
The first parameter is a name so that the phrase can be\n * modified or deleted later. The callback is a a function that\n * this phrase will call at every step—for example it might be\n * called playNote(value){}. The array determines\n * which value is passed into the callback at each step of the\n * phrase. It can be numbers, an object with multiple numbers,\n * or a zero (0) indicates a rest so the callback won't be called).
\n *\n * @class p5.Phrase\n * @constructor\n * @param {String} name Name so that you can access the Phrase.\n * @param {Function} callback The name of a function that this phrase\n * will call. Typically it will play a sound,\n * and accept two parameters: a time at which\n * to play the sound (in seconds from now),\n * and a value from the sequence array. The\n * time should be passed into the play() or\n * start() method to ensure precision.\n * @param {Array} sequence Array of values to pass into the callback\n * at each step of the phrase.\n * @example\n *
\n */\n p5.Phrase = function(name, callback, sequence) {\n this.phraseStep = 0;\n this.name = name;\n this.callback = callback;\n /**\n * Array of values to pass into the callback\n * at each step of the phrase. Depending on the callback\n * function's requirements, these values may be numbers,\n * strings, or an object with multiple parameters.\n * Zero (0) indicates a rest.\n *\n * @property {Array} sequence\n */\n this.sequence = sequence;\n };\n\n /**\n *
A p5.Part plays back one or more p5.Phrases. Instantiate a part\n * with steps and tatums. By default, each step represents a 1/16th note.
\n *\n *
See p5.Phrase for more about musical timing.
\n *\n * @class p5.Part\n * @constructor\n * @param {Number} [steps] Steps in the part\n * @param {Number} [tatums] Divisions of a beat, e.g. use 1/4, or 0.25 for a quater note (default is 1/16, a sixteenth note)\n * @example\n *
\n * var box, drum, myPart;\n * var boxPat = [1,0,0,2,0,2,0,0];\n * var drumPat = [0,1,1,0,2,0,1,0];\n * var msg = 'click to play';\n *\n * function preload() {\n * box = loadSound('assets/beatbox.mp3');\n * drum = loadSound('assets/drum.mp3');\n * }\n *\n * function setup() {\n * noStroke();\n * fill(255);\n * textAlign(CENTER);\n * masterVolume(0.1);\n *\n * var boxPhrase = new p5.Phrase('box', playBox, boxPat);\n * var drumPhrase = new p5.Phrase('drum', playDrum, drumPat);\n * myPart = new p5.Part();\n * myPart.addPhrase(boxPhrase);\n * myPart.addPhrase(drumPhrase);\n * myPart.setBPM(60);\n * masterVolume(0.1);\n * }\n *\n * function draw() {\n * background(0);\n * text(msg, width/2, height/2);\n * }\n *\n * function playBox(time, playbackRate) {\n * box.rate(playbackRate);\n * box.play(time);\n * }\n *\n * function playDrum(time, playbackRate) {\n * drum.rate(playbackRate);\n * drum.play(time);\n * }\n *\n * function mouseClicked() {\n * if (mouseX > 0 && mouseX < width && mouseY > 0 && mouseY < height) {\n * myPart.start();\n * msg = 'playing part';\n * }\n * }\n *
\n */\n p5.Part = function(steps, bLength) {\n this.length = steps || 0; // how many beats\n this.partStep = 0;\n this.phrases = [];\n this.isPlaying = false;\n this.noLoop();\n this.tatums = bLength || 0.0625; // defaults to quarter note\n\n this.metro = new p5.Metro();\n this.metro._init();\n this.metro.beatLength(this.tatums);\n this.metro.setBPM(BPM);\n p5sound.parts.push(this);\n this.callback = function() {};\n };\n\n /**\n * Set the tempo of this part, in Beats Per Minute.\n *\n * @method setBPM\n * @for p5.Part\n * @param {Number} BPM Beats Per Minute\n * @param {Number} [rampTime] Seconds from now\n */\n p5.Part.prototype.setBPM = function(tempo, rampTime) {\n this.metro.setBPM(tempo, rampTime);\n };\n\n /**\n * Returns the tempo, in Beats Per Minute, of this part.\n *\n * @method getBPM\n * @for p5.Part\n * @return {Number}\n */\n p5.Part.prototype.getBPM = function() {\n return this.metro.getBPM();\n };\n\n /**\n * Start playback of this part. It will play\n * through all of its phrases at a speed\n * determined by setBPM.\n *\n * @method start\n * @for p5.Part\n * @param {Number} [time] seconds from now\n */\n p5.Part.prototype.start = function(time) {\n if (!this.isPlaying) {\n this.isPlaying = true;\n this.metro.resetSync(this);\n var t = time || 0;\n this.metro.start(t);\n }\n };\n\n /**\n * Loop playback of this part. It will begin\n * looping through all of its phrases at a speed\n * determined by setBPM.\n *\n * @method loop\n * @for p5.Part\n * @param {Number} [time] seconds from now\n */\n p5.Part.prototype.loop = function(time) {\n this.looping = true;\n // rest onended function\n this.onended = function() {\n this.partStep = 0;\n };\n var t = time || 0;\n this.start(t);\n };\n\n /**\n * Tell the part to stop looping.\n *\n * @method noLoop\n * @for p5.Part\n */\n p5.Part.prototype.noLoop = function() {\n this.looping = false;\n // rest onended function\n this.onended = function() {\n this.stop();\n };\n };\n\n /**\n * Stop the part and cue it to step 0. Playback will resume from the begining of the Part when it is played again.\n *\n * @method stop\n * @for p5.Part\n * @param {Number} [time] seconds from now\n */\n p5.Part.prototype.stop = function(time) {\n this.partStep = 0;\n this.pause(time);\n };\n\n /**\n * Pause the part. Playback will resume\n * from the current step.\n *\n * @method pause\n * @for p5.Part\n * @param {Number} time seconds from now\n */\n p5.Part.prototype.pause = function(time) {\n this.isPlaying = false;\n var t = time || 0;\n this.metro.stop(t);\n };\n\n /**\n * Add a p5.Phrase to this Part.\n *\n * @method addPhrase\n * @for p5.Part\n * @param {p5.Phrase} phrase reference to a p5.Phrase\n */\n p5.Part.prototype.addPhrase = function(name, callback, array) {\n var p;\n if (arguments.length === 3) {\n p = new p5.Phrase(name, callback, array);\n } else if (arguments[0] instanceof p5.Phrase) {\n p = arguments[0];\n } else {\n throw 'invalid input. addPhrase accepts name, callback, array or a p5.Phrase';\n }\n this.phrases.push(p);\n // reset the length if phrase is longer than part's existing length\n if (p.sequence.length > this.length) {\n this.length = p.sequence.length;\n }\n };\n\n /**\n * Remove a phrase from this part, based on the name it was\n * given when it was created.\n *\n * @method removePhrase\n * @for p5.Part\n * @param {String} phraseName\n */\n p5.Part.prototype.removePhrase = function(name) {\n for (var i in this.phrases) {\n if (this.phrases[i].name === name) {\n this.phrases.splice(i, 1);\n }\n }\n };\n\n /**\n * Get a phrase from this part, based on the name it was\n * given when it was created. Now you can modify its array.\n *\n * @method getPhrase\n * @for p5.Part\n * @param {String} phraseName\n */\n p5.Part.prototype.getPhrase = function(name) {\n for (var i in this.phrases) {\n if (this.phrases[i].name === name) {\n return this.phrases[i];\n }\n }\n };\n\n /**\n * Find all sequences with the specified name, and replace their patterns with the specified array.\n *\n * @method replaceSequence\n * @for p5.Part\n * @param {String} phraseName\n * @param {Array} sequence Array of values to pass into the callback\n * at each step of the phrase.\n */\n p5.Part.prototype.replaceSequence = function(name, array) {\n for (var i in this.phrases) {\n if (this.phrases[i].name === name) {\n this.phrases[i].sequence = array;\n }\n }\n };\n\n p5.Part.prototype.incrementStep = function(time) {\n if (this.partStep < this.length - 1) {\n this.callback(time);\n this.partStep += 1;\n } else {\n if (!this.looping && this.partStep === this.length - 1) {\n console.log('done');\n // this.callback(time);\n this.onended();\n }\n }\n };\n\n /**\n * Set the function that will be called at every step. This will clear the previous function.\n *\n * @method onStep\n * @for p5.Part\n * @param {Function} callback The name of the callback\n * you want to fire\n * on every beat/tatum.\n */\n p5.Part.prototype.onStep = function(callback) {\n this.callback = callback;\n };\n\n\n // ===============\n // p5.Score\n // ===============\n\n /**\n * A Score consists of a series of Parts. The parts will\n * be played back in order. For example, you could have an\n * A part, a B part, and a C part, and play them back in this order\n * new p5.Score(a, a, b, a, c)\n *\n * @class p5.Score\n * @constructor\n * @param {p5.Part} [...parts] One or multiple parts, to be played in sequence.\n */\n p5.Score = function() {\n // for all of the arguments\n this.parts = [];\n this.currentPart = 0;\n\n var thisScore = this;\n for (var i in arguments) {\n if (arguments[i] && this.parts[i]) {\n this.parts[i] = arguments[i];\n this.parts[i].nextPart = this.parts[i + 1];\n this.parts[i].onended = function() {\n thisScore.resetPart(i);\n playNextPart(thisScore);\n };\n }\n }\n this.looping = false;\n };\n\n p5.Score.prototype.onended = function() {\n if (this.looping) {\n // this.resetParts();\n this.parts[0].start();\n } else {\n this.parts[this.parts.length - 1].onended = function() {\n this.stop();\n this.resetParts();\n };\n }\n this.currentPart = 0;\n };\n\n /**\n * Start playback of the score.\n *\n * @method start\n * @for p5.Score\n */\n p5.Score.prototype.start = function() {\n this.parts[this.currentPart].start();\n this.scoreStep = 0;\n };\n\n /**\n * Stop playback of the score.\n *\n * @method stop\n * @for p5.Score\n */\n p5.Score.prototype.stop = function() {\n this.parts[this.currentPart].stop();\n this.currentPart = 0;\n this.scoreStep = 0;\n };\n\n /**\n * Pause playback of the score.\n *\n * @method pause\n * @for p5.Score\n */\n p5.Score.prototype.pause = function() {\n this.parts[this.currentPart].stop();\n };\n\n /**\n * Loop playback of the score.\n *\n * @method loop\n * @for p5.Score\n */\n p5.Score.prototype.loop = function() {\n this.looping = true;\n this.start();\n };\n\n /**\n * Stop looping playback of the score. If it\n * is currently playing, this will go into effect\n * after the current round of playback completes.\n *\n * @method noLoop\n * @for p5.Score\n */\n p5.Score.prototype.noLoop = function() {\n this.looping = false;\n };\n\n p5.Score.prototype.resetParts = function() {\n var self = this;\n this.parts.forEach(function(part) {\n self.resetParts[part];\n });\n };\n\n p5.Score.prototype.resetPart = function(i) {\n this.parts[i].stop();\n this.parts[i].partStep = 0;\n for (var p in this.parts[i].phrases) {\n if (this.parts[i]) {\n this.parts[i].phrases[p].phraseStep = 0;\n }\n }\n };\n\n /**\n * Set the tempo for all parts in the score\n *\n * @method setBPM\n * @for p5.Score\n * @param {Number} BPM Beats Per Minute\n * @param {Number} rampTime Seconds from now\n */\n p5.Score.prototype.setBPM = function(bpm, rampTime) {\n for (var i in this.parts) {\n if (this.parts[i]) {\n this.parts[i].setBPM(bpm, rampTime);\n }\n }\n };\n\n function playNextPart(aScore) {\n aScore.currentPart++;\n if (aScore.currentPart >= aScore.parts.length) {\n aScore.scoreStep = 0;\n aScore.onended();\n } else {\n aScore.scoreStep = 0;\n aScore.parts[aScore.currentPart - 1].stop();\n aScore.parts[aScore.currentPart].start();\n }\n }\n\n});\n","'use strict';\n\ndefine(function (require) {\n var p5sound = require('master');\n var Clock = require('Tone/core/Clock');\n\n /**\n * SoundLoop\n *\n * @class p5.SoundLoop\n * @constructor\n *\n * @param {Function} callback this function will be called on each iteration of theloop\n * @param {Number|String} [interval] amount of time or beats for each iteration of the loop\n * defaults to 1\n *\n * @example\n *
\n * var click;\n * var looper1;\n *\n * function preload() {\n * click = loadSound('assets/drum.mp3');\n * }\n *\n * function setup() {\n * //the looper's callback is passed the timeFromNow\n * //this value should be used as a reference point from\n * //which to schedule sounds\n * looper1 = new p5.SoundLoop(function(timeFromNow){\n * click.play(timeFromNow);\n * background(255 * (looper1.iterations % 2));\n * }, 2);\n *\n * //stop after 10 iteratios;\n * looper1.maxIterations = 10;\n * //start the loop\n * looper1.start();\n * }\n *
\n */\n p5.SoundLoop = function(callback, interval) {\n this.callback = callback;\n /**\n * musicalTimeMode uses Tone.Time convention\n\t * true if string, false if number\n * @property {Boolean} musicalTimeMode\n */\n this.musicalTimeMode = typeof this._interval === 'number' ? false : true;\n\n this._interval = interval || 1;\n\n /**\n * musicalTimeMode variables\n * modify these only when the interval is specified in musicalTime format as a string\n */\n this._timeSignature = 4;\n this._bpm = 60;\n\n this.isPlaying = false;\n\n /**\n * Set a limit to the number of loops to play. defaults to Infinity\n * @property {Number} maxIterations\n */\n this.maxIterations = Infinity;\n var self = this;\n\n this.clock = new Clock({\n 'callback' : function(time) {\n var timeFromNow = time - p5sound.audiocontext.currentTime;\n /**\n * Do not initiate the callback if timeFromNow is < 0\n * This ususually occurs for a few milliseconds when the page\n * is not fully loaded\n *\n * The callback should only be called until maxIterations is reached\n */\n if (timeFromNow > 0 && self.iterations <= self.maxIterations) {\n self.callback(timeFromNow);}\n },\n 'frequency' : this._calcFreq()\n });\n };\n\n /**\n * Start the loop\n * @method start\n * @for p5.SoundLoop\n * @param {Number} [timeFromNow] schedule a starting time\n */\n p5.SoundLoop.prototype.start = function(timeFromNow) {\n var t = timeFromNow || 0;\n var now = p5sound.audiocontext.currentTime;\n if (!this.isPlaying) {\n this.clock.start(now + t);\n this.isPlaying = true;\n }\n };\n\n /**\n * Stop the loop\n * @method stop\n * @for p5.SoundLoop\n * @param {Number} [timeFromNow] schedule a stopping time\n */\n p5.SoundLoop.prototype.stop = function(timeFromNow) {\n var t = timeFromNow || 0;\n var now = p5sound.audiocontext.currentTime;\n if (this.isPlaying) {\n this.clock.stop(now + t);\n this.isPlaying = false;\n }\n };\n /**\n * Pause the loop\n * @method pause\n * @for p5.SoundLoop\n * @param {Number} [timeFromNow] schedule a pausing time\n */\n p5.SoundLoop.prototype.pause = function(timeFromNow) {\n var t = timeFromNow || 0;\n var now = p5sound.audiocontext.currentTime;\n if (this.isPlaying) {\n this.clock.pause(now + t);\n this.isPlaying = false;\n }\n };\n\n\n /**\n * Synchronize loops. Use this method to start two more more loops in synchronization\n * or to start a loop in synchronization with a loop that is already playing\n * This method will schedule the implicit loop in sync with the explicit master loop\n * i.e. loopToStart.syncedStart(loopToSyncWith)\n *\n * @method syncedStart\n * @for p5.SoundLoop\n * @param {Object} otherLoop a p5.SoundLoop to sync with\n * @param {Number} [timeFromNow] Start the loops in sync after timeFromNow seconds\n */\n p5.SoundLoop.prototype.syncedStart = function(otherLoop, timeFromNow) {\n var t = timeFromNow || 0;\n var now = p5sound.audiocontext.currentTime;\n\n if (!otherLoop.isPlaying) {\n otherLoop.clock.start(now + t);\n otherLoop.isPlaying = true;\n this.clock.start(now + t);\n this.isPlaying = true;\n } else if (otherLoop.isPlaying) {\n var time = otherLoop.clock._nextTick - p5sound.audiocontext.currentTime;\n this.clock.start(now + time);\n this.isPlaying = true;\n }\n };\n\n\n /**\n * Updates frequency value, reflected in next callback\n * @private\n * @for p5.SoundLoop\n * @method _update\n */\n p5.SoundLoop.prototype._update = function() {\n this.clock.frequency.value = this._calcFreq();\n };\n\n /**\n * Calculate the frequency of the clock's callback based on bpm, interval, and timesignature\n * @private\n * @for p5.SoundLoop\n * @method _calcFreq\n * @return {Number} new clock frequency value\n */\n p5.SoundLoop.prototype._calcFreq = function() {\n //Seconds mode, bpm / timesignature has no effect\n if (typeof this._interval === 'number') {\n this.musicalTimeMode = false;\n return 1 / this._interval;\n }\n //Musical timing mode, calculate interval based bpm, interval,and time signature\n else if (typeof this._interval === 'string') {\n this.musicalTimeMode = true;\n return this._bpm / 60 / this._convertNotation(this._interval) * (this._timeSignature / 4);\n }\n };\n\n /**\n * Convert notation from musical time format to seconds\n * Uses Tone.Time convention\n * @private\n * @for p5.SoundLoop\n * @method _convertNotation\n * @param {String} value value to be converted\n * @return {Number} converted value in seconds\n */\n p5.SoundLoop.prototype._convertNotation = function(value) {\n var type = value.slice(-1);\n value = Number(value.slice(0,-1));\n switch (type) {\n case 'm':\n return this._measure(value);\n case 'n':\n return this._note(value);\n default:\n console.warn('Specified interval is not formatted correctly. See Tone.js '+\n 'timing reference for more info: https://github.com/Tonejs/Tone.js/wiki/Time');\n }\n };\n\n /**\n * Helper conversion methods of measure and note\n * @private\n * @for p5.SoundLoop\n * @method _measure\n */\n p5.SoundLoop.prototype._measure = function(value) {\n return value * this._timeSignature;\n };\n\n /**\n * @private\n * @method _note\n * @for p5.SoundLoop\n */\n p5.SoundLoop.prototype._note = function(value) {\n return this._timeSignature / value ;\n };\n\n\n /**\n * Getters and Setters, setting any paramter will result in a change in the clock's\n * frequency, that will be reflected after the next callback\n * beats per minute (defaults to 60)\n * @property {Number} bpm\n * @for p5.SoundLoop\n */\n Object.defineProperty(p5.SoundLoop.prototype, 'bpm', {\n get : function() {\n return this._bpm;\n },\n set : function(bpm) {\n if (!this.musicalTimeMode) {\n console.warn('Changing the BPM in \"seconds\" mode has no effect. '+\n 'BPM is only relevant in musicalTimeMode '+\n 'when the interval is specified as a string '+\n '(\"2n\", \"4n\", \"1m\"...etc)');\n }\n this._bpm = bpm;\n this._update();\n }\n });\n\n /**\n * number of quarter notes in a measure (defaults to 4)\n * @property {Number} timeSignature\n * @for p5.SoundLoop\n */\n Object.defineProperty(p5.SoundLoop.prototype, 'timeSignature', {\n get : function() {\n return this._timeSignature;\n },\n set : function(timeSig) {\n if (!this.musicalTimeMode) {\n console.warn('Changing the timeSignature in \"seconds\" mode has no effect. '+\n 'BPM is only relevant in musicalTimeMode '+\n 'when the interval is specified as a string '+\n '(\"2n\", \"4n\", \"1m\"...etc)');\n }\n this._timeSignature = timeSig;\n this._update();\n }\n });\n\n /**\n * length of the loops interval\n * @property {Number|String} interval\n * @for p5.SoundLoop\n */\n Object.defineProperty(p5.SoundLoop.prototype, 'interval', {\n get : function() {\n return this._interval;\n },\n set : function(interval) {\n this.musicalTimeMode = typeof interval === 'Number'? false : true;\n this._interval = interval;\n this._update();\n }\n });\n\n /**\n * how many times the callback has been called so far\n * @property {Number} iterations\n * @for p5.SoundLoop\n * @readonly\n */\n Object.defineProperty(p5.SoundLoop.prototype, 'iterations', {\n get : function() {\n return this.clock.ticks;\n }\n });\n\n return p5.SoundLoop;\n});\n","define(function (require) {\n\t'use strict';\n\n\tvar p5sound = require('master');\n\tvar Effect = require('effect');\n var CustomError = require('errorHandler');\n\n /**\n * Compressor is an audio effect class that performs dynamics compression\n * on an audio input source. This is a very commonly used technique in music\n * and sound production. Compression creates an overall louder, richer,\n * and fuller sound by lowering the volume of louds and raising that of softs.\n * Compression can be used to avoid clipping (sound distortion due to\n * peaks in volume) and is especially useful when many sounds are played\n * at once. Compression can be used on indivudal sound sources in addition\n * to the master output.\n *\n * This class extends p5.Effect.\n * Methods amp(), chain(),\n * drywet(), connect(), and\n * disconnect() are available.\n *\n * @class p5.Compressor\n * @constructor\n * @extends p5.Effect\n *\n *\n */\n\tp5.Compressor = function() {\n\t\tEffect.call(this);\n\n /**\n * The p5.Compressor is built with a Web Audio Dynamics Compressor Node\n * \n * @property {AudioNode} compressor\n */\n\n\n\t\tthis.compressor = this.ac.createDynamicsCompressor();\n\n this.input.connect(this.compressor);\n this.compressor.connect(this.wet);\n\t};\n\n\tp5.Compressor.prototype = Object.create(Effect.prototype);\n\n /**\n * Performs the same function as .connect, but also accepts\n * optional parameters to set compressor's audioParams\n * @method process\n * @for p5.Compressor\n *\n * @param {Object} src Sound source to be connected\n *\n * @param {Number} [attack] The amount of time (in seconds) to reduce the gain by 10dB,\n * default = .003, range 0 - 1\n * @param {Number} [knee] A decibel value representing the range above the\n * threshold where the curve smoothly transitions to the \"ratio\" portion.\n * default = 30, range 0 - 40\n * @param {Number} [ratio] The amount of dB change in input for a 1 dB change in output\n * default = 12, range 1 - 20\n * @param {Number} [threshold] The decibel value above which the compression will start taking effect\n * default = -24, range -100 - 0\n * @param {Number} [release] The amount of time (in seconds) to increase the gain by 10dB\n * default = .25, range 0 - 1\n */\n\tp5.Compressor.prototype.process = function(src, attack, knee,\n ratio, threshold, release) {\n\t\tsrc.connect(this.input);\n\t\tthis.set(attack, knee, ratio, threshold, release);\n\t};\n\n /**\n * Set the paramters of a compressor.\n * @method set\n * @for p5.Compressor\n * @param {Number} attack The amount of time (in seconds) to reduce the gain by 10dB,\n * default = .003, range 0 - 1\n * @param {Number} knee A decibel value representing the range above the\n * threshold where the curve smoothly transitions to the \"ratio\" portion.\n * default = 30, range 0 - 40\n * @param {Number} ratio The amount of dB change in input for a 1 dB change in output\n * default = 12, range 1 - 20\n * @param {Number} threshold The decibel value above which the compression will start taking effect\n * default = -24, range -100 - 0\n * @param {Number} release The amount of time (in seconds) to increase the gain by 10dB\n * default = .25, range 0 - 1\n */\n p5.Compressor.prototype.set = function (attack, knee,\n ratio, threshold, release) {\n\n if (typeof attack !== 'undefined') {this.attack(attack);}\n if (typeof knee !== 'undefined') {this.knee(knee);}\n if (typeof ratio !== 'undefined') {this.ratio(ratio);}\n if (typeof threshold !== 'undefined') {this.threshold(threshold);}\n if (typeof release !== 'undefined') {this.release(release);}\n };\n\n\n /**\n * Get current attack or set value w/ time ramp\n *\n *\n * @method attack\n * @for p5.Compressor\n * @param {Number} [attack] Attack is the amount of time (in seconds) to reduce the gain by 10dB,\n * default = .003, range 0 - 1\n * @param {Number} [time] Assign time value to schedule the change in value\n */\n p5.Compressor.prototype.attack = function (attack, time){\n var t = time || 0;\n if (typeof attack == 'number'){\n this.compressor.attack.value = attack;\n this.compressor.attack.cancelScheduledValues(this.ac.currentTime + 0.01 + t);\n this.compressor.attack.linearRampToValueAtTime(attack, this.ac.currentTime + 0.02 + t);\n } else if (typeof attack !== 'undefined') {\n attack.connect(this.compressor.attack);\n }\n return this.compressor.attack.value;\n };\n\n\n /**\n * Get current knee or set value w/ time ramp\n *\n * @method knee\n * @for p5.Compressor\n * @param {Number} [knee] A decibel value representing the range above the\n * threshold where the curve smoothly transitions to the \"ratio\" portion.\n * default = 30, range 0 - 40\n * @param {Number} [time] Assign time value to schedule the change in value\n */\n p5.Compressor.prototype.knee = function (knee, time){\n var t = time || 0;\n if (typeof knee == 'number'){\n this.compressor.knee.value = knee;\n this.compressor.knee.cancelScheduledValues(this.ac.currentTime + 0.01 + t);\n this.compressor.knee.linearRampToValueAtTime(knee, this.ac.currentTime + 0.02 + t);\n } else if (typeof knee !== 'undefined') {\n knee.connect(this.compressor.knee);\n }\n return this.compressor.knee.value;\n };\n\n\n /**\n * Get current ratio or set value w/ time ramp\n * @method ratio\n * @for p5.Compressor\n * @param {Number} [ratio] The amount of dB change in input for a 1 dB change in output\n * default = 12, range 1 - 20\n * @param {Number} [time] Assign time value to schedule the change in value\n */\n p5.Compressor.prototype.ratio = function (ratio, time){\n var t = time || 0;\n if (typeof ratio == 'number'){\n this.compressor.ratio.value = ratio;\n this.compressor.ratio.cancelScheduledValues(this.ac.currentTime + 0.01 + t);\n this.compressor.ratio.linearRampToValueAtTime(ratio, this.ac.currentTime + 0.02 + t);\n } else if (typeof ratio !== 'undefined') {\n ratio.connect(this.compressor.ratio);\n }\n return this.compressor.ratio.value;\n };\n\n\n /**\n * Get current threshold or set value w/ time ramp\n * @method threshold\n * @for p5.Compressor\n * @param {Number} threshold The decibel value above which the compression will start taking effect\n * default = -24, range -100 - 0\n * @param {Number} [time] Assign time value to schedule the change in value\n */\n p5.Compressor.prototype.threshold = function (threshold, time){\n var t = time || 0;\n if (typeof threshold == 'number'){\n this.compressor.threshold.value = threshold;\n this.compressor.threshold.cancelScheduledValues(this.ac.currentTime + 0.01 + t);\n this.compressor.threshold.linearRampToValueAtTime(threshold, this.ac.currentTime + 0.02 + t);\n } else if (typeof threshold !== 'undefined') {\n threshold.connect(this.compressor.threshold);\n }\n return this.compressor.threshold.value;\n };\n\n\n /**\n * Get current release or set value w/ time ramp\n * @method release\n * @for p5.Compressor\n * @param {Number} release The amount of time (in seconds) to increase the gain by 10dB\n * default = .25, range 0 - 1\n *\n * @param {Number} [time] Assign time value to schedule the change in value\n */\n p5.Compressor.prototype.release = function (release, time){\n var t = time || 0;\n if (typeof release == 'number'){\n this.compressor.release.value = release;\n this.compressor.release.cancelScheduledValues(this.ac.currentTime + 0.01 + t);\n this.compressor.release.linearRampToValueAtTime(release, this.ac.currentTime + 0.02 + t);\n } else if (typeof number !== 'undefined') {\n release.connect(this.compressor.release);\n }\n return this.compressor.release.value;\n };\n\n /**\n * Return the current reduction value\n *\n * @method reduction\n * @for p5.Compressor\n * @return {Number} Value of the amount of gain reduction that is applied to the signal\n */\n p5.Compressor.prototype.reduction =function() {\n return this.compressor.reduction.value;\n };\n\n\n\tp5.Compressor.prototype.dispose = function() {\n Effect.prototype.dispose.apply(this);\n if (this.compressor) {\n this.compressor.disconnect();\n delete this.compressor;\n }\n\t};\n\n return p5.Compressor;\n});\n","'use strict';\n\ndefine(function (require) {\n\n // inspiration: recorder.js, Tone.js & typedarray.org\n\n var p5sound = require('master');\n var convertToWav = require('helpers').convertToWav;\n var processorNames = require('./audioWorklet/processorNames');\n var ac = p5sound.audiocontext;\n\n /**\n *
Record sounds for playback and/or to save as a .wav file.\n * The p5.SoundRecorder records all sound output from your sketch,\n * or can be assigned a specific source with setInput().
\n *
The record() method accepts a p5.SoundFile as a parameter.\n * When playback is stopped (either after the given amount of time,\n * or with the stop() method), the p5.SoundRecorder will send its\n * recording to that p5.SoundFile for playback.
\n * var mic, recorder, soundFile;\n * var state = 0;\n *\n * function setup() {\n * background(200);\n * // create an audio in\n * mic = new p5.AudioIn();\n *\n * // prompts user to enable their browser mic\n * mic.start();\n *\n * // create a sound recorder\n * recorder = new p5.SoundRecorder();\n *\n * // connect the mic to the recorder\n * recorder.setInput(mic);\n *\n * // this sound file will be used to\n * // playback & save the recording\n * soundFile = new p5.SoundFile();\n *\n * text('keyPress to record', 20, 20);\n * }\n *\n * function keyPressed() {\n * // make sure user enabled the mic\n * if (state === 0 && mic.enabled) {\n *\n * // record to our p5.SoundFile\n * recorder.record(soundFile);\n *\n * background(255,0,0);\n * text('Recording!', 20, 20);\n * state++;\n * }\n * else if (state === 1) {\n * background(0,255,0);\n *\n * // stop recorder and\n * // send result to soundFile\n * recorder.stop();\n *\n * text('Stopped', 20, 20);\n * state++;\n * }\n *\n * else if (state === 2) {\n * soundFile.play(); // play the result!\n * save(soundFile, 'mySound.wav');\n * state++;\n * }\n * }\n *
\n */\n p5.SoundRecorder = function() {\n this.input = ac.createGain();\n this.output = ac.createGain();\n\n this._inputChannels = 2;\n this._outputChannels = 2; // stereo output, even if input is mono\n\n this._workletNode = new AudioWorkletNode(ac, processorNames.recorderProcessor, {\n outputChannelCount: [this._outputChannels],\n processorOptions: { numInputChannels: this._inputChannels }\n });\n\n this._workletNode.port.onmessage = function(event) {\n if (event.data.name === 'buffers') {\n const buffers = [\n new Float32Array(event.data.leftBuffer),\n new Float32Array(event.data.rightBuffer)\n ];\n this._callback(buffers);\n }\n }.bind(this);\n\n /**\n * callback invoked when the recording is over\n * @private\n * @type Function(Float32Array)\n */\n this._callback = function() {};\n\n // connections\n this._workletNode.connect(p5.soundOut._silentNode);\n this.setInput();\n\n // add this p5.SoundFile to the soundArray\n p5sound.soundArray.push(this);\n };\n\n /**\n * Connect a specific device to the p5.SoundRecorder.\n * If no parameter is given, p5.SoundRecorer will record\n * all audible p5.sound from your sketch.\n *\n * @method setInput\n * @for p5.SoundRecorder\n * @param {Object} [unit] p5.sound object or a web audio unit\n * that outputs sound\n */\n p5.SoundRecorder.prototype.setInput = function(unit) {\n this.input.disconnect();\n this.input = null;\n this.input = ac.createGain();\n this.input.connect(this._workletNode);\n this.input.connect(this.output);\n if (unit) {\n unit.connect(this.input);\n } else {\n p5.soundOut.output.connect(this.input);\n }\n };\n\n /**\n * Start recording. To access the recording, provide\n * a p5.SoundFile as the first parameter. The p5.SoundRecorder\n * will send its recording to that p5.SoundFile for playback once\n * recording is complete. Optional parameters include duration\n * (in seconds) of the recording, and a callback function that\n * will be called once the complete recording has been\n * transfered to the p5.SoundFile.\n *\n * @method record\n * @for p5.SoundRecorder\n * @param {p5.SoundFile} soundFile p5.SoundFile\n * @param {Number} [duration] Time (in seconds)\n * @param {Function} [callback] The name of a function that will be\n * called once the recording completes\n */\n p5.SoundRecorder.prototype.record = function(sFile, duration, callback) {\n this._workletNode.port.postMessage({ name: 'start', duration: duration });\n\n if (sFile && callback) {\n this._callback = function(buffer) {\n sFile.setBuffer(buffer);\n callback();\n };\n }\n else if (sFile) {\n this._callback = function(buffer) {\n sFile.setBuffer(buffer);\n };\n }\n };\n\n /**\n * Stop the recording. Once the recording is stopped,\n * the results will be sent to the p5.SoundFile that\n * was given on .record(), and if a callback function\n * was provided on record, that function will be called.\n *\n * @method stop\n * @for p5.SoundRecorder\n */\n p5.SoundRecorder.prototype.stop = function() {\n this._workletNode.port.postMessage({ name: 'stop' });\n };\n\n p5.SoundRecorder.prototype.dispose = function() {\n // remove reference from soundArray\n var index = p5sound.soundArray.indexOf(this);\n p5sound.soundArray.splice(index, 1);\n\n this._callback = function() {};\n if (this.input) {\n this.input.disconnect();\n }\n this.input = null;\n this._workletNode = null;\n };\n\n\n /**\n * Save a p5.SoundFile as a .wav file. The browser will prompt the user\n * to download the file to their device.\n * For uploading audio to a server, use\n * `p5.SoundFile.saveBlob`.\n *\n * @for p5\n * @method saveSound\n * @param {p5.SoundFile} soundFile p5.SoundFile that you wish to save\n * @param {String} fileName name of the resulting .wav file.\n */\n // add to p5.prototype as this is used by the p5 `save()` method.\n p5.prototype.saveSound = function (soundFile, fileName) {\n const dataView = convertToWav(soundFile.buffer);\n p5.prototype.writeFile([dataView], fileName, 'wav');\n };\n});\n","'use strict';\n\ndefine(function () {\n /**\n *
PeakDetect works in conjunction with p5.FFT to\n * look for onsets in some or all of the frequency spectrum.\n *
\n *
\n * To use p5.PeakDetect, call update in the draw loop\n * and pass in a p5.FFT object.\n *
\n *
\n * You can listen for a specific part of the frequency spectrum by\n * setting the range between freq1 and freq2.\n *
\n *\n *
threshold is the threshold for detecting a peak,\n * scaled between 0 and 1. It is logarithmic, so 0.1 is half as loud\n * as 1.0.
\n *\n *
\n * The update method is meant to be run in the draw loop, and\n * frames determines how many loops must pass before\n * another peak can be detected.\n * For example, if the frameRate() = 60, you could detect the beat of a\n * 120 beat-per-minute song with this equation:\n * framesPerPeak = 60 / (estimatedBPM / 60 );\n *
\n *\n *
\n * Based on example contribtued by @b2renger, and a simple beat detection\n * explanation by Felix Turner.\n *
\n *\n * @class p5.PeakDetect\n * @constructor\n * @param {Number} [freq1] lowFrequency - defaults to 20Hz\n * @param {Number} [freq2] highFrequency - defaults to 20000 Hz\n * @param {Number} [threshold] Threshold for detecting a beat between 0 and 1\n * scaled logarithmically where 0.1 is 1/2 the loudness\n * of 1.0. Defaults to 0.35.\n * @param {Number} [framesPerPeak] Defaults to 20.\n * @example\n *
\n */\n p5.PeakDetect = function(freq1, freq2, threshold, _framesPerPeak) {\n // framesPerPeak determines how often to look for a beat.\n // If a beat is provided, try to look for a beat based on bpm\n this.framesPerPeak = _framesPerPeak || 20;\n this.framesSinceLastPeak = 0;\n this.decayRate = 0.95;\n\n this.threshold = threshold || 0.35;\n this.cutoff = 0;\n\n // how much to increase the cutoff\n // TO DO: document this / figure out how to make it accessible\n this.cutoffMult = 1.5;\n\n this.energy = 0;\n this.penergy = 0;\n\n // TO DO: document this property / figure out how to make it accessible\n this.currentValue = 0;\n\n /**\n * isDetected is set to true when a peak is detected.\n *\n * @attribute isDetected {Boolean}\n * @default false\n */\n this.isDetected = false;\n\n this.f1 = freq1 || 40;\n this.f2 = freq2 || 20000;\n\n // function to call when a peak is detected\n this._onPeak = function() {};\n };\n\n\n /**\n * The update method is run in the draw loop.\n *\n * Accepts an FFT object. You must call .analyze()\n * on the FFT object prior to updating the peakDetect\n * because it relies on a completed FFT analysis.\n *\n * @method update\n * @param {p5.FFT} fftObject A p5.FFT object\n */\n p5.PeakDetect.prototype.update = function(fftObject) {\n var nrg = this.energy = fftObject.getEnergy(this.f1,this.f2)/255;\n if (nrg > this.cutoff && nrg > this.threshold && nrg-this.penergy > 0) {\n\n // trigger callback\n this._onPeak();\n this.isDetected = true;\n\n // debounce\n this.cutoff = nrg * this.cutoffMult;\n this.framesSinceLastPeak = 0;\n } else {\n this.isDetected = false;\n if (this.framesSinceLastPeak <= this.framesPerPeak) {\n this.framesSinceLastPeak++;\n } else {\n this.cutoff *= this.decayRate;\n this.cutoff = Math.max(this.cutoff, this.threshold);\n }\n }\n\n this.currentValue = nrg;\n this.penergy = nrg;\n };\n\n /**\n * onPeak accepts two arguments: a function to call when\n * a peak is detected. The value of the peak,\n * between 0.0 and 1.0, is passed to the callback.\n *\n * @method onPeak\n * @param {Function} callback Name of a function that will\n * be called when a peak is\n * detected.\n * @param {Object} [val] Optional value to pass\n * into the function when\n * a peak is detected.\n * @example\n *
\n * var cnv, soundFile, fft, peakDetect;\n * var ellipseWidth = 0;\n *\n * function preload() {\n * soundFile = loadSound('assets/beat.mp3');\n * }\n *\n * function setup() {\n * cnv = createCanvas(100,100);\n * textAlign(CENTER);\n *\n * fft = new p5.FFT();\n * peakDetect = new p5.PeakDetect();\n *\n * setupSound();\n *\n * // when a beat is detected, call triggerBeat()\n * peakDetect.onPeak(triggerBeat);\n * }\n *\n * function draw() {\n * background(0);\n * fill(255);\n * text('click to play', width/2, height/2);\n *\n * fft.analyze();\n * peakDetect.update(fft);\n *\n * ellipseWidth *= 0.95;\n * ellipse(width/2, height/2, ellipseWidth, ellipseWidth);\n * }\n *\n * // this function is called by peakDetect.onPeak\n * function triggerBeat() {\n * ellipseWidth = 50;\n * }\n *\n * // mouseclick starts/stops sound\n * function setupSound() {\n * cnv.mouseClicked( function() {\n * if (soundFile.isPlaying() ) {\n * soundFile.stop();\n * } else {\n * soundFile.play();\n * }\n * });\n * }\n *
\n */\n p5.PeakDetect.prototype.onPeak = function(callback, val) {\n var self = this;\n\n self._onPeak = function() {\n callback(self.energy, val);\n };\n };\n\n});\n","'use strict';\n\ndefine(function (require) {\n var p5sound = require('master');\n\n /**\n * A gain node is usefull to set the relative volume of sound.\n * It's typically used to build mixers.\n *\n * @class p5.Gain\n * @constructor\n * @example\n *
\n *\n * // load two soundfile and crossfade beetween them\n * var sound1,sound2;\n * var gain1, gain2, gain3;\n *\n * function preload(){\n * soundFormats('ogg', 'mp3');\n * sound1 = loadSound('assets/Damscray_-_Dancing_Tiger_01');\n * sound2 = loadSound('assets/beat.mp3');\n * }\n *\n * function setup() {\n * createCanvas(400,200);\n *\n * // create a 'master' gain to which we will connect both soundfiles\n * gain3 = new p5.Gain();\n * gain3.connect();\n *\n * // setup first sound for playing\n * sound1.rate(1);\n * sound1.loop();\n * sound1.disconnect(); // diconnect from p5 output\n *\n * gain1 = new p5.Gain(); // setup a gain node\n * gain1.setInput(sound1); // connect the first sound to its input\n * gain1.connect(gain3); // connect its output to the 'master'\n *\n * sound2.rate(1);\n * sound2.disconnect();\n * sound2.loop();\n *\n * gain2 = new p5.Gain();\n * gain2.setInput(sound2);\n * gain2.connect(gain3);\n *\n * }\n *\n * function draw(){\n * background(180);\n *\n * // calculate the horizontal distance beetween the mouse and the right of the screen\n * var d = dist(mouseX,0,width,0);\n *\n * // map the horizontal position of the mouse to values useable for volume control of sound1\n * var vol1 = map(mouseX,0,width,0,1);\n * var vol2 = 1-vol1; // when sound1 is loud, sound2 is quiet and vice versa\n *\n * gain1.amp(vol1,0.5,0);\n * gain2.amp(vol2,0.5,0);\n *\n * // map the vertical position of the mouse to values useable for 'master volume control'\n * var vol3 = map(mouseY,0,height,0,1);\n * gain3.amp(vol3,0.5,0);\n * }\n *
\n *\n */\n\n p5.Gain = function() {\n this.ac = p5sound.audiocontext;\n\n this.input = this.ac.createGain();\n this.output = this.ac.createGain();\n\n // otherwise, Safari distorts\n this.input.gain.value = 0.5;\n this.input.connect(this.output);\n\n // add to the soundArray\n p5sound.soundArray.push(this);\n };\n\n /**\n * Connect a source to the gain node.\n *\n * @method setInput\n * @for p5.Gain\n * @param {Object} src p5.sound / Web Audio object with a sound\n * output.\n */\n\n\n p5.Gain.prototype.setInput = function(src) {\n src.connect(this.input);\n };\n\n /**\n * Send output to a p5.sound or web audio object\n *\n * @method connect\n * @for p5.Gain\n * @param {Object} unit\n */\n p5.Gain.prototype.connect = function(unit) {\n var u = unit || p5.soundOut.input;\n this.output.connect(u.input ? u.input : u);\n };\n\n /**\n * Disconnect all output.\n *\n * @method disconnect\n * @for p5.Gain\n */\n p5.Gain.prototype.disconnect = function() {\n if (this.output) {\n this.output.disconnect();\n }\n };\n\n /**\n * Set the output level of the gain node.\n *\n * @method amp\n * @for p5.Gain\n * @param {Number} volume amplitude between 0 and 1.0\n * @param {Number} [rampTime] create a fade that lasts rampTime\n * @param {Number} [timeFromNow] schedule this event to happen\n * seconds from now\n */\n p5.Gain.prototype.amp = function(vol, rampTime, tFromNow) {\n var rampTime = rampTime || 0;\n var tFromNow = tFromNow || 0;\n var now = p5sound.audiocontext.currentTime;\n var currentVol = this.output.gain.value;\n this.output.gain.cancelScheduledValues(now);\n this.output.gain.linearRampToValueAtTime(currentVol, now + tFromNow);\n this.output.gain.linearRampToValueAtTime(vol, now + tFromNow + rampTime);\n };\n\n p5.Gain.prototype.dispose = function() {\n // remove reference from soundArray\n var index = p5sound.soundArray.indexOf(this);\n p5sound.soundArray.splice(index, 1);\n if (this.output) {\n this.output.disconnect();\n delete this.output;\n }\n if (this.input) {\n this.input.disconnect();\n delete this.input;\n }\n };\n\n});\n","'use strict';\n\ndefine(function (require) {\n\n var Effect = require('effect');\n\n /*\n * Adapted from [Kevin Ennis on StackOverflow](http://stackoverflow.com/questions/22312841/waveshaper-node-in-webaudio-how-to-emulate-distortion)\n */\n function makeDistortionCurve(amount) {\n var k = typeof amount === 'number' ? amount : 50;\n var numSamples = 44100;\n var curve = new Float32Array(numSamples);\n var deg = Math.PI / 180;\n var i = 0;\n var x;\n for ( ; i < numSamples; ++i ) {\n x = i * 2 / numSamples - 1;\n curve[i] = ( 3 + k ) * x * 20 * deg / ( Math.PI + k * Math.abs(x) );\n }\n return curve;\n }\n\n /**\n * A Distortion effect created with a Waveshaper Node,\n * with an approach adapted from\n * [Kevin Ennis](http://stackoverflow.com/questions/22312841/waveshaper-node-in-webaudio-how-to-emulate-distortion)\n *\n * This class extends p5.Effect.\n * Methods amp(), chain(),\n * drywet(), connect(), and\n * disconnect() are available.\n *\n * @class p5.Distortion\n * @extends p5.Effect\n * @constructor\n * @param {Number} [amount=0.25] Unbounded distortion amount.\n * Normal values range from 0-1.\n * @param {String} [oversample='none'] 'none', '2x', or '4x'.\n *\n */\n p5.Distortion = function(amount, oversample) {\n Effect.call(this);\n\n if (typeof amount === 'undefined') {\n amount = 0.25;\n } if (typeof amount !== 'number') {\n throw new Error('amount must be a number');\n } if (typeof oversample === 'undefined') {\n oversample = '2x';\n } if (typeof oversample !== 'string') {\n throw new Error('oversample must be a String');\n }\n\n var curveAmount = p5.prototype.map(amount, 0.0, 1.0, 0, 2000);\n\n /**\n * The p5.Distortion is built with a\n * \n * Web Audio WaveShaper Node.\n *\n * @property {AudioNode} WaveShaperNode\n */\n this.waveShaperNode = this.ac.createWaveShaper();\n\n this.amount = curveAmount;\n this.waveShaperNode.curve = makeDistortionCurve(curveAmount);\n this.waveShaperNode.oversample = oversample;\n\n this.input.connect(this.waveShaperNode);\n\n this.waveShaperNode.connect(this.wet);\n };\n\n p5.Distortion.prototype = Object.create(Effect.prototype);\n\n\n /**\n * Process a sound source, optionally specify amount and oversample values.\n *\n * @method process\n * @for p5.Distortion\n * @param {Number} [amount=0.25] Unbounded distortion amount.\n * Normal values range from 0-1.\n * @param {String} [oversample='none'] 'none', '2x', or '4x'.\n */\n p5.Distortion.prototype.process = function(src, amount, oversample) {\n src.connect(this.input);\n this.set(amount, oversample);\n };\n\n /**\n * Set the amount and oversample of the waveshaper distortion.\n *\n * @method set\n * @for p5.Distortion\n * @param {Number} [amount=0.25] Unbounded distortion amount.\n * Normal values range from 0-1.\n * @param {String} [oversample='none'] 'none', '2x', or '4x'.\n */\n p5.Distortion.prototype.set = function(amount, oversample) {\n if (amount) {\n var curveAmount = p5.prototype.map(amount, 0.0, 1.0, 0, 2000);\n this.amount = curveAmount;\n this.waveShaperNode.curve = makeDistortionCurve(curveAmount);\n }\n if (oversample) {\n this.waveShaperNode.oversample = oversample;\n }\n };\n\n /**\n * Return the distortion amount, typically between 0-1.\n *\n * @method getAmount\n * @for p5.Distortion\n * @return {Number} Unbounded distortion amount.\n * Normal values range from 0-1.\n */\n p5.Distortion.prototype.getAmount = function() {\n return this.amount;\n };\n\n /**\n * Return the oversampling.\n *\n * @method getOversample\n * @for p5.Distortion\n * @return {String} Oversample can either be 'none', '2x', or '4x'.\n */\n p5.Distortion.prototype.getOversample = function() {\n return this.waveShaperNode.oversample;\n };\n\n\n p5.Distortion.prototype.dispose = function() {\n Effect.prototype.dispose.apply(this);\n if (this.waveShaperNode) {\n this.waveShaperNode.disconnect();\n this.waveShaperNode = null;\n }\n };\n});\n"],"sourceRoot":""}
\ No newline at end of file
diff --git a/src/audioWorklet/soundFileProcessor.js b/src/audioWorklet/soundFileProcessor.js
index a442b2d5..b9abaffd 100644
--- a/src/audioWorklet/soundFileProcessor.js
+++ b/src/audioWorklet/soundFileProcessor.js
@@ -2,29 +2,12 @@
const processorNames = preval.require('./processorNames');
class SoundFileProcessor extends AudioWorkletProcessor {
- constructor() {
- super();
-
- this.paused = false;
-
- this.port.onmessage = (event) => {
- const data = event.data;
- if (data.name === 'play') {
- this.paused = false;
- } else if (data.name === 'pause') {
- this.paused = true;
- }
- };
- }
-
process(inputs) {
const input = inputs[0];
const inputChannel = input[0];
const position = inputChannel[inputChannel.length - 1] || 0;
- if (!this.paused) {
- this.port.postMessage({ name: 'position', position: position });
- }
+ this.port.postMessage({ name: 'position', position: position });
return true;
}
diff --git a/src/soundfile.js b/src/soundfile.js
index d402e2a3..52bf2ee4 100644
--- a/src/soundfile.js
+++ b/src/soundfile.js
@@ -369,7 +369,6 @@ define(function (require) {
// TO DO: if already playing, create array of buffers for easy stop()
if (this.buffer) {
-
// reset the pause time (if it was paused)
this._pauseTime = 0;
@@ -439,7 +438,6 @@ define(function (require) {
this._counterNode.loopEnd = cueEnd;
}
- this._workletNode.port.postMessage({ name: 'play' });
};
@@ -539,13 +537,12 @@ define(function (require) {
var pTime = time + now;
if (this.isPlaying() && this.buffer && this.bufferSourceNode) {
- this._workletNode.port.postMessage({ name: 'pause' });
+ this._paused = true;
+ this._playing = false;
this.pauseTime = this.currentTime();
this.bufferSourceNode.stop(pTime);
this._counterNode.stop(pTime);
- this._paused = true;
- this._playing = false;
this._pauseTime = this.currentTime();
// TO DO: make sure play() still starts from orig start position
@@ -1247,14 +1244,18 @@ define(function (require) {
delete self._workletNode;
}
self._workletNode = new AudioWorkletNode(ac, processorNames.soundFileProcessor);
- self._workletNode.port.onmessage = function(event) {
+ self._workletNode.port.onmessage = event => {
if (event.data.name === 'position') {
+ // event.data.position should only be 0 when paused
+ if (event.data.position === 0) {
+ return;
+ }
this._lastPos = event.data.position;
// do any callbacks that have been scheduled
this._onTimeUpdate(self._lastPos);
}
- }.bind(self);
+ };
// create counter buffer of the same length as self.buffer
cNode.buffer = _createCounterBuffer( self.buffer );
From b32e460deb85414c650847a2eeacb0f15e027e09 Mon Sep 17 00:00:00 2001
From: Oren Shoham
Date: Fri, 16 Aug 2019 17:14:48 -0400
Subject: [PATCH 4/4] Fix pause_soundfile example in Safari by calling
getAudioContext().resume() on user interaction before any other audio code
---
examples/pause_soundfile/sketch.js | 22 +++++++++++++++++-----
1 file changed, 17 insertions(+), 5 deletions(-)
diff --git a/examples/pause_soundfile/sketch.js b/examples/pause_soundfile/sketch.js
index 6a9495b8..e7aa7184 100644
--- a/examples/pause_soundfile/sketch.js
+++ b/examples/pause_soundfile/sketch.js
@@ -1,8 +1,10 @@
// ====================
// DEMO: pause sound when the user presses a key, resume on release
// ====================
+'use strict';
var soundFile;
+var audioContextStarted = false;
function preload() {
// create a SoundFile
@@ -14,16 +16,26 @@ function setup() {
createCanvas(400, 400);
background(0, 255, 0);
- soundFile.loop();
+ userStartAudio().then(function() {
+ soundFile.loop();
+ audioContextStarted = true;
+ });
+
createP('Press any key to pause. Resume when the key is released')
}
function keyTyped() {
- soundFile.pause();
- background(255, 0, 0);
+ if (!audioContextStarted) {
+ return;
+ }
+ soundFile.pause();
+ background(255, 0, 0);
}
function keyReleased() {
- soundFile.play();
- background(0, 255, 0);
+ if (!audioContextStarted) {
+ return;
+ }
+ soundFile.play();
+ background(0, 255, 0);
}