PageSourceSearch

https://dreamlens.netlify.app/p5/p5.sound.js

js dreamlens.netlify.app collected 2026-10-03 10:39:56 UTC 450,566 bytes, 11,834 lines download raw bytes

vendor: 4,829 bytes, lines 1-104
1/** [p5.sound]  Version: 0.3.12 - 2020-01-06 */ 
2 /**
3 *  <p>p5.sound extends p5 with <a href="http://caniuse.com/audio-api"
4 *  target="_blank">Web Audio</a> functionality including audio input,
5 *  playback, analysis and synthesis.
6 *  </p>
7 *  <ul>
8 *  <li><a href="#/p5.SoundFile"><b>p5.SoundFile</b></a>: Load and play sound files.</li>
9 *  <li><a href="#/p5.Amplitude"><b>p5.Amplitude</b></a>: Get the current volume of a sound.</li>
10 *  <li><a href="#/p5.AudioIn"><b>p5.AudioIn</b></a>: Get sound from an input source, typically
11 *    a computer microphone.</li>
12 *  <li><a href="#/p5.FFT"><b>p5.FFT</b></a>: Analyze the frequency of sound. Returns
13 *    results from the frequency spectrum or time domain (waveform).</li>
14 *  <li><a href="#/p5.Oscillator"><b>p5.Oscillator</b></a>: Generate Sine,
15 *    Triangle, Square and Sawtooth waveforms. Base class of
16 *    <li><a href="#/p5.Noise">p5.Noise</a> and <a href="#/p5.Pulse">p5.Pulse</a>.
17 *    </li>
18 *  <li>
19 *    <a href="#/p5.MonoSynth">p5.MonoSynth</a> and <a href="#/p5.PolySynth">p5.PolySynth</a>: Play musical notes
20 *  </li>
21 *  <li><a href="#/p5.Envelope"><b>p5.Envelope</b></a>: An Envelope is a series
22 *    of fades over time. Often used to control an object's
23 *    output gain level as an "ADSR Envelope" (Attack, Decay,
24 *    Sustain, Release). Can also modulate other parameters.</li>
25 *  <li><a href="#/p5.Delay"><b>p5.Delay</b></a>: A delay effect with
26 *    parameters for feedback, delayTime, and lowpass filter.</li>
27 *  <li><a href="#/p5.Filter"><b>p5.Filter</b></a>: Filter the frequency range of a
28 *    sound.
29 *  </li>
30 *  <li><a href="#/p5.Reverb"><b>p5.Reverb</b></a>: Add reverb to a sound by specifying
31 *    duration and decay. </li>
32 *  <b><li><a href="#/p5.Convolver">p5.Convolver</a>:</b> Extends
33 *  <a href="#/p5.Reverb">p5.Reverb</a> to simulate the sound of real
34 *    physical spaces through convolution.</li>
35 *  <b><li><a href="#/p5.SoundRecorder">p5.SoundRecorder</a></b>: Record sound for playback
36 *    / save the .wav file.
37 *  <b><li><a href="#/p5.SoundLoop">p5.SoundLoop</a>, <a href="#/p5.Phrase">p5.Phrase</a></b>, <b><a href="#/p5.Part">p5.Part</a></b> and
38 *  <b><a href="#/p5.Score">p5.Score</a></b>: Compose musical sequences.
39 *  </li>
40 *  <li><a href="#/p5/userStartAudio">userStartAudio</a>: Enable audio in a
41 *  browser- and user-friendly way.</a>
42 *  <p>p5.sound is on <a href="https://github.com/therewasaguy/p5.sound/">GitHub</a>.
43 *  Download the latest version
44 *  <a href="https://github.com/therewasaguy/p5.sound/blob/master/lib/p5.sound.js">here</a>.</p>
45 *
46 *  @module p5.sound
47 *  @submodule p5.sound
48 *  @for p5.sound
49 *  @main
50 */
51
52/**
53 *  p5.sound 
54 *  https://p5js.org/reference/#/libraries/p5.sound
55 *
56 *  From the Processing Foundation and contributors
57 *  https://github.com/processing/p5.js-sound/graphs/contributors
58 *
59 *  MIT License (MIT)
60 *  https://github.com/processing/p5.js-sound/blob/master/LICENSE
61 *
62 *  Some of the many audio libraries & resources that inspire p5.sound:
63 *   - TONE.js (c) Yotam Mann. Licensed under The MIT License (MIT). https://github.com/TONEnoTONE/Tone.js
64 *   - buzz.js (c) Jay Salvat. Licensed under The MIT License (MIT). http://buzz.jaysalvat.com/
65 *   - Boris Smus Web Audio API book, 2013. Licensed under the Apache License http://www.apache.org/licenses/LICENSE-2.0
66 *   - wavesurfer.js https://github.com/katspaugh/wavesurfer.js
67 *   - Web Audio Components by Jordan Santell https://github.com/web-audio-components
68 *   - Wilm Thoben's Sound library for Processing https://github.com/processing/processing/tree/master/java/libraries/sound
69 *
70 *   Web Audio API: http://w3.org/TR/webaudio/
71 */
72
73 (function(modules) { 
74 	var installedModules = {};
75 	function __webpack_require__(moduleId) {
76 		if(installedModules[moduleId]) {
77 			return installedModules[moduleId].exports;
78 		}
79 		var module = installedModules[moduleId] = {
80 			i: moduleId,
81 			l: false,
82 			exports: {}
83 		};
84 		modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
85 		module.l = true;
86 		return module.exports;
87 	}
88 	__webpack_require__.m = modules;
89 	__webpack_require__.c = installedModules;
90 	__webpack_require__.d = function(exports, name, getter) {
91 		if(!__webpack_require__.o(exports, name)) {
92 			Object.defineProperty(exports, name, { enumerable: true, get: getter });
93 		}
94 	};
95 	__webpack_require__.r = function(exports) {
96 		if(typeof Symbol !== 'undefined' && Symbol.toStringTag) {
97 			Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
98 		}
99 		Object.defineProperty(exports, '__esModule', { value: true });
100 	};
101 	__webpack_require__.t = function(value, mode) {
102 		if(mode & 1) value = __webpack_require__(value);
103 		if(mode & 8) return value;
104 		if((mode & 4) && typeof value === 'object' && value && value.__esMo
104dule) return value;
105 		var ns = Object.create(null);
106 		__webpack_require__.r(ns);
107 		Object.defineProperty(ns, 'default', { enumerable: true, value: value });
108 		if(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key));
109 		return ns;
110 	};
111 	__webpack_require__.n = function(module) {
112 		var getter = module && module.__esModule ?
113 			function getDefault() { return module['default']; } :
114 			function getModuleExports() { return module; };
115 		__webpack_require__.d(getter, 'a', getter);
116 		return getter;
117 	};
118 	__webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };
119 	__webpack_require__.p = "";
120 	return __webpack_require__(__webpack_require__.s = 31);
121 })
122 ([
123 (function(module, exports, __webpack_require__) {
124
125var __WEBPACK_AMD_DEFINE_RESULT__;!(__WEBPACK_AMD_DEFINE_RESULT__ = (function(){"use strict";function a(t,e){this.isUndef(t)||1===t?this.input=this.context.createGain():1<t&&(this.input=new Array(t)),this.isUndef(e)||1===e?this.output=this.context.createGain():1<e&&(this.output=new Array(t))}var e;return a.prototype.set=function(t,e,n){if(this.isObject(t))n=e;else if(this.isString(t)){var o={};o[t]=e,t=o}t:for(var i in t){e=t[i];var r=this;if(-1!==i.indexOf(".")){for(var s=i.split("."),u=0;u<s.length-1;u++)if((r=r[s[u]])instanceof a){s.splice(0,u+1);var p=s.join(".");r.set(p,e);continue t}i=s[s.length-1]}var c=r[i];this.isUndef(c)||(a.Signal&&c instanceof a.Signal||a.Param&&c instanceof a.Param?c.value!==e&&(this.isUndef(n)?c.value=e:c.rampTo(e,n)):c instanceof AudioParam?c.value!==e&&(c.value=e):c instanceof a?c.set(e):c!==e&&(r[i]=e))}return this},a.prototype.get=function(t){this.isUndef(t)?t=this._collectDefaults(this.constructor):this.isString(t)&&(t=[t]);for(var e={},n=0;n<t.length;n++){var o=t[n],i=this,r=e;if(-1!==o.indexOf(".")){for(var s=o.split("."),u=0;u<s.length-1;u++){var p=s[u];r[p]=r[p]||{},r=r[p],i=i[p]}o=s[s.length-1]}var c=i[o];this.isObject(t[o])?r[o]=c.get():a.Signal&&c instanceof a.Signal?r[o]=c.value:a.Param&&c instanceof a.Param?r[o]=c.value:c instanceof AudioParam?r[o]=c.value:c instanceof a?r[o]=c.get():this.isFunction(c)||this.isUndef(c)||(r[o]=c)}return e},a.prototype._collectDefaults=function(t){var e=[];if(this.isUndef(t.defaults)||(e=Object.keys(t.defaults)),!this.isUndef(t._super))for(var n=this._collectDefaults(t._super),o=0;o<n.length;o++)-1===e.indexOf(n[o])&&e.push(n[o]);return e},a.prototype.toString=function(){for(var t in a){var e=t[0].match(/^[A-Z]$/),n=a[t]===this.constructor;if(this.isFunction(a[t])&&e&&n)return t}return"Tone"},Object.defineProperty(a.prototype,"numberOfInputs",{get:function(){return this.input?this.isArray(this.input)?this.input.length:1:0}}),Object.defineProperty(a.prototype,"numberOfOutputs",{get:function(){return this.output?this.isArray(this.output)?this.output.length:1:0}}),a.prototype.dispose=function(){return this.isUndef(this.input)||(this.input instanceof AudioNode&&this.input.disconnect(),this.input=null),this.isUndef(this.output)||(this.output instanceof AudioNode&&this.output.disconnect(),this.output=null),this},a.prototype.connect=function(t,e,n){return Array.isArray(this.output)?(e=this.defaultArg(e,0),this.output[e].connect(t,0,n)):this.output.connect(t,e,n),this},a.prototype.disconnect=function(t,e,n){this.isArray(this.output)?this.isNumber(t)?this.output[t].disconnect():(e=this.defaultArg(e,0),this.output[e].disconnect(t,0,n)):this.output.disconnect.apply(this.output,arguments)},a.prototype.connectSeries=function(){if(1<arguments.length)for(var t=arguments[0],e=1;e<arguments.length;e++){var n=arguments[e];t.connect(n),t=n}return this},a.prototype.chain=function(){if(0<arguments.length)for(var t=this,e=0;e<arguments.length;e++){var n=arguments[e];t.connect(n),t=n}return this},a.prototype.fan=function(){if(0<arguments.length)for(var t=0;t<arguments.length;t++)this.connect(arguments[t]);return this},AudioNode.prototype.chain=a.prototype.chain,AudioNode.prototype.fan=a.prototype.fan,a.prototype.defaultArg=function(t,e){if(this.isObject(t)&&this.isObject(e)){var n={};for(var o in t)n[o]=this.defaultArg(e[o],t[o]);for(var i in e)n[i]=this.defaultArg(t[i],e[i]);return n}return this.isUndef(t)?e:t},a.prototype.optionsObject=function(t,e,n){var o={};if(1===t.length&&this.isObject(t[0]))o=t[0];else for(var i=0;i<e.length;i++)o[e[i]]=t[i];return this.isUndef(n)?o:this.defaultArg(o,n)},a.prototype.isUndef=function(t){return void 0===t},a.prototype.isFunction=function(t){return"function"==typeof t},a.prototype.isNumber=function(t){return"number"==typeof t},a.prototype.isObject=function(t){return"[object Object]"===Object.prototype.toString.call(t)&&t.constructor===Object},a.prototype.isBoolean=function(t){return"boolean"==typeof t},a.prototype.isArray=function(t){return Array.isArray(t)},a.prototype.isString=function(t){return"string"==typeof t},a.noOp=function(){},a.prototype._readOnly=function(t){if(Array.isArray(t))for(var e=0;e<t.length;e++)this._readOnly(t[e]);else Object.defineProperty(this,t,{writable:!1,enumerable:!0})},a.prototype._writable=function(t){if(Array.isArray(t))for(var e=0;e<t.length;e++)this._writable(t[e]);else Object.defineProperty(this,t,{writable:!0})},a.State={Started:"started",Stopped:"stopped",Paused:"paused"},a.prototype.equalPowerScale=function(t){var e=.5*Math.PI;return Math.sin(t*e)},a.prototype.dbToGain=function(t){return Math.pow(2,t/6)},a.prototype.gainToDb=function(t){return Math.log(t)/Math.LN10*20},a.prototype.intervalToFrequencyRatio=function(t){return Math.pow(2,t/12)},a.prototype.now=function(){return a.context.now()},a.now=function(){return a.context.now()},a.extend=function(t,e){function n(){}a.prototype.isUndef(e)&&(e=a),n.prototype=e.prototype,t.prototype=new n,(t.prototype.constructor=t)._super=e},Object.defineProperty(a,"context",{get:function(){return e},set:function(t){e=a.Context&&t instanceof a.Context?t:new a.Context(t),a.Context&&a.Context.emit("init",e)}}),Object.defineProperty(a.prototype,"context",{get:function(){return a.context}}),a.setContext=function(t){a.context=t},Object.defineProperty(a.prototype,"blockTime",{get:function(){return 128/this.context.sampleRate}}),Object.defineProperty(a.prototype,"sampleTime",{get:function(){return 1/this.context.sampleRate}}),Object.defineProperty(a,"supported",{get:function(){var t=window.hasOwnProperty("AudioContext")||window.hasOwnProperty("webkitAudioContext"),e=window.hasOwnProperty("Promise"),n=window.hasOwnProperty("Worker");return t&&e&&n}}),a.version="r10",window.TONE_SILENCE_VERSION_LOGGING||console.log("%c * Tone.js "+a.version+" * ","background: #000; color: #fff"),a}).call(exports, __webpack_require__, exports, module),
126				__WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));
127
128 }),
129 (function(module, exports, __webpack_require__) {
130
131"use strict";
132var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;
133
134!(__WEBPACK_AMD_DEFINE_ARRAY__ = [__webpack_require__(17)], __WEBPACK_AMD_DEFINE_RESULT__ = (function (audiocontext) {
135  var Master = function Master() {
136    this.input = audiocontext.createGain();
137    this.output = audiocontext.createGain(); 
138
139    this.limiter = audiocontext.createDynamicsCompressor();
140    this.limiter.threshold.value = -3;
141    this.limiter.ratio.value = 20;
142    this.limiter.knee.value = 1;
143    this.audiocontext = audiocontext;
144    this.output.disconnect(); 
145
146    this.input.connect(this.limiter); 
147
148    this.limiter.connect(this.output); 
149
150    this.meter = audiocontext.createGain();
151    this.fftMeter = audiocontext.createGain();
152    this.output.connect(this.meter);
153    this.output.connect(this.fftMeter); 
154
155    this.output.connect(this.audiocontext.destination); 
156
157    this.soundArray = []; 
158
159    this.parts = []; 
160
161    this.extensions = [];
162  }; 
163
164
165  var p5sound = new Master();
166  /**
167   * Returns a number representing the master amplitude (volume) for sound
168   * in this sketch.
169   *
170   * @method getMasterVolume
171   * @return {Number} Master amplitude (volume) for sound in this sketch.
172   *                  Should be between 0.0 (silence) and 1.0.
173   */
174
175  p5.prototype.getMasterVolume = function () {
176    return p5sound.output.gain.value;
177  };
178  /**
179   *  <p>Scale the output of all sound in this sketch</p>
180   *  Scaled between 0.0 (silence) and 1.0 (full volume).
181   *  1.0 is the maximum amplitude of a digital sound, so multiplying
182   *  by greater than 1.0 may cause digital distortion. To
183   *  fade, provide a <code>rampTime</code> parameter. For more
184   *  complex fades, see the Envelope class.
185   *
186   *  Alternately, you can pass in a signal source such as an
187   *  oscillator to modulate the amplitude with an audio signal.
188   *
189   *  <p><b>How This Works</b>: When you load the p5.sound module, it
190   *  creates a single instance of p5sound. All sound objects in this
191   *  module output to p5sound before reaching your computer's output.
192   *  So if you change the amplitude of p5sound, it impacts all of the
193   *  sound in this module.</p>
194   *
195   *  <p>If no value is provided, returns a Web Audio API Gain Node</p>
196   *
197   *  @method  masterVolume
198   *  @param {Number|Object} volume  Volume (amplitude) between 0.0
199   *                                     and 1.0 or modulating signal/oscillator
200   *  @param {Number} [rampTime]  Fade for t seconds
201   *  @param {Number} [timeFromNow]  Schedule this event to happen at
202   *                                 t seconds in the future
203   */
204
205
206  p5.prototype.masterVolume = function (vol, rampTime, tFromNow) {
207    if (typeof vol === 'number') {
208      var rampTime = rampTime || 0;
209      var tFromNow = tFromNow || 0;
210      var now = p5sound.audiocontext.currentTime;
211      var currentVol = p5sound.output.gain.value;
212      p5sound.output.gain.cancelScheduledValues(now + tFromNow);
213      p5sound.output.gain.linearRampToValueAtTime(currentVol, now + tFromNow);
214      p5sound.output.gain.linearRampToValueAtTime(vol, now + tFromNow + rampTime);
215    } else if (vol) {
216      vol.connect(p5sound.output.gain);
217    } else {
218      return p5sound.output.gain;
219    }
220  };
221  /**
222   *  `p5.soundOut` is the p5.sound master output. It sends output to
223   *  the destination of this window's web audio context. It contains
224   *  Web Audio API nodes including a dyanmicsCompressor (<code>.limiter</code>),
225   *  and Gain Nodes for <code>.input</code> and <code>.output</code>.
226   *
227   *  @property {Object} soundOut
228   */
229
230
231  p5.prototype.soundOut = p5.soundOut = p5sound; 
232
233  p5.soundOut._silentNode = p5sound.audiocontext.createGain();
234  p5.soundOut._silentNode.gain.value = 0;
235
236  p5.soundOut._silentNode.connect(p5sound.audiocontext.destination);
237
238  return p5sound;
239}).apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__),
240				__WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));
241
242 }),
243 (function(module, exports, __webpack_require__) {
244
245var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;!(__WEBPACK_AMD_DEFINE_ARRAY__ = [__webpack_require__(0),__webpack_require__(5),__webpack_require__(8),__webpack_require__(22),__webpack_require__(9)], __WEBPACK_AMD_DEFINE_RESULT__ = (function(n){"use strict";return n.Signal=function(){var t=this.optionsObject(arguments,["value","units"],n.Signal.defaults);this.output=this._gain=this.context.createGain(),t.param=this._gain.gain,n.Param.call(this,t),this.input=this._param=this._gain.gain,this.context.getConstant(1).chain(this._gain)},n.extend(n.Signal,n.Param),n.Signal.defaults={value:0,units:n.Type.Default,convert:!0},n.Signal.prototype.connect=n.SignalBase.prototype.connect,n.Signal.prototype.dispose=function(){return n.Param.prototype.dispose.call(this),this._param=null,this._gain.disconnect(),this._gain=null,this},n.Signal}).apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__),
246				__WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));
247
248 }),
249 (function(module, exports, __webpack_require__) {
250
251var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;!(__WEBPACK_AMD_DEFINE_ARRAY__ = [__webpack_require__(0),__webpack_require__(2),__webpack_require__(9)], __WEBPACK_AMD_DEFINE_RESULT__ = (function(i){"use strict";return i.Multiply=function(t){this.createInsOuts(2,0),this._mult=this.input[0]=this.output=new i.Gain,this._param=this.input[1]=this.output.gain,this._param.value=this.defaultArg(t,0)},i.extend(i.Multiply,i.Signal),i.Multiply.prototype.dispose=function(){return i.prototype.dispose.call(this),this._mult.dispose(),this._mult=null,this._param=null,this},i.Multiply}).apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__),
252				__WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));
253
254 }),
255 (function(module, exports, __webpack_require__) {
256
257"use strict";
258var __WEBPACK_AMD_DEFINE_RESULT__;
259
260!(__WEBPACK_AMD_DEFINE_RESULT__ = (function (require) {
261  var p5sound = __webpack_require__(1);
262
263  var CrossFade = __webpack_require__(51);
264  /**
265   * Effect is a base class for audio effects in p5. <br>
266   * This module handles the nodes and methods that are
267   * common and useful for current and future effects.
268   *
269   *
270   * This class is extended by <a href="/reference/#/p5.Distortion">p5.Distortion</a>,
271   * <a href="/reference/#/p5.Compressor">p5.Compressor</a>,
272   * <a href="/reference/#/p5.Delay">p5.Delay</a>,
273   * <a href="/reference/#/p5.Filter">p5.Filter</a>,
274   * <a href="/reference/#/p5.Reverb">p5.Reverb</a>.
275   *
276   * @class  p5.Effect
277   * @constructor
278   *
279   * @param {Object} [ac]   Reference to the audio context of the p5 object
280   * @param {AudioNode} [input]  Gain Node effect wrapper
281   * @param {AudioNode} [output] Gain Node effect wrapper
282   * @param {Object} [_drywet]   Tone.JS CrossFade node (defaults to value: 1)
283   * @param {AudioNode} [wet]  Effects that extend this class should connect
284   *                              to the wet signal to this gain 
284node, so that dry and wet
285   *                              signals are mixed properly.
286   */
287
288
289  p5.Effect = function () {
290    this.ac = p5sound.audiocontext;
291    this.input = this.ac.createGain();
292    this.output = this.ac.createGain();
293    /**
294     *	The p5.Effect class is built
295     * 	using Tone.js CrossFade
296     * 	@private
297     */
298
299    this._drywet = new CrossFade(1);
300    /**
301     *	In classes that extend
302     *	p5.Effect, connect effect nodes
303     *	to the wet parameter
304     */
305
306    this.wet = this.ac.createGain();
307    this.input.connect(this._drywet.a);
308    this.wet.connect(this._drywet.b);
309
310    this._drywet.connect(this.output);
311
312    this.connect(); 
313
314    p5sound.soundArray.push(this);
315  };
316  /**
317   *  Set the output volume of the filter.
318   *
319   *  @method  amp
320   *  @for p5.Effect
321   *  @param {Number} [vol] amplitude between 0 and 1.0
322   *  @param {Number} [rampTime] create a fade that lasts until rampTime
323   *  @param {Number} [tFromNow] schedule this event to happen in tFromNow seconds
324   */
325
326
327  p5.Effect.prototype.amp = function (vol, rampTime, tFromNow) {
328    var rampTime = rampTime || 0;
329    var tFromNow = tFromNow || 0;
330    var now = p5sound.audiocontext.currentTime;
331    var currentVol = this.output.gain.value;
332    this.output.gain.cancelScheduledValues(now);
333    this.output.gain.linearRampToValueAtTime(currentVol, now + tFromNow + .001);
334    this.output.gain.linearRampToValueAtTime(vol, now + tFromNow + rampTime + .001);
335  };
336  /**
337   *  Link effects together in a chain
338   *  Example usage: filter.chain(reverb, delay, panner);
339   *  May be used with an open-ended number of arguments
340   *
341   *  @method chain
342   *  @for p5.Effect
343   *  @param {Object} [arguments]  Chain together multiple sound objects
344   */
345
346
347  p5.Effect.prototype.chain = function () {
348    if (arguments.length > 0) {
349      this.connect(arguments[0]);
350
351      for (var i = 1; i < arguments.length; i += 1) {
352        arguments[i - 1].connect(arguments[i]);
353      }
354    }
355
356    return this;
357  };
358  /**
359   *  Adjust the dry/wet value.
360   *
361   *  @method drywet
362   *  @for p5.Effect
363   *  @param {Number} [fade] The desired drywet value (0 - 1.0)
364   */
365
366
367  p5.Effect.prototype.drywet = function (fade) {
368    if (typeof fade !== "undefined") {
369      this._drywet.fade.value = fade;
370    }
371
372    return this._drywet.fade.value;
373  };
374  /**
375   *  Send output to a p5.js-sound, Web Audio Node, or use signal to
376   *  control an AudioParam
377   *
378   *  @method connect
379   *  @for p5.Effect
380   *  @param {Object} unit
381   */
382
383
384  p5.Effect.prototype.connect = function (unit) {
385    var u = unit || p5.soundOut.input;
386    this.output.connect(u.input ? u.input : u);
387  };
388  /**
389   * Disconnect all output.
390   * @method disconnect
391   * @for p5.Effect
392   */
393
394
395  p5.Effect.prototype.disconnect = function () {
396    if (this.output) {
397      this.output.disconnect();
398    }
399  };
400
401  p5.Effect.prototype.dispose = function () {
402    var index = p5sound.soundArray.indexOf(this);
403    p5sound.soundArray.splice(index, 1);
404
405    if (this.input) {
406      this.input.disconnect();
407      delete this.input;
408    }
409
410    if (this.output) {
411      this.output.disconnect();
412      delete this.output;
413    }
414
415    if (this._drywet) {
416      this._drywet.disconnect();
417
418      delete this._drywet;
419    }
420
421    if (this.wet) {
422      this.wet.disconnect();
423      delete this.wet;
424    }
425
426    this.ac = undefined;
427  };
428
429  return p5.Effect;
430}).call(exports, __webpack_require__, exports, module),
431				__WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));
432
433 }),
434 (function(module, exports, __webpack_require__) {
435
436var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;!(__WEBPACK_AMD_DEFINE_ARRAY__ = [__webpack_require__(0),__webpack_require__(19)], __WEBPACK_AMD_DEFINE_RESULT__ = (function(e){"use strict";return e.WaveShaper=function(e,t){this._shaper=this.input=this.output=this.context.createWaveShaper(),this._curve=null,Array.isArray(e)?this.curve=e:isFinite(e)||this.isUndef(e)?this._curve=new Float32Array(this.defaultArg(e,1024)):this.isFunction(e)&&(this._curve=new Float32Array(this.defaultArg(t,1024)),this.setMap(e))},e.extend(e.WaveShaper,e.SignalBase),e.WaveShaper.prototype.setMap=function(e){for(var t=0,r=this._curve.length;t<r;t++){var s=t/(r-1)*2-1;this._curve[t]=e(s,t)}return this._shaper.curve=this._curve,this},Object.defineProperty(e.WaveShaper.prototype,"curve",{get:function(){return this._shaper.curve},set:function(e){this._curve=new Float32Array(e),this._shaper.curve=this._curve}}),Object.defineProperty(e.WaveShaper.prototype,"oversample",{get:function(){return this._shaper.oversample},set:function(e){if(-1===["none","2x","4x"].indexOf(e))throw new RangeError("Tone.WaveShaper: oversampling must be either 'none', '2x', or '4x'");this._shaper.oversample=e}}),e.WaveShaper.prototype.dispose=function(){return e.prototype.dispose.call(this),this._shaper.disconnect(),this._shaper=null,this._curve=null,this},e.WaveShaper}).apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__),
437				__WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));
438
439 }),
440 (function(module, exports, __webpack_require__) {
441
442"use strict";
443var __WEBPACK_AMD_DEFINE_RESULT__;
444
445function _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); }
446
447!(__WEBPACK_AMD_DEFINE_RESULT__ = (function (require) {
448  var p5sound = __webpack_require__(1);
449
450  var processorNames = __webpack_require__(10);
451  /**
452   * @for p5
453   */
454
455  /**
456   * Returns a number representing the sample rate, in samples per second,
457   * of all sound objects in this audio context. It is determined by the
458   * sampling rate of your operating system's sound card, and it is not
459   * currently possile to change.
460   * It is often 44100, or twice the range of human hearing.
461   *
462   * @method sampleRate
463   * @return {Number} samplerate samples per second
464   */
465
466
467  p5.prototype.sampleRate = function () {
468    return p5sound.audiocontext.sampleRate;
469  };
470  /**
471   *  Returns the closest MIDI note value for
472   *  a given frequency.
473   *
474   *  @method freqToMidi
475   *  @param  {Number} frequency A freqeuncy, for example, the "A"
476   *                             above Middle C is 440Hz
477   *  @return {Number}   MIDI note value
478   */
479
480
481  p5.prototype.freqToMidi = function (f) {
482    var mathlog2 = Math.log(f / 440) / Math.log(2);
483    var m = Math.round(12 * mathlog2) + 69;
484    return m;
485  };
486  /**
487   *  Returns the frequency value of a MIDI note value.
488   *  General MIDI treats notes as integers where middle C
489   *  is 60, C# is 61, D is 62 etc. Useful for generating
490   *  musical frequencies with oscillators.
491   *
492   *  @method  midiToFreq
493   *  @param  {Number} midiNote The number of a MIDI note
494   *  @return {Number} Frequency value of the given MIDI note
495   *  @example
496   *  <div><code>
497   *  let midiNotes = [60, 64, 67, 72];
498   *  let noteIndex = 0;
499   *  let midiVal, freq;
500   *
501   *  function setup() {
502   *    let cnv = createCanvas(100, 100);
503   *    cnv.mousePressed(startSound);
504   *    osc = new p5.TriOsc();
505   *    env = new p5.Envelope();
506   *  }
507   *
508   *  function draw() {
509   *    background(220);
510   *    text('tap to play', 10, 20);
511   *    if (midiVal) {
512   *      text('MIDI: ' + midiVal, 10, 40);
513   *      text('Freq: ' + freq, 10, 60);
514   *    }
515   *  }
516   *
517   *  function startSound() {
518   *    // see also: userStartAudio();
519   *    osc.start();
520   *
521   *    midiVal = midiNotes[noteIndex % midiNotes.length];
522   *    freq = midiToFreq(midiVal);
523   *    osc.freq(freq);
524   *    env.ramp(osc, 0, 1.0, 0);
525   *
526   *    noteIndex++;
527   *  }
528   *  </code></div>
529   */
530
531
532  var midiToFreq = p5.prototype.midiToFreq = function (m) {
533    return 440 * Math.pow(2, (m - 69) / 12.0);
534  }; 
535
536
537  var noteToFreq = function noteToFreq(note) {
538    if (typeof note !== 'string') {
539      return note;
540    }
541
542    var wholeNotes = {
543      A: 21,
544      B: 23,
545      C: 24,
546      D: 26,
547      E: 28,
548      F: 29,
549      G: 31
550    };
551    var value = wholeNotes[note[0].toUpperCase()];
552    var octave = ~~note.slice(-1);
553    value += 12 * (octave - 1);
554
555    switch (note[1]) {
556      case '#':
557        value += 1;
558        break;
559
560      case 'b':
561        value -= 1;
562        break;
563
564      default:
565        break;
566    }
567
568    return midiToFreq(value);
569  };
570  /**
571   *  List the SoundFile formats that you will include. LoadSound
572   *  will search your directory for these extensions, and will pick
573   *  a format that is compatable with the client's web browser.
574   *  <a href="http://media.io/">Here</a> is a free online file
575   *  converter.
576   *
577   *  @method soundFormats
578   *  @param {String} [...formats] i.e. 'mp3', 'wav', 'ogg'
579   *  @example
580   *  <div><code>
581   *  function preload() {
582   *    // set the global sound formats
583   *    soundFormats('mp3', 'ogg');
584   *
585   *    // load either beatbox.mp3, or .ogg, depending on browser
586   *    mySound = loadSound('assets/beatbox.mp3');
587   *  }
588   *
589   *  function setup() {
590   *       let cnv = createCanvas(100, 100);
591   *       background(220);
592   *       text('sound loaded! tap to play', 10, 20, width - 20);
593   *       cnv.mousePressed(function() {
594   *         mySound.play();
595   *       });
596   *     }
597   *  </code></div>
598   */
599
600
601  p5.prototype.soundFormats = function () {
602    p5sound.extensions = []; 
603
604    for (var i = 0; i < arguments.length; i++) {
605      arguments[i] = arguments[i].toLowerCase();
606
607      if (['mp3', 'wav', 'ogg', 'm4a', 'aac'].indexOf(arguments[i]) > -1) {
608        p5sound.extensions.push(arguments[i]);
609      } else {
610        throw arguments[i] + ' is not a valid sound format!';
611      }
612    }
613  };
614
615  p5.prototype.disposeSound = function () {
616    for (var i = 0; i < p5sound.soundArray.length; i++) {
617      p5sound.soundArray[i].dispose();
618    }
619  }; 
620
621
622  p5.prototype.registerMethod('remove', p5.prototype.disposeSound);
623
624  p5.prototype._checkFileFormats = function (paths) {
625    var path; 
626
627    if (typeof paths === 'string') {
628      path = paths; 
629
630      var extTest = path.split('.').pop(); 
631
632      if (['mp3', 'wav', 'ogg', 'm4a', 'aac'].indexOf(extTest) > -1) {
633        if (p5.prototype.isFileSupported(extTest)) {
634          path = path;
635        } else {
636          var pathSplit = path.split('.');
637          var pathCore = pathSplit[pathSplit.length - 1];
638
639          for (var i = 0; i < p5sound.extensions.length; i++) {
640            var extension = p5sound.extensions[i];
641            var supported = p5.prototype.isFileSupported(extension);
642
643            if (supported) {
644              pathCore = '';
645
646              if (pathSplit.length === 2) {
647                pathCore += pathSplit[0];
648              }
649
650              for (var i = 1; i <= pathSplit.length - 2; i++) {
651                var p = pathSplit[i];
652                pathCore += '.' + p;
653              }
654
655              path = pathCore += '.';
656              path = path += extension;
657              break;
658            }
659          }
660        }
661      } 
662      else {
663          for (var i = 0; i < p5sound.extensions.length; i++) {
664            var extension = p5sound.extensions[i];
665            var supported = p5.prototype.isFileSupported(extension);
666
667            if (supported) {
668              path = path + '.' + extension;
669              break;
670            }
671          }
672        }
673    } 
674    else if (_typeof(paths) === 'object') {
675        for (var i = 0; i < paths.length; i++) {
676          var extension = paths[i].split('.').pop();
677          var supported = p5.prototype.isFileSupported(extension);
678
679          if (supported) {
680            path = paths[i];
681            break;
682          }
683        }
684      }
685
686    return path;
687  };
688  /**
689   *  Used by Osc and Envelope to chain signal math
690   */
691
692
693  p5.prototype._mathChain = function (o, math, thisChain, nextChain, type) {
694    for (var i in o.mathOps) {
695      if (o.mathOps[i] instanceof type) {
696        o.mathOps[i].dispose();
697        thisChain = i;
698
699        if (thisChain < o.mathOps.length - 1) {
700          nextChain = o.mathOps[i + 1];
701        }
702      }
703    }
704
705    o.mathOps[thisChain - 1].disconnect();
706    o.mathOps[thisChain - 1].connect(math);
707    math.connect(nextChain);
708    o.mathOps[thisChain] = math;
709    return o;
710  }; 
711
712
713  function convertToWav(audioBuffer) {
714    var leftChannel, rightChannel;
715    leftChannel = audioBuffer.getChannelData(0); 
716
717    if (audioBuffer.numberOfChannels > 1) {
718      rightChannel = audioBuffer.getChannelData(1);
719    } else {
720      rightChannel = leftChannel;
721    }
722
723    var interleaved = interleave(leftChannel, rightChannel); 
724
725    var buffer = new window.ArrayBuffer(44 + interleaved.length * 2);
726    var view = new window.DataView(buffer); 
727
728    writeUTFBytes(view, 0, 'RIFF');
729    view.setUint32(4, 36 + interleaved.length * 2, true);
730    writeUTFBytes(view, 8, 'WAVE'); 
731
732    writeUTFBytes(view, 12, 'fmt ');
733    view.setUint32(16, 16, true);
734    view.setUint16(20, 1, true); 
735
736    view.setUint16(22, 2, true);
737    view.setUint32(24, p5sound.audiocontext.sampleRate, true);
738    view.setUint32(28, p5sound.audiocontext.sampleRate * 4, true);
739    view.setUint16(32, 4, true);
740    view.setUint16(34, 16, true); 
741
742    writeUTFBytes(view, 36, 'data');
743    view.setUint32(40, interleaved.length * 2, true); 
744
745    var lng = interleaved.length;
746    var index = 44;
747    var volume = 1;
748
749    for (var i = 0; i < lng; i++) {
750      view.setInt16(index, interleaved[i] * (0x7FFF * volume), true);
751      index += 2;
752    }
753
754    return view;
755  } 
756
757
758  function interleave(leftChannel, rightChannel) {
759    var length = leftChannel.length + rightChannel.length;
760    var result = new Float32Array(length);
761    var inputIndex = 0;
762
763    for (var index = 0; index < length;) {
764      result[index++] = leftChannel[inputIndex];
765      result[index++] = rightChannel[inputIndex];
766      inputIndex++;
767    }
768
769    return result;
770  }
771
772  function writeUTFBytes(view, offset, string) {
773    var lng = string.length;
774
775    for (var i = 0; i < lng; i++) {
776      view.setUint8(offset + i, string.charCodeAt(i));
777    }
778  }
779
780  function safeBufferSize(idealBufferSize) {
781    var bufferSize = idealBufferSize; 
782
783    var tempAudioWorkletNode = new AudioWorkletNode(p5sound.audiocontext, processorNames.soundFileProcessor);
784
785    if (tempAudioWorkletNode instanceof ScriptProcessorNode) {
786      bufferSize = tempAudioWorkletNode.bufferSize;
787    }
788
789    tempAudioWorkletNode.disconnect();
790    tempAudioWorkletNode = null;
791    return bufferSize;
792  }
793
794  return {
795    convertToWav: convertToWav,
796    midiToFreq: midiToFreq,
797    noteToFreq: noteToFreq,
798    safeBufferSize: safeBufferSize
799  };
800}).call(exports, __webpack_require__, exports, module),
801				__WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));
802
803 }),
804 (function(module, exports, __webpack_require__) {
805
806var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;!(__WEBPACK_AMD_DEFINE_ARRAY__ = [__webpack_require__(0),__webpack_require__(2),__webpack_require__(9)], __WEBPACK_AMD_DEFINE_RESULT__ = (function(i){"use strict";return i.Add=function(t){this.createInsOuts(2,0),this._sum=this.input[0]=this.input[1]=this.output=new i.Gain,this._param=this.input[1]=new i.Signal(t),this._param.connect(this._sum)},i.extend(i.Add,i.Signal),i.Add.prototype.dispose=function(){return i.prototype.dispose.call(this),this._sum.dispose(),this._sum=null,this._param.dispose(),this._param=null,this},i.Add}).apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__),
807				__WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));
808
809 }),
810 (function(module, exports, __webpack_require__) {
811
812var __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__(12)], __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__),
813				__WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));
814
815 }),
816 (function(module, exports, __webpack_require__) {
817
818var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;!(__WEBPACK_AMD_DEFINE_ARRAY__ = [__webpack_require__(0),__webpack_require__(22),__webpack_require__(8)], __WEBPACK_AMD_DEFINE_RESULT__ = (function(i){"use strict";return window.GainNode&&!AudioContext.prototype.createGain&&(AudioContext.prototype.createGain=AudioContext.prototype.createGainNode),i.Gain=function(){var t=this.optionsObject(arguments,["gain","units"],i.Gain.defaults);this.input=this.output=this._gainNode=this.context.createGain(),this.gain=new i.Param({param:this._gainNode.gain,units:t.units,value:t.gain,convert:t.convert}),this._readOnly("gain")},i.extend(i.Gain),i.Gain.defaults={gain:1,convert:!0},i.Gain.prototype.dispose=function(){i.Param.prototype.dispose.call(this),this._gainNode.disconnect(),this._gainNode=null,this._writable("gain"),this.gain.dispose(),this.gain=null},i.prototype.createInsOuts=function(t,n){1===t?this.input=new i.Gain:1<t&&(this.input=new Array(t)),1===n?this.output=new i.Gain:1<n&&(this.output=new Array(t))},i.Gain}).apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__),
819				__WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));
820
821 }),
822 (function(module, exports) {
823
824module.exports = {
825  recorderProcessor: 'recorder-processor',
826  soundFileProcessor: 'sound-file-processor',
827  amplitudeProcessor: 'amplitude-processor'
828};
829
830 }),
831 (function(module, exports, __webpack_require__) {
832
833"use strict";
834var __WEBPACK_AMD_DEFINE_RESULT__;
835
836!(__WEBPACK_AMD_DEFINE_RESULT__ = (function () {
837  var CustomError = function CustomError(name, errorTrace, failedPath) {
838    var err = new Error();
839    var tempStack, splitStack;
840    err.name = name;
841    err.originalStack = err.stack + errorTrace;
842    tempStack = err.stack + errorTrace;
843    err.failedPath = failedPath; 
844
845    var splitStack = tempStack.split('\n');
846    splitStack = splitStack.filter(function (ln) {
847      return !ln.match(/(p5.|native code|globalInit)/g);
848    });
849    err.stack = splitStack.join('\n');
850    return err; 
851  };
852
853  return CustomError;
854}).call(exports, __webpack_require__, exports, module),
855				__WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));
856
857 }),
858 (function(module, exports, __webpack_require__) {
859
860var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;!(__WEBPACK_AMD_DEFINE_ARRAY__ = [__webpack_require__(0),__webpack_require__(18)], __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;o<n.length;o++)n[o]=t;var i=this._context.createBufferSource();return i.channelCount=1,i.channelCountMode="explicit",i.buffer=e,i.loop=!0,i.start(0),this._constants[t]=i},Object.defineProperty(o.Context.prototype,"lag",{get:function(){var t=this._computedUpdateInterval-this._updateInterval;return t=Math.max(t,0)}}),Object.defineProperty(o.Context.prototype,"lookAhead",{get:function(){return this._lookAhead},set:function(t){this._lookAhead=t}}),Object.defineProperty(o.Context.prototype,"updateInterval",{get:function(){return this._updateInterval},set:function(t){this._updateInterval=Math.max(t,o.prototype.blockTime),this._worker.postMessage(Math.max(1e3*t,1))}}),Object.defineProperty(o.Context.prototype,"latencyHint",{get:function(){return this._latencyHint},set:function(t){var e=t;if(this._latencyHint=t,this.isString(t))switch(t){case"interactive":e=.1,this._context.latencyHint=t;break;case"playback":e=.8,this._context.latencyHint=t;break;case"balanced":e=.25,this._context.latencyHint=t;break;case"fastest":e=.01}this.lookAhead=e,this.updateInterval=e/3}}),o.supported?(i=AudioNode.prototype.connect,r=AudioNode.prototype.disconnect,AudioNode.prototype.connect!==t&&(AudioNode.prototype.connect=t,AudioNode.prototype.disconnect=function(e,t,n){if(e&&e.input&&Array.isArray(e.input))o.prototype.isUndef(n)&&(n=0),this.disconnect(e.input[n],t,n);else if(e&&e.input)this.disconnect(e.input,t,n);else try{r.apply(this,arguments)}catch(t){throw new Error("error disconnecting node: "+e+"\n"+t)}}),o.context=new o.Context):console.warn("This browser does not support Tone.js"),o.Context}).apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__),
861				__WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));
862
863 }),
864 (function(module, exports, __webpack_require__) {
865
866var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;!(__WEBPACK_AMD_DEFINE_ARRAY__ = [__webpack_require__(0),__webpack_require__(7),__webpack_require__(3),__webpack_require__(2)], __WEBPACK_AMD_DEFINE_RESULT__ = (function(i){"use strict";return i.Scale=function(t,e){this._outputMin=this.defaultArg(t,0),this._outputMax=this.defaultArg(e,1),this._scale=this.input=new i.Multiply(1),this._add=this.output=new i.Add(0),this._scale.connect(this._add),this._setRange()},i.extend(i.Scale,i.SignalBase),Object.defineProperty(i.Scale.prototype,"min",{get:function(){return this._outputMin},set:function(t){this._outputMin=t,this._setRange()}}),Object.defineProperty(i.Scale.prototype,"max",{get:function(){return this._outputMax},set:function(t){this._outputMax=t,this._setRange()}}),i.Scale.prototype._setRange=function(){this._add.value=this._outputMin,this._scale.value=this._outputMax-this._outputMin},i.Scale.prototype.dispose=function(){return i.prototype.dispose.call(this),this._add.dispose(),this._add=null,this._scale.dispose(),this._scale=null,this},i.Scale}).apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__),
867				__WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));
868
869 }),
870 (function(module, exports, __webpack_require__) {
871
872var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;!(__WEBPACK_AMD_DEFINE_ARRAY__ = [__webpack_require__(0),__webpack_require__(2),__webpack_require__(24)], __WEBPACK_AMD_DEFINE_RESULT__ = (function(o){"use strict";return o.TimelineSignal=function(){var e=this.optionsObject(arguments,["value","units"],o.Signal.defaults);this._events=new o.Timeline(10),o.Signal.apply(this,e),e.param=this._param,o.Param.call(this,e),this._initial=this._fromUnits(this._param.value)},o.extend(o.TimelineSignal,o.Param),o.TimelineSignal.Type={Linear:"linear",Exponential:"exponential",Target:"target",Curve:"curve",Set:"set"},Object.defineProperty(o.TimelineSignal.prototype,"value",{get:function(){var e=this.now(),t=this.getValueAtTime(e);return this._toUnits(t)},set:function(e){var t=this._fromUnits(e);this._initial=t,this.cancelScheduledValues(),this._param.value=t}}),o.TimelineSignal.prototype.setValueAtTime=function(e,t){return e=this._fromUnits(e),t=this.toSeconds(t),this._events.add({type:o.TimelineSignal.Type.Set,value:e,time:t}),this._param.setValueAtTime(e,t),this},o.TimelineSignal.prototype.linearRampToValueAtTime=function(e,t){return e=this._fromUnits(e),t=this.toSeconds(t),this._events.add({type:o.TimelineSignal.Type.Linear,value:e,time:t}),this._param.linearRampToValueAtTime(e,t),this}
872,o.TimelineSignal.prototype.exponentialRampToValueAtTime=function(e,t){t=this.toSeconds(t);var i=this._searchBefore(t);i&&0===i.value&&this.setValueAtTime(this._minOutput,i.time),e=this._fromUnits(e);var n=Math.max(e,this._minOutput);return this._events.add({type:o.TimelineSignal.Type.Exponential,value:n,time:t}),e<this._minOutput?(this._param.exponentialRampToValueAtTime(this._minOutput,t-this.sampleTime),this.setValueAtTime(0,t)):this._param.exponentialRampToValueAtTime(e,t),this},o.TimelineSignal.prototype.setTargetAtTime=function(e,t,i){return e=this._fromUnits(e),e=Math.max(this._minOutput,e),i=Math.max(this._minOutput,i),t=this.toSeconds(t),this._events.add({type:o.TimelineSignal.Type.Target,value:e,time:t,constant:i}),this._param.setTargetAtTime(e,t,i),this},o.TimelineSignal.prototype.setValueCurveAtTime=function(e,t,i,n){n=this.defaultArg(n,1);for(var a=new Array(e.length),l=0;l<a.length;l++)a[l]=this._fromUnits(e[l])*n;t=this.toSeconds(t),i=this.toSeconds(i),this._events.add({type:o.TimelineSignal.Type.Curve,value:a,time:t,duration:i}),this._param.setValueAtTime(a[0],t);for(var s=1;s<a.length;s++){var r=t+s/(a.length-1)*i;this._param.linearRampToValueAtTime(a[s],r)}return this},o.TimelineSignal.prototype.cancelScheduledValues=function(e){return e=this.toSeconds(e),this._events.cancel(e),this._param.cancelScheduledValues(e),this},o.TimelineSignal.prototype.setRampPoint=function(e){e=this.toSeconds(e);var t=this._toUnits(this.getValueAtTime(e)),i=this._searchBefore(e);if(i&&i.time===e)this.cancelScheduledValues(e+this.sampleTime);else if(i&&i.type===o.TimelineSignal.Type.Curve&&i.time+i.duration>e)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__),
873				__WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));
874
875 }),
876 (function(module, exports, __webpack_require__) {
877
878"use strict";
879var __WEBPACK_AMD_DEFINE_RESULT__;
880
881!(__WEBPACK_AMD_DEFINE_RESULT__ = (function (require) {
882  var Effect = __webpack_require__(4);
883  /**
884   *  <p>A p5.Filter uses a Web Audio Biquad Filter to filter
885   *  the frequency response of an input source. Subclasses
886   *  include:</p>
887   *  <a href="/reference/#/p5.LowPass"><code>p5.LowPass</code></a>:
888   *  Allows frequencies below the cutoff frequency to pass through,
889   *  and attenuates frequencies above the cutoff.<br/>
890   *  <a href="/reference/#/p5.HighPass"><code>p5.HighPass</code></a>:
891   *  The opposite of a lowpass filter. <br/>
892   *  <a href="/reference/#/p5.BandPass"><code>p5.BandPass</code></a>:
893   *  Allows a range of frequencies to pass through and attenuates
894   *  the frequencies below and above this frequency range.<br/>
895   *
896   *  The <code>.res()</code> method controls either width of the
897   *  bandpass, or resonance of the low/highpass cutoff frequency.
898   *
899   *  This class extends <a href = "/reference/#/p5.Effect">p5.Effect</a>.
900   *  Methods <a href = "/reference/#/p5.Effect/amp">amp()</a>, <a href = "/reference/#/p5.Effect/chain">chain()</a>,
901   *  <a href = "/reference/#/p5.Effect/drywet">drywet()</a>, <a href = "/reference/#/p5.Effect/connect">connect()</a>, and
902   *  <a href = "/reference/#/p5.Effect/disconnect">disconnect()</a> are available.
903   *
904   *  @class p5.Filter
905   *  @extends p5.Effect
906   *  @constructor
907   *  @param {String} [type] 'lowpass' (default), 'highpass', 'bandpass'
908   *  @example
909   *  <div><code>
910  *  let fft, noise, filter;
911  *
912  *  function setup() {
913  *    let cnv = createCanvas(100,100);
914  *    cnv.mousePressed(makeNoise);
915  *    fill(255, 0, 255);
916  *
917  *    filter = new p5.BandPass();
918  *    noise = new p5.Noise();
919  *    noise.disconnect();
920  *    noise.connect(filter);
921  *
922  *    fft = new p5.FFT();
923  *  }
924  *
925  *  function draw() {
926  *    background(220);
927  *
928  *    // set the BandPass frequency based on mouseX
929  *    let freq = map(mouseX, 0, width, 20, 10000);
930  *    freq = constrain(freq, 0, 22050);
931  *    filter.freq(freq);
932  *    // give the filter a narrow band (lower res = wider bandpass)
933  *    filter.res(50);
934  *
935  *    // draw filtered spectrum
936  *    let spectrum = fft.analyze();
937  *    noStroke();
938  *    for (let i = 0; i < spectrum.length; i++) {
939  *      let x = map(i, 0, spectrum.length, 0, width);
940  *      let h = -height + map(spectrum[i], 0, 255, height, 0);
941  *      rect(x, height, width/spectrum.length, h);
942  *    }
943  *    if (!noise.started) {
944  *      text('tap here and drag to change frequency', 10, 20, width - 20);
945  *    } else {
946  *      text('Frequency: ' + round(freq)+'Hz', 20, 20, width - 20);
947  *    }
948  *  }
949  *
950  *  function makeNoise() {
951  *    // see also: `userStartAudio()`
952  *    noise.start();
953  *    noise.amp(0.5, 0.2);
954  *  }
955  *
956  *  function mouseReleased() {
957  *    noise.amp(0, 0.2);
958  *  }
959  *
960   *  </code></div>
961   */
962
963
964  p5.Filter = function (type) {
965    Effect.call(this); 
966
967    /**
968      *  The p5.Filter is built with a
969      *  <a href="http://www.w3.org/TR/webaudio/#BiquadFilterNode">
970      *  Web Audio BiquadFilter Node</a>.
971      *
972      *  @property {DelayNode} biquadFilter
973    */
974
975    this.biquad = this.ac.createBiquadFilter();
976    this.input.connect(this.biquad);
977    this.biquad.connect(this.wet);
978
979    if (type) {
980      this.setType(type);
981    } 
982
983
984    this._on = true;
985    this._untoggledType = this.biquad.type;
986  };
987
988  p5.Filter.prototype = Object.create(Effect.prototype);
989  /**
990   *  Filter an audio signal according to a set
991   *  of filter parameters.
992   *
993   *  @method  process
994   *  @param  {Object} Signal  An object that outputs audio
995   *  @param {Number} [freq] Frequency in Hz, from 10 to 22050
996   *  @param {Number} [res] Resonance/Width of the filter frequency
997   *                        from 0.001 to 1000
998   */
999
1000  p5.Filter.prototype.process = function (src, freq, res, time) {
1001    src.connect(this.input);
1002    this.set(freq, res, time);
1003  };
1004  /**
1005   *  Set the frequency and the resonance of the filter.
1006   *
1007   *  @method  set
1008   *  @param {Number} [freq] Frequency in Hz, from 10 to 22050
1009   *  @param {Number} [res]  Resonance (Q) from 0.001 to 1000
1010   *  @param {Number} [timeFromNow] schedule this event to happen
1011   *                                seconds from now
1012   */
1013
1014
1015  p5.Filter.prototype.set = function (freq, res, time) {
1016    if (freq) {
1017      this.freq(freq, time);
1018    }
1019
1020    if (res) {
1021      this.res(res, time);
1022    }
1023  };
1024  /**
1025   *  Set the filter frequency, in Hz, from 10 to 22050 (the range of
1026   *  human hearing, although in reality most people hear in a narrower
1027   *  range).
1028   *
1029   *  @method  freq
1030   *  @param  {Number} freq Filter Frequency
1031   *  @param {Number} [timeFromNow] schedule this event to happen
1032   *                                seconds from now
1033   *  @return {Number} value  Returns the current frequency value
1034   */
1035
1036
1037  p5.Filter.prototype.freq = function (freq, time) {
1038    var t = time || 0;
1039
1040    if (freq <= 0) {
1041      freq = 1;
1042    }
1043
1044    if (typeof freq === 'number') {
1045      this.biquad.frequency.cancelScheduledValues(this.ac.currentTime + 0.01 + t);
1046      this.biquad.frequency.exponentialRampToValueAtTime(freq, this.ac.currentTime + 0.02 + t);
1047    } else if (freq) {
1048      freq.connect(this.biquad.frequency);
1049    }
1050
1051    return this.biquad.frequency.value;
1052  };
1053  /**
1054   *  Controls either width of a bandpass frequency,
1055   *  or the resonance of a low/highpass cutoff frequency.
1056   *
1057   *  @method  res
1058   *  @param {Number} res  Resonance/Width of filter freq
1059   *                       from 0.001 to 1000
1060   *  @param {Number} [timeFromNow] schedule this event to happen
1061   *                                seconds from now
1062   *  @return {Number} value Returns the current res value
1063   */
1064
1065
1066  p5.Filter.prototype.res = function (res, time) {
1067    var t = time || 0;
1068
1069    if (typeof res === 'number') {
1070      this.biquad.Q.value = res;
1071      this.biquad.Q.cancelScheduledValues(this.ac.currentTime + 0.01 + t);
1072      this.biquad.Q.linearRampToValueAtTime(res, this.ac.currentTime + 0.02 + t);
1073    } else if (res) {
1074      res.connect(this.biquad.Q);
1075    }
1076
1077    return this.biquad.Q.value;
1078  };
1079  /**
1080   * Controls the gain attribute of a Biquad Filter.
1081   * This is distinctly different from .amp() which is inherited from p5.Effect
1082   * .amp() controls the volume via the output gain node
1083   * p5.Filter.gain() controls the gain parameter of a Biquad Filter node.
1084   *
1085   * @method gain
1086   * @param  {Number} gain
1087   * @return {Number} Returns the current or updated gain value
1088   */
1089
1090
1091  p5.Filter.prototype.gain = function (gain, time) {
1092    var t = time || 0;
1093
1094    if (typeof gain === 'number') {
1095      this.biquad.gain.value = gain;
1096      this.biquad.gain.cancelScheduledValues(this.ac.currentTime + 0.01 + t);
1097      this.biquad.gain.linearRampToValueAtTime(gain, this.ac.currentTime + 0.02 + t);
1098    } else if (gain) {
1099      gain.connect(this.biquad.gain);
1100    }
1101
1102    return this.biquad.gain.value;
1103  };
1104  /**
1105   * Toggle function. Switches between the specified type and allpass
1106   *
1107   * @method toggle
1108   * @return {boolean} [Toggle value]
1109   */
1110
1111
1112  p5.Filter.prototype.toggle = function () {
1113    this._on = !this._on;
1114
1115    if (this._on === true) {
1116      this.biquad.type = this._untoggledType;
1117    } else if (this._on === false) {
1118      this.biquad.type = 'allpass';
1119    }
1120
1121    return this._on;
1122  };
1123  /**
1124   *  Set the type of a p5.Filter. Possible types include:
1125   *  "lowpass" (default), "highpass", "bandpass",
1126   *  "lowshelf", "highshelf", "peaking", "notch",
1127   *  "allpass".
1128   *
1129   *  @method  setType
1130   *  @param {String} t
1131   */
1132
1133
1134  p5.Filter.prototype.setType = function (t) {
1135    this.biquad.type = t;
1136    this._untoggledType = this.biquad.type;
1137  };
1138
1139  p5.Filter.prototype.dispose = function () {
1140    Effect.prototype.dispose.apply(this);
1141
1142    if (this.biquad) {
1143      this.biquad.disconnect();
1144      delete this.biquad;
1145    }
1146  };
1147  /**
1148   *  Constructor: <code>new p5.LowPass()</code> Filter.
1149   *  This is the same as creating a p5.Filter and then calling
1150   *  its method <code>setType('lowpass')</code>.
1151   *  See p5.Filter for methods.
1152   *
1153   *  @class p5.LowPass
1154   *  @constructor
1155   *  @extends p5.Filter
1156   */
1157
1158
1159  p5.LowPass = function () {
1160    p5.Filter.call(this, 'lowpass');
1161  };
1162
1163  p5.LowPass.prototype = Object.create(p5.Filter.prototype);
1164  /**
1165   *  Constructor: <code>new p5.HighPass()</code> Filter.
1166   *  This is the same as creating a p5.Filter and then calling
1167   *  its method <code>setType('highpass')</code>.
1168   *  See p5.Filter for methods.
1169   *
1170   *  @class p5.HighPass
1171   *  @constructor
1172   *  @extends p5.Filter
1173   */
1174
1175  p5.HighPass = function () {
1176    p5.Filter.call(this, 'highpass');
1177  };
1178
1179  p5.HighPass.prototype = Object.create(p5.Filter.prototype);
1180  /**
1181   *  Constructor: <code>new p5.BandPass()</code> Filter.
1182   *  This is the same as creating a p5.Filter and then calling
1183   *  its method <code>setType('bandpass')</code>.
1184   *  See p5.Filter for methods.
1185   *
1186   *  @class p5.BandPass
1187   *  @constructor
1188   *  @extends p5.Filter
1189   */
1190
1191  p5.BandPass = function () {
1192    p5.Filter.call(this, 'bandpass');
1193  };
1194
1195  p5.BandPass.prototype = Object.create(p5.Filter.prototype);
1196  return p5.Filter;
1197}).call(exports, __webpack_require__, exports, module),
1198				__WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));
1199
1200 }),
1201 (function(module, exports, __webpack_require__) {
1202
1203var __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__),
1204				__WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));
1205
1206 }),
1207 (function(module, exports, __webpack_require__) {
1208
1209"use strict";
1210(function(global) {var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;
1211
1212global.TONE_SILENCE_VERSION_LOGGING = true;
1213!(__WEBPACK_AMD_DEFINE_ARRAY__ = [__webpack_require__(35), __webpack_require__(12), __webpack_require__(0)], __WEBPACK_AMD_DEFINE_RESULT__ = (function (StartAudioContext, Context, Tone) {
1214  var audiocontext = new window.AudioContext(); 
1215
1216  Tone.context.dispose();
1217  Tone.setContext(audiocontext);
1218  /**
1219   * <p>Returns the Audio Context for this sketch. Useful for users
1220   * who would like to dig deeper into the <a target='_blank' href=
1221   * 'http://webaudio.github.io/web-audio-api/'>Web Audio API
1222   * </a>.</p>
1223   *
1224   * <p>Some browsers require users to startAudioContext
1225   * with a user gesture, such as touchStarted in the example below.</p>
1226   *
1227   * @for p5
1228   * @method getAudioContext
1229   * @return {Object}    AudioContext for this sketch
1230   * @example
1231   * <div><code>
1232   *  function draw() {
1233   *    background(255);
1234   *    textAlign(CENTER);
1235   *
1236   *    if (getAudioContext().state !== 'running') {
1237   *      text('click to start audio', width/2, height/2);
1238   *    } else {
1239   *      text('audio is enabled', width/2, height/2);
1240   *    }
1241   *  }
1242   *
1243   *  function touchStarted() {
1244   *    if (getAudioContext().state !== 'running') {
1245   *      getAudioContext().resume();
1246   *    }
1247   *    var synth = new p5.MonoSynth();
1248   *    synth.play('A4', 0.5, 0, 0.2);
1249   *  }
1250   *
1251   * </div></code>
1252   */
1253
1254  p5.prototype.getAudioContext = function () {
1255    return audiocontext;
1256  };
1257  /**
1258   *  <p>It is not only a good practice to give users control over starting
1259   *  audio. This policy is enforced by many web browsers, including iOS and
1260   *  <a href="https://goo.gl/7K7WLu" title="Google Chrome's autoplay
1261   *  policy">Google Chrome</a>, which create the Web Audio API's
1262   *  <a href="https://developer.mozilla.org/en-US/docs/Web/API/AudioContext"
1263   *  title="Audio Context @ MDN">Audio Context</a>
1264   *  in a suspended state.</p>
1265   *
1266   *  <p>In these browser-specific policies, sound will not play until a user
1267   *  interaction event (i.e. <code>mousePressed()</code>) explicitly resumes
1268   *  the AudioContext, or starts an audio node. This can be accomplished by
1269   *  calling <code>start()</code> on a <code>p5.Oscillator</code>,
1270   *  <code> play()</code> on a <code>p5.SoundFile</code>, or simply
1271   *  <code>userStartAudio()</code>.</p>
1272   *
1273   *  <p><code>userStartAudio()</code> starts the AudioContext on a user
1274   *  gesture. The default behavior will enable audio on any
1275   *  mouseUp or touchEnd event. It can also be placed in a specific
1276   *  interaction function, such as <code>mousePressed()</code> as in the
1277   *  example below. This method utilizes
1278   *  <a href="https://github.com/tambien/StartAudioContext">StartAudioContext
1279   *  </a>, a library by Yotam Mann (MIT Licence, 2016).</p>
1280   *  @param  {Element|Array}   [element(s)] This argument can be an Element,
1281   *                                Selector String, NodeList, p5.Element,
1282   *                                jQuery Element, or an Array of any of those.
1283   *  @param  {Function} [callback] Callback to invoke when the AudioContext
1284   *                                has started
1285   *  @return {Promise}            Returns a Promise that resolves when
1286   *                                       the AudioContext state is 'running'
1287   *  @method userStartAudio
1288   *  @for p5
1289   *  @example
1290   *  <div><code>
1291   *  function setup() {
1292   *    // mimics the autoplay policy
1293   *    getAudioContext().suspend();
1294   *
1295   *    let mySynth = new p5.MonoSynth();
1296   *
1297   *    // This won't play until the context has resumed
1298   *    mySynth.play('A6');
1299   *  }
1300   *  function draw() {
1301   *    background(220);
1302   *    textAlign(CENTER, CENTER);
1303   *    text(getAudioContext().state, width/2, height/2);
1304   *  }
1305   *  function mousePressed() {
1306   *    userStartAudio();
1307   *  }
1308   *  </code></div>
1309   */
1310
1311
1312  p5.prototype.userStartAudio = function (elements, callback) {
1313    var elt = elements;
1314
1315    if (elements instanceof p5.Element) {
1316      elt = elements.elt;
1317    } else if (elements instanceof Array && elements[0] instanceof p5.Element) {
1318      elt = elements.map(function (e) {
1319        return e.elt;
1320      });
1321    }
1322
1323    return StartAudioContext(audiocontext, elt, callback);
1324  };
1325
1326  return audiocontext;
1327}).apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__),
1328				__WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));
1329}.call(this, __webpack_require__(34)))
1330
1331 }),
1332 (function(module, exports, __webpack_require__) {
1333
1334var __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;r<i.length;r++){var n=i[r];this._events.hasOwnProperty(n)||(this._events[n]=[]),this._events[n].push(e)}return this},o.Emitter.prototype.off=function(t,e){for(var i=t.split(/\W+/),r=0;r<i.length;r++)if(t=i[r],this._events.hasOwnProperty(t))if(o.prototype.isUndef(e))this._events[t]=[];else for(var n=this._events[t],s=0;s<n.length;s++)n[s]===e&&n.splice(s,1);return this},o.Emitter.prototype.emit=function(t){if(this._events){var e=Array.apply(null,arguments).slice(1);if(this._events.hasOwnProperty(t))for(var i=this._events[t],r=0,n=i.length;r<n;r++)i[r].apply(this,e)}return this},o.Emitter.mixin=function(t){var e=["on","off","emit"];t._events={};for(var i=0;i<e.length;i++){var r=e[i],n=o.Emitter.prototype[r];t[r]=n}},o.Emitter.prototype.dispose=function(){return o.prototype.dispose.call(this),this._events=null,this},o.Emitter}).apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__),
1335				__WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));
1336
1337 }),
1338 (function(module, exports, __webpack_require__) {
1339
1340var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;!(__WEBPACK_AMD_DEFINE_ARRAY__ = [__webpack_require__(0)], __WEBPACK_AMD_DEFINE_RESULT__ = (function(c){"use strict";return c.SignalBase=function(){},c.extend(c.SignalBase),c.SignalBase.prototype.connect=function(e,n,a){return c.Signal&&c.Signal===e.constructor||c.Param&&c.Param===e.constructor||c.TimelineSignal&&c.TimelineSignal===e.constructor?(e._param.cancelScheduledValues(0),e._param.value=0,e.overridden=!0):e instanceof AudioParam&&(e.cancelScheduledValues(0),e.value=0),c.prototype.connect.call(this,e,n,a),this},c.SignalBase}).apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__),
1341				__WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));
1342
1343 }),
1344 (function(module, exports, __webpack_require__) {
1345
1346var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;!(__WEBPACK_AMD_DEFINE_ARRAY__ = [__webpack_require__(0),__webpack_require__(21)], __WEBPACK_AMD_DEFINE_RESULT__ = (function(o){return o.Time=function(t,e){if(!(this instanceof o.Time))return new o.Time(t,e);this._plusNow=!1,o.TimeBase.call(this,t,e)},o.extend(o.Time,o.TimeBase),o.Time.prototype._unaryExpressions=Object.create(o.TimeBase.prototype._unaryExpressions),o.Time.prototype._unaryExpressions.quantize={regexp:/^@/,method:function(t){return o.Trans
1346port.nextSubdivision(t())}},o.Time.prototype._unaryExpressions.now={regexp:/^\+/,method:function(t){return this._plusNow=!0,t()}},o.Time.prototype.quantize=function(t,e){return e=this.defaultArg(e,1),this._expr=function(t,e,o){return t=t(),e=e.toSeconds(),t+(Math.round(t/e)*e-t)*o}.bind(this,this._expr,new this.constructor(t),e),this},o.Time.prototype.addNow=function(){return this._plusNow=!0,this},o.Time.prototype._defaultExpr=function(){return this._plusNow=!0,this._noOp},o.Time.prototype.copy=function(t){return o.TimeBase.prototype.copy.call(this,t),this._plusNow=t._plusNow,this},o.Time.prototype.toNotation=function(){var t=this.toSeconds(),e=this._toNotationHelper(t,["1m","2n","4n","8n","16n","32n","64n","128n"]),o=this._toNotationHelper(t,["1m","2n","2t","4n","4t","8n","8t","16n","16t","32n","32t","64n","64t","128n"]);return o.split("+").length<e.split("+").length?o:e},o.Time.prototype._toNotationHelper=function(t,e){for(var o=this._notationToUnits(e[e.length-1]),n="",i=0;i<e.length;i++){var r=this._notationToUnits(e[i]),s=t/r;if(1-s%1<1e-6&&(s+=1e-6),0<(s=Math.floor(s))){if(n+=1===s?e[i]:s.toString()+"*"+e[i],(t-=s*r)<o)break;n+=" + "}}return""===n&&(n="0"),n},o.Time.prototype._notationToUnits=function(t){for(var e=this._primaryExpressions,o=[e.n,e.t,e.m],n=0;n<o.length;n++){var i=o[n],r=t.match(i.regexp);if(r)return i.method.call(this,r[1])}},o.Time.prototype.toBarsBeatsSixteenths=function(){var t=this._beatsToUnits(1),e=this.toSeconds()/t,o=Math.floor(e/this._timeSignature()),n=e%1*4;return e=Math.floor(e)%this._timeSignature(),3<(n=n.toString()).length&&(n=parseFloat(n).toFixed(3)),[o,e,n].join(":")},o.Time.prototype.toTicks=function(){var t=this._beatsToUnits(1),e=this.valueOf()/t;return Math.floor(e*o.Transport.PPQ)},o.Time.prototype.toSamples=function(){return this.toSeconds()*this.context.sampleRate},o.Time.prototype.toFrequency=function(){return 1/this.toSeconds()},o.Time.prototype.toSeconds=function(){return this.valueOf()},o.Time.prototype.toMilliseconds=function(){return 1e3*this.toSeconds()},o.Time.prototype.valueOf=function(){return this._expr()+(this._plusNow?this.now():0)},o.Time}).apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__),
1347				__WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));
1348
1349 }),
1350 (function(module, exports, __webpack_require__) {
1351
1352var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;!(__WEBPACK_AMD_DEFINE_ARRAY__ = [__webpack_require__(0)], __WEBPACK_AMD_DEFINE_RESULT__ = (function(n){return n.TimeBase=function(e,t){if(!(this instanceof n.TimeBase))return new n.TimeBase(e,t);if(this._expr=this._noOp,e instanceof n.TimeBase)this.copy(e);else if(!this.isUndef(t)||this.isNumber(e)){t=this.defaultArg(t,this._defaultUnits);var r=this._primaryExpressions[t].method;this._expr=r.bind(this,e)}else this.isString(e)?this.set(e):this.isUndef(e)&&(this._expr=this._defaultExpr())},n.extend(n.TimeBase),n.TimeBase.prototype.set=function(e){return this._expr=this._parseExprString(e),this},n.TimeBase.prototype.clone=function(){var e=new this.constructor;return e.copy(this),e},n.TimeBase.prototype.copy=function(e){var t=e._expr();return this.set(t)},n.TimeBase.prototype._primaryExpressions={n:{regexp:/^(\d+)n/i,method:function(e){return 1===(e=parseInt(e))?this._beatsToUnits(this._timeSignature()):this._beatsToUnits(4/e)}},t:{regexp:/^(\d+)t/i,method:function(e){return e=parseInt(e),this._beatsToUnits(8/(3*parseInt(e)))}},m:{regexp:/^(\d+)m/i,method:function(e){return this._beatsToUnits(parseInt(e)*this._timeSignature())}},i:{regexp:/^(\d+)i/i,method:function(e){return this._ticksToUnits(parseInt(e))}},hz:{regexp:/^(\d+(?:\.\d+)?)hz/i,method:function(e){return this._frequencyToUnits(parseFloat(e))}},tr:{regexp:/^(\d+(?:\.\d+)?):(\d+(?:\.\d+)?):?(\d+(?:\.\d+)?)?/,method:function(e,t,r){var n=0;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}},s:{regexp:/^(\d+(?:\.\d+)?s)/,method:function(e){return this._secondsToUnits(parseFloat(e))}},samples:{regexp:/^(\d+)samples/,method:function(e){return parseInt(e)/this.context.sampleRate}},default:{regexp:/^(\d+(?:\.\d+)?)/,method:function(e){return this._primaryExpressions[this._defaultUnits].method.call(this,e)}}},n.TimeBase.prototype._binaryExpressions={"+":{regexp:/^\+/,precedence:2,method:function(e,t){return e()+t()}},"-":{regexp:/^\-/,precedence:2,method:function(e,t){return e()-t()}},"*":{regexp:/^\*/,precedence:1,method:function(e,t){return e()*t()}},"/":{regexp:/^\//,precedence:1,method:function(e,t){return e()/t()}}},n.TimeBase.prototype._unaryExpressions={neg:{regexp:/^\-/,method:function(e){return-e()}}},n.TimeBase.prototype._syntaxGlue={"(":{regexp:/^\(/},")":{regexp:/^\)/}},n.TimeBase.prototype._tokenize=function(e){for(var t=-1,r=[];0<e.length;){var n=i(e=e.trim(),this);r.push(n),e=e.substr(n.value.length)}function i(e,t){for(var r=["_binaryExpressions","_unaryExpressions","_primaryExpressions","_syntaxGlue"],n=0;n<r.length;n++){var i=t[r[n]];for(var s in i){var o=i[s],p=o.regexp,a=e.match(p);if(null!==a)return{method:o.method,precedence:o.precedence,regexp:o.regexp,value:a[0]}}}throw new SyntaxError("Tone.TimeBase: Unexpected token "+e)}return{next:function(){return r[++t]},peek:function(){return r[t+1]}}},n.TimeBase.prototype._matchGroup=function(e,t,r){if(!this.isUndef(e))for(var n in t){var i=t[n];if(i.regexp.test(e.value)){if(this.isUndef(r))return i;if(i.precedence===r)return i}}return!1},n.TimeBase.prototype._parseBinary=function(e,t){var r;this.isUndef(t)&&(t=2),r=t<0?this._parseUnary(e):this._parseBinary(e,t-1);for(var n=e.peek();n&&this._matchGroup(n,this._binaryExpressions,t);)r=(n=e.next()).method.bind(this,r,this._parseBinary(e,t-1)),n=e.peek();return r},n.TimeBase.prototype._parseUnary=function(e){var t,r;t=e.peek();var n=this._matchGroup(t,this._unaryExpressions);return n?(t=e.next(),r=this._parseUnary(e),n.method.bind(this,r)):this._parsePrimary(e)},n.TimeBase.prototype._parsePrimary=function(e){var t,r;if(t=e.peek(),this.isUndef(t))throw new SyntaxError("Tone.TimeBase: Unexpected end of expression");if(this._matchGroup(t,this._primaryExpressions)){var n=(t=e.next()).value.match(t.regexp);return t.method.bind(this,n[1],n[2],n[3])}if(t&&"("===t.value){if(e.next(),r=this._parseBinary(e),!(t=e.next())||")"!==t.value)throw new SyntaxError("Expected )");return r}throw new SyntaxError("Tone.TimeBase: Cannot process token "+t.value)},n.TimeBase.prototype._parseExprString=function(e){this.isString(e)||(e=e.toString());var t=this._tokenize(e);return this._parseBinary(t)},n.TimeBase.prototype._noOp=function(){return 0},n.TimeBase.prototype._defaultExpr=function(){return this._noOp},n.TimeBase.prototype._defaultUnits="s",n.TimeBase.prototype._frequencyToUnits=function(e){return 1/e},n.TimeBase.prototype._beatsToUnits=function(e){return 60/n.Transport.bpm.value*e},n.TimeBase.prototype._secondsToUnits=function(e){return e},n.TimeBase.prototype._ticksToUnits=function(e){return e*(this._beatsToUnits(1)/n.Transport.PPQ)},n.TimeBase.prototype._timeSignature=function(){return n.Transport.timeSignature},n.TimeBase.prototype._pushExpr=function(e,t,r){return e instanceof n.TimeBase||(e=new this.constructor(e,r)),this._expr=this._binaryExpressions[t].method.bind(this,this._expr,e._expr),this},n.TimeBase.prototype.add=function(e,t){return this._pushExpr(e,"+",t)},n.TimeBase.prototype.sub=function(e,t){return this._pushExpr(e,"-",t)},n.TimeBase.prototype.mult=function(e,t){return this._pushExpr(e,"*",t)},n.TimeBase.prototype.div=function(e,t){return this._pushExpr(e,"/",t)},n.TimeBase.prototype.valueOf=function(){return this._expr()},n.TimeBase.prototype.dispose=function(){this._expr=null},n.TimeBase}).apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__),
1353				__WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));
1354
1355 }),
1356 (function(module, exports, __webpack_require__) {
1357
1358var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;!(__WEBPACK_AMD_DEFINE_ARRAY__ = [__webpack_require__(0),__webpack_require__(8)], __WEBPACK_AMD_DEFINE_RESULT__ = (function(a){"use strict";
1358return a.Param=function(){var t=this.optionsObject(arguments,["param","units","convert"],a.Param.defaults);this._param=this.input=t.param,this.units=t.units,this.convert=t.convert,this.overridden=!1,this._lfo=null,this.isObject(t.lfo)?this.value=t.lfo:this.isUndef(t.value)||(this.value=t.value)},a.extend(a.Param),a.Param.defaults={units:a.Type.Default,convert:!0,param:void 0},Object.defineProperty(a.Param.prototype,"value",{get:function(){return this._toUnits(this._param.value)},set:function(t){if(this.isObject(t)){if(this.isUndef(a.LFO))throw new Error("Include 'Tone.LFO' to use an LFO as a Param value.");this._lfo&&this._lfo.dispose(),this._lfo=new a.LFO(t).start(),this._lfo.connect(this.input)}else{var e=this._fromUnits(t);this._param.cancelScheduledValues(0),this._param.value=e}}}),a.Param.prototype._fromUnits=function(t){if(!this.convert&&!this.isUndef(this.convert))return t;switch(this.units){case a.Type.Time:return this.toSeconds(t);case a.Type.Frequency:return this.toFrequency(t);case a.Type.Decibels:return this.dbToGain(t);case a.Type.NormalRange:return Math.min(Math.max(t,0),1);case a.Type.AudioRange:return Math.min(Math.max(t,-1),1);case a.Type.Positive:return Math.max(t,0);default:return t}},a.Param.prototype._toUnits=function(t){if(!this.convert&&!this.isUndef(this.convert))return t;switch(this.units){case a.Type.Decibels:return this.gainToDb(t);default:return t}},a.Param.prototype._minOutput=1e-5,a.Param.prototype.setValueAtTime=function(t,e){return t=this._fromUnits(t),(e=this.toSeconds(e))<=this.now()+this.blockTime?this._param.value=t:this._param.setValueAtTime(t,e),this},a.Param.prototype.setRampPoint=function(t){t=this.defaultArg(t,this.now());var e=this._param.value;return 0===e&&(e=this._minOutput),this._param.setValueAtTime(e,t),this},a.Param.prototype.linearRampToValueAtTime=function(t,e){return t=this._fromUnits(t),this._param.linearRampToValueAtTime(t,this.toSeconds(e)),this},a.Param.prototype.exponentialRampToValueAtTime=function(t,e){return t=this._fromUnits(t),t=Math.max(this._minOutput,t),this._param.exponentialRampToValueAtTime(t,this.toSeconds(e)),this},a.Param.prototype.exponentialRampToValue=function(t,e,i){return i=this.toSeconds(i),this.setRampPoint(i),this.exponentialRampToValueAtTime(t,i+this.toSeconds(e)),this},a.Param.prototype.linearRampToValue=function(t,e,i){return i=this.toSeconds(i),this.setRampPoint(i),this.linearRampToValueAtTime(t,i+this.toSeconds(e)),this},a.Param.prototype.setTargetAtTime=function(t,e,i){return t=this._fromUnits(t),t=Math.max(this._minOutput,t),i=Math.max(this._minOutput,i),this._param.setTargetAtTime(t,this.toSeconds(e),i),this},a.Param.prototype.setValueCurveAtTime=function(t,e,i){for(var a=0;a<t.length;a++)t[a]=this._fromUnits(t[a]);return this._param.setValueCurveAtTime(t,this.toSeconds(e),this.toSeconds(i)),this},a.Param.prototype.cancelScheduledValues=function(t){return this._param.cancelScheduledValues(this.toSeconds(t)),this},a.Param.prototype.rampTo=function(t,e,i){return e=this.defaultArg(e,0),this.units===a.Type.Frequency||this.units===a.Type.BPM||this.units===a.Type.Decibels?this.exponentialRampToValue(t,e,i):this.linearRampToValue(t,e,i),this},Object.defineProperty(a.Param.prototype,"lfo",{get:function(){return this._lfo}}),a.Param.prototype.dispose=function(){return a.prototype.dispose.call(this),this._param=null,this._lfo&&(this._lfo.dispose(),this._lfo=null),this},a.Param}).apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__),
1359				__WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));
1360
1361 }),
1362 (function(module, exports, __webpack_require__) {
1363
1364"use strict";
1365var __WEBPACK_AMD_DEFINE_RESULT__;
1366
1367!(__WEBPACK_AMD_DEFINE_RESULT__ = (function (require) {
1368  var p5sound = __webpack_require__(1);
1369
1370  var Add = __webpack_require__(7);
1371
1372  var Mult = __webpack_require__(3);
1373
1374  var Scale = __webpack_require__(13);
1375  /**
1376   *  <p>Creates a signal that oscillates between -1.0 and 1.0.
1377   *  By default, the oscillation takes the form of a sinusoidal
1378   *  shape ('sine'). Additional types include 'triangle',
1379   *  'sawtooth' and 'square'. The frequency defaults to
1380   *  440 oscillations per second (440Hz, equal to the pitch of an
1381   *  'A' note).</p>
1382   *
1383   *  <p>Set the type of oscillation with setType(), or by instantiating a
1384   *  specific oscillator: <a href="/reference/#/p5.SinOsc">p5.SinOsc</a>, <a
1385   *  href="/reference/#/p5.TriOsc">p5.TriOsc</a>, <a
1386   *  href="/reference/#/p5.SqrOsc">p5.SqrOsc</a>, or <a
1387   *  href="/reference/#/p5.SawOsc">p5.SawOsc</a>.
1388   *  </p>
1389   *
1390   *  @class p5.Oscillator
1391   *  @constructor
1392   *  @param {Number} [freq] frequency defaults to 440Hz
1393   *  @param {String} [type] type of oscillator. Options:
1394   *                         'sine' (default), 'triangle',
1395   *                         'sawtooth', 'square'
1396   *  @example
1397   *  <div><code>
1398   *  let osc, playing, freq, amp;
1399   *
1400   *  function setup() {
1401   *    let cnv = createCanvas(100, 100);
1402   *    cnv.mousePressed(playOscillator);
1403   *    osc = new p5.Oscillator('sine');
1404   *  }
1405   *
1406   *  function draw() {
1407   *    background(220)
1408   *    freq = constrain(map(mouseX, 0, width, 100, 500), 100, 500);
1409   *    amp = constrain(map(mouseY, height, 0, 0, 1), 0, 1);
1410   *
1411   *    text('tap to play', 20, 20);
1412   *    text('freq: ' + freq, 20, 40);
1413   *    text('amp: ' + amp, 20, 60);
1414   *
1415   *    if (playing) {
1416   *      // smooth the transitions by 0.1 seconds
1417   *      osc.freq(freq, 0.1);
1418   *      osc.amp(amp, 0.1);
1419   *    }
1420   *  }
1421   *
1422   *  function playOscillator() {
1423   *    // starting an oscillator on a user gesture will enable audio
1424   *    // in browsers that have a strict autoplay policy.
1425   *    // See also: userStartAudio();
1426   *    osc.start();
1427   *    playing = true;
1428   *  }
1429   *
1430   *  function mouseReleased() {
1431   *    // ramp amplitude to 0 over 0.5 seconds
1432   *    osc.amp(0, 0.5);
1433   *    playing = false;
1434   *  }
1435   *  </code> </div>
1436   */
1437
1438
1439  p5.Oscillator = function (freq, type) {
1440    if (typeof freq === 'string') {
1441      var f = type;
1442      type = freq;
1443      freq = f;
1444    }
1445
1446    if (typeof type === 'number') {
1447      var f = type;
1448      type = freq;
1449      freq = f;
1450    }
1451
1452    this.started = false; 
1453
1454    this.phaseAmount = undefined;
1455    this.oscillator = p5sound.audiocontext.createOscillator();
1456    this.f = freq || 440.0; 
1457
1458    this.oscillator.type = type || 'sine';
1459    this.oscillator.frequency.setValueAtTime(this.f, p5sound.audiocontext.currentTime); 
1460
1461    this.output = p5sound.audiocontext.createGain();
1462    this._freqMods = []; 
1463
1464    this.output.gain.value = 0.5;
1465    this.output.gain.setValueAtTime(0.5, p5sound.audiocontext.currentTime);
1466    this.oscillator.connect(this.output); 
1467
1468    this.panPosition = 0.0;
1469    this.connection = p5sound.input; 
1470
1471    this.panner = new p5.Panner(this.output, this.connection, 1); 
1472
1473    this.mathOps = [this.output]; 
1474
1475    p5sound.soundArray.push(this);
1476  };
1477  /**
1478   *  Start an oscillator.
1479   *
1480   *  Starting an oscillator on a user gesture will enable audio in browsers
1481   *  that have a strict autoplay policy, including Chrome and most mobile
1482   *  devices. See also: `userStartAudio()`.
1483   *
1484   *  @method  start
1485   *  @for p5.Oscillator
1486   *  @param  {Number} [time] startTime in seconds from now.
1487   *  @param  {Number} [frequency] frequency in Hz.
1488   */
1489
1490
1491  p5.Oscillator.prototype.start = function (time, f) {
1492    if (this.started) {
1493      var now = p5sound.audiocontext.currentTime;
1494      this.stop(now);
1495    }
1496
1497    if (!this.started) {
1498      var freq = f || this.f;
1499      var type = this.oscillator.type; 
1500
1501      if (this.oscillator) {
1502        this.oscillator.disconnect();
1503        delete this.oscillator;
1504      } 
1505
1506
1507      this.oscillator = p5sound.audiocontext.createOscillator();
1508      this.oscillator.frequency.value = Math.abs(freq);
1509      this.oscillator.type = type; 
1510
1511      this.oscillator.connect(this.output);
1512      time = time || 0;
1513      this.oscillator.start(time + p5sound.audiocontext.currentTime);
1514      this.freqNode = this.oscillator.frequency; 
1515
1516      for (var i in this._freqMods) {
1517        if (typeof this._freqMods[i].connect !== 'undefined') {
1518          this._freqMods[i].connect(this.oscillator.frequency);
1519        }
1520      }
1521
1522      this.started = true;
1523    }
1524  };
1525  /**
1526   *  Stop an oscillator. Accepts an optional parameter
1527   *  to determine how long (in seconds from now) until the
1528   *  oscillator stops.
1529   *
1530   *  @method  stop
1531   *  @for p5.Oscillator
1532   *  @param  {Number} secondsFromNow Time, in seconds from now.
1533   */
1534
1535
1536  p5.Oscillator.prototype.stop = function (time) {
1537    if (this.started) {
1538      var t = time || 0;
1539      var now = p5sound.audiocontext.currentTime;
1540      this.oscillator.stop(t + now);
1541      this.started = false;
1542    }
1543  };
1544  /**
1545   *  Set the amplitude between 0 and 1.0. Or, pass in an object
1546   *  such as an oscillator to modulate amplitude with an audio signal.
1547   *
1548   *  @method  amp
1549   *  @for p5.Oscillator
1550   *  @param  {Number|Object} vol between 0 and 1.0
1551   *                              or a modulating signal/oscillator
1552   *  @param {Number} [rampTime] create a fade that lasts rampTime
1553   *  @param {Number} [timeFromNow] schedule this event to happen
1554   *                                seconds from now
1555   *  @return  {AudioParam} gain  If no value is provided,
1556   *                              returns the Web Audio API
1557   *                              AudioParam that controls
1558   *                              this oscillator's
1559   *                              gain/amplitude/volume)
1560   */
1561
1562
1563  p5.Oscillator.prototype.amp = function (vol, rampTime, tFromNow) {
1564    var self = this;
1565
1566    if (typeof vol === 'number') {
1567      var rampTime = rampTime || 0;
1568      var tFromNow = tFromNow || 0;
1569      var now = p5sound.audiocontext.currentTime;
1570      this.output.gain.linearRampToValueAtTime(vol, now + tFromNow + rampTime);
1571    } else if (vol) {
1572      vol.connect(self.output.gain);
1573    } else {
1574      return this.output.gain;
1575    }
1576  }; 
1577
1578
1579  p5.Oscillator.prototype.fade = p5.Oscillator.prototype.amp;
1580
1581  p5.Oscillator.prototype.getAmp = function () {
1582    return this.output.gain.value;
1583  };
1584  /**
1585   *  Set frequency of an oscillator to a value. Or, pass in an object
1586   *  such as an oscillator to modulate the frequency with an audio signal.
1587   *
1588   *  @method  freq
1589   *  @for p5.Oscillator
1590   *  @param  {Number|Object} Frequency Frequency 
1590in Hz
1591   *                                        or modulating signal/oscillator
1592   *  @param  {Number} [rampTime] Ramp time (in seconds)
1593   *  @param  {Number} [timeFromNow] Schedule this event to happen
1594   *                                   at x seconds from now
1595   *  @return  {AudioParam} Frequency If no value is provided,
1596   *                                  returns the Web Audio API
1597   *                                  AudioParam that controls
1598   *                                  this oscillator's frequency
1599   *  @example
1600   *  <div><code>
1601   *  let osc;
1602   *
1603   *  function setup() {
1604   *    let cnv = createCanvas(100, 100);
1605   *    cnv.mousePressed(playOscillator);
1606   *    osc = new p5.Oscillator(300);
1607   *    background(220);
1608   *    text('tap to play', 20, 20);
1609   *  }
1610   *
1611   *  function playOscillator() {
1612   *    osc.start();
1613   *    osc.amp(0.5);
1614   *    // start at 700Hz
1615   *    osc.freq(700);
1616   *    // ramp to 60Hz over 0.7 seconds
1617   *    osc.freq(60, 0.7);
1618   *    osc.amp(0, 0.1, 0.7);
1619   *  }
1620   *  </code></div>
1621   */
1622
1623
1624  p5.Oscillator.prototype.freq = function (val, rampTime, tFromNow) {
1625    if (typeof val === 'number' && !isNaN(val)) {
1626      this.f = val;
1627      var now = p5sound.audiocontext.currentTime;
1628      var rampTime = rampTime || 0;
1629      var tFromNow = tFromNow || 0;
1630      var t = now + tFromNow + rampTime; 
1631
1632      if (rampTime === 0) {
1633        this.oscillator.frequency.setValueAtTime(val, tFromNow + now);
1634      } else {
1635        if (val > 0) {
1636          this.oscillator.frequency.exponentialRampToValueAtTime(val, tFromNow + rampTime + now);
1637        } else {
1638          this.oscillator.frequency.linearRampToValueAtTime(val, tFromNow + rampTime + now);
1639        }
1640      } 
1641
1642
1643      if (this.phaseAmount) {
1644        this.phase(this.phaseAmount);
1645      }
1646    } else if (val) {
1647      if (val.output) {
1648        val = val.output;
1649      }
1650
1651      val.connect(this.oscillator.frequency); 
1652
1653      this._freqMods.push(val);
1654    } else {
1655      return this.oscillator.frequency;
1656    }
1657  };
1658
1659  p5.Oscillator.prototype.getFreq = function () {
1660    return this.oscillator.frequency.value;
1661  };
1662  /**
1663   *  Set type to 'sine', 'triangle', 'sawtooth' or 'square'.
1664   *
1665   *  @method  setType
1666   *  @for p5.Oscillator
1667   *  @param {String} type 'sine', 'triangle', 'sawtooth' or 'square'.
1668   */
1669
1670
1671  p5.Oscillator.prototype.setType = function (type) {
1672    this.oscillator.type = type;
1673  };
1674
1675  p5.Oscillator.prototype.getType = function () {
1676    return this.oscillator.type;
1677  };
1678  /**
1679   *  Connect to a p5.sound / Web Audio object.
1680   *
1681   *  @method  connect
1682   *  @for p5.Oscillator
1683   *  @param  {Object} unit A p5.sound or Web Audio object
1684   */
1685
1686
1687  p5.Oscillator.prototype.connect = function (unit) {
1688    if (!unit) {
1689      this.panner.connect(p5sound.input);
1690    } else if (unit.hasOwnProperty('input')) {
1691      this.panner.connect(unit.input);
1692      this.connection = unit.input;
1693    } else {
1694      this.panner.connect(unit);
1695      this.connection = unit;
1696    }
1697  };
1698  /**
1699   *  Disconnect all outputs
1700   *
1701   *  @method  disconnect
1702   *  @for p5.Oscillator
1703   */
1704
1705
1706  p5.Oscillator.prototype.disconnect = function () {
1707    if (this.output) {
1708      this.output.disconnect();
1709    }
1710
1711    if (this.panner) {
1712      this.panner.disconnect();
1713
1714      if (this.output) {
1715        this.output.connect(this.panner);
1716      }
1717    }
1718
1719    this.oscMods = [];
1720  };
1721  /**
1722   *  Pan between Left (-1) and Right (1)
1723   *
1724   *  @method  pan
1725   *  @for p5.Oscillator
1726   *  @param  {Number} panning Number between -1 and 1
1727   *  @param  {Number} timeFromNow schedule this event to happen
1728   *                                seconds from now
1729   */
1730
1731
1732  p5.Oscillator.prototype.pan = function (pval, tFromNow) {
1733    this.panPosition = pval;
1734    this.panner.pan(pval, tFromNow);
1735  };
1736
1737  p5.Oscillator.prototype.getPan = function () {
1738    return this.panPosition;
1739  }; 
1740
1741
1742  p5.Oscillator.prototype.dispose = function () {
1743    var index = p5sound.soundArray.indexOf(this);
1744    p5sound.soundArray.splice(index, 1);
1745
1746    if (this.oscillator) {
1747      var now = p5sound.audiocontext.currentTime;
1748      this.stop(now);
1749      this.disconnect();
1750      this.panner = null;
1751      this.oscillator = null;
1752    } 
1753
1754
1755    if (this.osc2) {
1756      this.osc2.dispose();
1757    }
1758  };
1759  /**
1760   *  Set the phase of an oscillator between 0.0 and 1.0.
1761   *  In this implementation, phase is a delay time
1762   *  based on the oscillator's current frequency.
1763   *
1764   *  @method  phase
1765   *  @for p5.Oscillator
1766   *  @param  {Number}
1766 phase float between 0.0 and 1.0
1767   */
1768
1769
1770  p5.Oscillator.prototype.phase = function (p) {
1771    var delayAmt = p5.prototype.map(p, 0, 1.0, 0, 1 / this.f);
1772    var now = p5sound.audiocontext.currentTime;
1773    this.phaseAmount = p;
1774
1775    if (!this.dNode) {
1776      this.dNode = p5sound.audiocontext.createDelay(); 
1777
1778      this.oscillator.disconnect();
1779      this.oscillator.connect(this.dNode);
1780      this.dNode.connect(this.output);
1781    } 
1782
1783
1784    this.dNode.delayTime.setValueAtTime(delayAmt, now);
1785  }; 
1786
1787
1788  var sigChain = function sigChain(o, mathObj, thisChain, nextChain, type) {
1789    var chainSource = o.oscillator; 
1790
1791    for (var i in o.mathOps) {
1792      if (o.mathOps[i] instanceof type) {
1793        chainSource.disconnect();
1794        o.mathOps[i].dispose();
1795        thisChain = i; 
1796
1797        if (thisChain < o.mathOps.length - 2) {
1798          nextChain = o.mathOps[i + 1];
1799        }
1800      }
1801    }
1802
1803    if (thisChain === o.mathOps.length - 1) {
1804      o.mathOps.push(nextChain);
1805    } 
1806
1807
1808    if (i > 0) {
1809      chainSource = o.mathOps[i - 1];
1810    }
1811
1812    chainSource.disconnect();
1813    chainSource.connect(mathObj);
1814    mathObj.connect(nextChain);
1815    o.mathOps[thisChain] = mathObj;
1816    return o;
1817  };
1818  /**
1819   *  Add a value to the p5.Oscillator's output amplitude,
1820   *  and return the oscillator. Calling this method again
1821   *  will override the initial add() with a new value.
1822   *
1823   *  @method  add
1824   *  @for p5.Oscillator
1825   *  @param {Number} number Constant number to add
1826   *  @return {p5.Oscillator} Oscillator Returns this oscillator
1827   *                                     with scaled output
1828   *
1829   */
1830
1831
1832  p5.Oscillator.prototype.add = function (num) {
1833    var add = new Add(num);
1834    var thisChain = this.mathOps.length - 1;
1835    var nextChain = this.output;
1836    return sigChain(this, add, thisChain, nextChain, Add);
1837  };
1838  /**
1839   *  Multiply the p5.Oscillator's output amplitude
1840   *  by a fixed value (i.e. turn it up!). Calling this method
1841   *  again will override the initial mult() with a new value.
1842   *
1843   *  @method  mult
1844   *  @for p5.Oscillator
1845   *  @param {Number} number Constant number to multiply
1846   *  @return {p5.Oscillator} Oscillator Returns this oscillator
1847   *                                     with multiplied output
1848   */
1849
1850
1851  p5.Oscillator.prototype.mult = function (num) {
1852    var mult = new Mult(num);
1853    var thisChain = this.mathOps.length - 1;
1854    var nextChain = this.output;
1855    return sigChain(this, mult, thisChain, nextChain, Mult);
1856  };
1857  /**
1858   *  Scale this oscillator's amplitude values to a given
1859   *  range, and return the oscillator. Calling this method
1860   *  again will override the initial scale() with new values.
1861   *
1862   *  @method  scale
1863   *  @for p5.Oscillator
1864   *  @param  {Number} inMin  input range minumum
1865   *  @param  {Number} inMax  input range maximum
1866   *  @param  {Number} outMin input range minumum
1867   *  @param  {Number} outMax input range maximum
1868   *  @return {p5.Oscillator} Oscillator Returns this oscillator
1869   *                                     with scaled output
1870   */
1871
1872
1873  p5.Oscillator.prototype.scale = function (inMin, inMax, outMin, outMax) {
1874    var mapOutMin, mapOutMax;
1875
1876    if (arguments.length === 4) {
1877      mapOutMin = p5.prototype.map(outMin, inMin, inMax, 0, 1) - 0.5;
1878      mapOutMax = p5.prototype.map(outMax, inMin, inMax, 0, 1) - 0.5;
1879    } else {
1880      mapOutMin = arguments[0];
1881      mapOutMax = arguments[1];
1882    }
1883
1884    var scale = new Scale(mapOutMin, mapOutMax);
1885    var thisChain = this.mathOps.length - 1;
1886    var nextChain = this.output;
1887    return sigChain(this, scale, thisChain, nextChain, Scale); 
1888  }; 
1889
1890  /**
1891   *  Constructor: <code>new p5.SinOsc()</code>.
1892   *  This creates a Sine Wave Oscillator and is
1893   *  equivalent to <code> new p5.Oscillator('sine')
1894   *  </code> or creating a p5.Oscillator and then calling
1895   *  its method <code>setType('sine')</code>.
1896   *  See p5.Oscillator for methods.
1897   *
1898   *  @class  p5.SinOsc
1899   *  @constructor
1900   *  @extends p5.Oscillator
1901   *  @param {Number} [freq] Set the frequency
1902   */
1903
1904
1905  p5.SinOsc = function (freq) {
1906    p5.Oscillator.call(this, freq, 'sine');
1907  };
1908
1909  p5.SinOsc.prototype = Object.create(p5.Oscillator.prototype);
1910  /**
1911   *  Constructor: <code>new p5.TriOsc()</code>.
1912   *  This creates a Triangle Wave Oscillator and is
1913   *  equivalent to <code>new p5.Oscillator('triangle')
1914   *  </code> or creating a p5.Oscillator and then calling
1915   *  its method <code>
1915setType('triangle')</code>.
1916   *  See p5.Oscillator for methods.
1917   *
1918   *  @class  p5.TriOsc
1919   *  @constructor
1920   *  @extends p5.Oscillator
1921   *  @param {Number} [freq] Set the frequency
1922   */
1923
1924  p5.TriOsc = function (freq) {
1925    p5.Oscillator.call(this, freq, 'triangle');
1926  };
1927
1928  p5.TriOsc.prototype = Object.create(p5.Oscillator.prototype);
1929  /**
1930   *  Constructor: <code>new p5.SawOsc()</code>.
1931   *  This creates a SawTooth Wave Oscillator and is
1932   *  equivalent to <code> new p5.Oscillator('sawtooth')
1933   *  </code> or creating a p5.Oscillator and then calling
1934   *  its method <code>setType('sawtooth')</code>.
1935   *  See p5.Oscillator for methods.
1936   *
1937   *  @class  p5.SawOsc
1938   *  @constructor
1939   *  @extends p5.Oscillator
1940   *  @param {Number} [freq] Set the frequency
1941   */
1942
1943  p5.SawOsc = function (freq) {
1944    p5.Oscillator.call(this, freq, 'sawtooth');
1945  };
1946
1947  p5.SawOsc.prototype = Object.create(p5.Oscillator.prototype);
1948  /**
1949   *  Constructor: <code>new p5.SqrOsc()</code>.
1950   *  This creates a Square Wave Oscillator and is
1951   *  equivalent to <code> new p5.Oscillator('square')
1952   *  </code> or creating a p5.Oscillator and then calling
1953   *  its method <code>setType('square')</code>.
1954   *  See p5.Oscillator for methods.
1955   *
1956   *  @class  p5.SqrOsc
1957   *  @constructor
1958   *  @extends p5.Oscillator
1959   *  @param {Number} [freq] Set the frequency
1960   */
1961
1962  p5.SqrOsc = function (freq) {
1963    p5.Oscillator.call(this, freq, 'square');
1964  };
1965
1966  p5.SqrOsc.prototype = Object.create(p5.Oscillator.prototype);
1967}).call(exports, __webpack_require__, exports, module),
1968				__WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));
1969
1970 }),
1971 (function(module, exports, __webpack_require__) {
1972
1973var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;!(__WEBPACK_AMD_DEFINE_ARRAY__ = [__webpack_require__(0),__webpack_require__(8)], __WEBPACK_AMD_DEFINE_RESULT__ = (function(i){"use strict";return i.Timeline=function(){var e=this.optionsObject(arguments,["memory"],i.Timeline.defaults);this._timeline=[],this._toRemove=[],this._iterating=!1,this.memory=e.memory},i.extend(i.Timeline),i.Timeline.defaults={memory:1/0},Object.defineProperty(i.Timeline.prototype,"length",{get:function(){return this._timeline.length}}),i.Timeline.prototype.add=function(e){if(this.isUndef(e.time))throw new Error("Tone.Timeline: events must have a time attribute");if(this._timeline.length){var i=this._search(e.time);this._timeline.splice(i+1,0,e)}else this._timeline.push(e);if(this.length>this.memory){var t=this.length-this.memory;this._timeline.splice(0,t)}return this},i.Timeline.prototype.remove=function(e){if(this._iterating)this._toRemove.push(e);else{var i=this._timeline.indexOf(e);-1!==i&&this._timeline.splice(i,1)}return this},i.Timeline.prototype.get=function(e){var i=this._search(e);return-1!==i?this._timeline[i]:null},i.Timeline.prototype.peek=function(){return this._timeline[0]},i.Timeline.prototype.shift=function(){return this._timeline.shift()},i.Timeline.prototype.getAfter=function(e){var i=this._search(e);return i+1<this._timeline.length?this._timeline[i+1]:null},i.Timeline.prototype.getBefore=function(e){var i=this._timeline.length;if(0<i&&this._timeline[i-1].time<e)return this._timeline[i-1];var t=this._search(e);return 0<=t-1?this._timeline[t-1]:null},i.Timeline.prototype.cancel=function(e){if(1<this._timeline.length){var i=this._search(e);if(0<=i)if(this._timeline[i].time===e){for(var t=i;0<=t&&this._timeline[t].time===e;t--)i=t;this._timeline=this._timeline.slice(0,i)}else this._timeline=this._timeline.slice(0,i+1);else this._timeline=[]}else 1===this._timeline.length&&this._timeline[0].time>=e&&(this._timeline=[]);return this},i.Timeline.prototype.cancelBefore=function(e){if(this._timeline.length){var i=this._search(e);0<=i&&(this._timeline=this._timeline.slice(i+1))}return this},i.Timeline.prototype._search=function(e){var i=0,t=this._timeline.length,n=t;if(0<t&&this._timeline[t-1].time<=e)return t-1;for(;i<n;){var r=Math.floor(i+(n-i)/2),s=this._timeline[r],h=this._timeline[r+1];if(s.time===e){for(var l=r;l<this._timeline.length;l++){this._timeline[l].time===e&&(r=l)}return r}if(s.time<e&&h.time>e)return r;s.time>e?n=r:s.time<e&&(i=r+1)}return-1},i.Timeline.prototype._iterate=function(e,i,t){this._iterating=!0,i=this.defaultArg(i,0),t=this.defaultArg(t,this._timeline.length-1);for(var n=i;n<=t;n++)e(this._timeline[n]);if(this._iterating=!1,0<this._toRemove.length){for(var r=0;r<this._toRemove.length;r++){var s=this._timeline.indexOf(this._toRemove[r]);-1!==s&&this._timeline.splice(s,1)}this._toRemove=[]}},i.Timeline.prototype.forEach=function(e){return this._iterate(e),this},i.Timeline.prototype.forEachBefore=function(e,i){var t=this._search(e);return-1!==t&&this._iterate(i,0,t),this},i.Timeline.prototype.forEachAfter=function(e,i){var t=this._search(e);return this._iterate(i,t+1),this},i.Timeline.prototype.forEachFrom=function(e,i){for(var t=this._search(e);0<=t&&this._timeline[t].time>=e;)t--;return this._iterate(i,t+1),this},i.Timeline.prototype.forEachAtTime=function(i,t){var e=this._search(i);return-1!==e&&this._iterate(function(e){e.time===i&&t(e)},0,e),this},i.Timeline.prototype.dispose=function(){i.prototype.dispose.call(this),this._timeline=null,this._toRemove=null},i.Timeline}).apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__),
1974				__WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));
1975
1976 }),
1977 (function(module, exports, __webpack_require__) {
1978
1979var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;!(__WEBPACK_AMD_DEFINE_ARRAY__ = [__webpack_require__(0),__webpack_require__(3),__webpack_require__(2)], __WEBPACK_AMD_DEFINE_RESULT__ = (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(exports, __WEBPACK_AMD_DEFINE_ARRAY__),
1980				__WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));
1981
1982 }),
1983 (function(module, exports, __webpack_require__) {
1984
1985var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;!(__WEBPACK_AMD_DEFINE_ARRAY__ = [__webpack_require__(0),__webpack_require__(2),__webpack_require__(3),__webpack_require__(5)], __WEBPACK_AMD_DEFINE_RESULT__ = (function(e){"use strict";return e.GreaterThanZero=function(){this._thresh=this.output=new e.WaveShaper(function(e){return e<=0?0:1},127),this._scale=this.input=new e.Multiply(1e4),this._scale.connect(this._thresh)},e.extend(e.GreaterThanZero,e.SignalBase),e.GreaterThanZero.prototype.dispose=function(){return e.prototype.dispose.call(this),this._scale.dispose(),this._scale=null,this._thresh.dispose(),this._thresh=null,this},e.GreaterThanZero}).apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__),
1986				__WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));
1987
1988 }),
1989 (function(module, exports, __webpack_require__) {
1990
1991var __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__(12)], __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
1991("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__),
1992				__WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));
1993
1994 }),
1995 (function(module, exports, __webpack_require__) {
1996
1997"use strict";
1998var __WEBPACK_AMD_DEFINE_RESULT__;
1999
2000!(__WEBPACK_AMD_DEFINE_RESULT__ = (function (require) {
2001  var p5sound = __webpack_require__(1);
2002
2003  var AudioVoice = __webpack_require__(29);
2004
2005  var noteToFreq = __webpack_require__(6).noteToFreq;
2006
2007  var DEFAULT_SUSTAIN = 0.15;
2008  /**
2009    *  A MonoSynth is used as a single voice for sound synthesis.
2010    *  This is a class to be used in conjunction with the PolySynth
2011    *  class. Custom synthetisers should be built inheriting from
2012    *  this class.
2013    *
2014    *  @class p5.MonoSynth
2015    *  @constructor
2016    *  @example
2017    *  <div><code>
2018    *  let monoSynth;
2019    *
2020    *  function setup() {
2021    *    let cnv = createCanvas(100, 100);
2022    *    cnv.mousePressed(playSynth);
2023    *    background(220);
2024    *    textAlign(CENTER);
2025    *    text('tap to play', width/2, height/2);
2026    *
2027    *    monoSynth = new p5.MonoSynth();
2028    *  }
2029    *
2030    *  function playSynth() {
2031    *    userStartAudio();
2032    *
2033    *    let note = random(['Fb4', 'G4']);
2034    *    // note velocity (volume, from 0 to 1)
2035    *    let velocity = random();
2036    *    // time from now (in seconds)
2037    *    let time = 0;
2038    *    // note duration (in seconds)
2039    *    let dur = 1/6;
2040    *
2041    *    monoSynth.play(note, velocity, time, dur);
2042    *  }
2043    *  </code></div>
2044    **/
2045
2046  p5.MonoSynth = function () {
2047    AudioVoice.call(this);
2048    this.oscillator = new p5.Oscillator();
2049    this.env = new p5.Envelope();
2050    this.env.setRange(1, 0);
2051    this.env.setExp(true); 
2052
2053    this.setADSR(0.02, 0.25, 0.05, 0.35); 
2054
2055    this.oscillator.disconnect();
2056    this.oscillator.connect(this.output);
2057    this.env.disconnect();
2058    this.env.setInput(this.output.gain); 
2059
2060    this.oscillator.output.gain.value = 1.0;
2061    this.oscillator.start();
2062    this.connect();
2063    p5sound.soundArray.push(this);
2064  };
2065
2066  p5.MonoSynth.prototype = Object.create(p5.AudioVoice.prototype);
2067  /**
2068    *  Play tells the MonoSynth to start playing a note. This method schedules
2069    *  the calling of .triggerAttack and .triggerRelease.
2070    *
2071    *  @method play
2072    *  @for p5.MonoSynth
2073    *  @param {String | Number} note the note you want to play, specified as a
2074    *                                 frequency in Hertz (Number) or as a midi
2075    *                                 value in Note/Octave format ("C4", "Eb3"...etc")
2076    *                                 See <a href = "https://github.com/Tonejs/Tone.js/wiki/Instruments">
2077    *                                 Tone</a>. Defaults to 440 hz.
2078    *  @param  {Number} [velocity] velocity of the note to play (ranging from 0 to 1)
2079    *  @param  {Number} [secondsFromNow]  time from now (in seconds) at which to play
2080    *  @param  {Number} [sustainTime] time to sustain before releasing the envelope. Defaults to 0.15 seconds.
2081    *  @example
2082    *  <div><code>
2083    *  let monoSynth;
2084    *
2085    *  function setup() {
2086    *    let cnv = createCanvas(100, 100);
2087    *    cnv.mousePressed(playSynth);
2088    *    background(220);
2089    *    textAlign(CENTER);
2090    *    text('tap to play', width/2, height/2);
2091    *
2092    *    monoSynth = new p5.MonoSynth();
2093    *  }
2094    *
2095    *  function playSynth() {
2096    *    userStartAudio();
2097    *
2098    *    let note = random(['Fb4', 'G4']);
2099    *    // note velocity (volume, from 0 to 1)
2100    *    let velocity = random();
2101    *    // time from now (in seconds)
2102    *    let time = 0;
2103    *    // note duration (in seconds)
2104    *    let dur = 1/6;
2105    *
2106    *    monoSynth.play(note, velocity, time, dur);
2107    *  }
2108    *  </code></div>
2109    *
2110    */
2111
2112  p5.MonoSynth.prototype.play = function (note, velocity, secondsFromNow, susTime) {
2113    this.triggerAttack(note, velocity, ~~secondsFromNow);
2114    this.triggerRelease(~~secondsFromNow + (susTime || DEFAULT_SUSTAIN));
2115  };
2116  /**
2117     *  Trigger the Attack, and Decay portion of the Envelope.
2118     *  Similar to holding down a key on a piano, but it will
2119     *  hold the sustain level until you let go.
2120     *
2121     *  @param {String | Number} note the note you want to play, specified as a
2122     *                                 frequency in Hertz (Number) or as a midi
2123     *                                 value in Note/Octave format ("C4", "Eb3"...etc")
2124     *                                 See <a href = "https://github.com/Tonejs/Tone.js/wiki/Instruments">
2125     *                                 Tone</a>. Defaults to 440 hz
2126     *  @param  {Number} [velocity] velocity of the note to play (ranging from 0 to 1)
2127     *  @param  {Number} [secondsFromNow]  time from now (in seconds) at which to play
2128     *  @method  triggerAttack
2129     *  @for p5.MonoSynth
2130     *  @example
2131     *  <div><code>
2132     *  let monoSynth;
2133     *
2134     *  function setup() {
2135     *    let cnv = createCanvas(100, 100);
2136     *    cnv.mousePressed(triggerAttack);
2137     *    background(220);
2138     *    text('tap here for attack, let go to release', 5, 20, width - 20);
2139     *    monoSynth = new p5.MonoSynth();
2140     *  }
2141     *
2142     *  function triggerAttack() {
2143     *    userStartAudio();
2144     *
2145     *    monoSynth.triggerAttack("E3");
2146     *  }
2147     *
2148     *  function mouseReleased() {
2149     *    monoSynth.triggerRelease();
2150     *  }
2151     *  </code></div>
2152     */
2153
2154
2155  p5.MonoSynth.prototype.triggerAttack = function (note, velocity, secondsFromNow) {
2156    var secondsFromNow = ~~secondsFromNow;
2157    var freq = noteToFreq(note);
2158    var vel = velocity || 0.1;
2159    this.oscillator.freq(freq, 0, secondsFromNow);
2160    this.env.ramp(this.output.gain, secondsFromNow, vel);
2161  };
2162  /**
2163     *  Trigger the release of the Envelope. This is similar to releasing
2164     *  the key on a piano and letting the sound fade according to the
2165     *  release level and release time.
2166     *
2167     *  @param  {Number} secondsFromNow time to trigger the release
2168     *  @method  triggerRelease
2169     *  @for p5.MonoSynth
2170     *  @example
2171     *  <div><code>
2172     *  let monoSynth;
2173     *
2174     *  function setup() {
2175     *    let cnv = createCanvas(100, 100);
2176     *    cnv.mousePressed(triggerAttack);
2177     *    background(220);
2178     *    text('tap here for attack, let go to release', 5, 20, width - 20);
2179     *    monoSynth = new p5.MonoSynth();
2180     *  }
2181     *
2182     *  function triggerAttack() {
2183     *    userStartAudio();
2184     *
2185     *    monoSynth.triggerAttack("E3");
2186     *  }
2187     *
2188     *  function mouseReleased() {
2189     *    monoSynth.triggerRelease();
2190     *  }
2191     *  </code></div>
2192     */
2193
2194
2195  p5.MonoSynth.prototype.triggerRelease = function (secondsFromNow) {
2196    var secondsFromNow = secondsFromNow || 0;
2197    this.env.ramp(this.output.gain, secondsFromNow, 0);
2198  };
2199  /**
2200     *  Set values like a traditional
2201     *  <a href="https://en.wikipedia.org/wiki/Synthesizer#/media/File:ADSR_parameter.svg">
2202     *  ADSR envelope
2203     *  </a>.
2204     *
2205     *  @method  setADSR
2206     *  @for p5.MonoSynth
2207     *  @param {Number} attackTime    Time (in seconds before envelope
2208     *                                reaches Attack Level
2209     *  @param {Number} [decayTime]    Time (in seconds) before envelope
2210     *                                reaches Decay/Sustain Level
2211     *  @param {Number} [susRatio]    Ratio between attackLevel and releaseLevel, on a scale from 0 to 1,
2212     *                                where 1.0 = attackLevel, 0.0 = releaseLevel.
2213     *                                The susRatio determines the decayLevel and the level at which the
2214     *                                sustain portion of the envelope will sustain.
2215     *                                For example, if attackLevel is 0.4, releaseLevel is 0,
2216     *                                and susAmt is 0.5, the decayLevel would be 0.2. If attackLevel is
2217     *                                increased to 1.0 (using <code>setRange</code>),
2218     *                                then decayLevel would increase proportionally, to become 0.5.
2219     *  @param {Number} [releaseTime]   Time in seconds from now (defaults to 0)
2220     */
2221
2222
2223  p5.MonoSynth.prototype.setADSR = function (attack, decay, sustain, release) {
2224    this.env.setADSR(attack, decay, sustain, release);
2225  };
2226  /**
2227   * Getters and Setters
2228   * @property {Number} attack
2229   * @for p5.MonoSynth
2230   */
2231
2232  /**
2233   * @property {Number} decay
2234   * @for p5.MonoSynth
2235   */
2236
2237  /**
2238   * @property {Number} sustain
2239   * @for p5.MonoSynth
2240   */
2241
2242  /**
2243   * @property {Number} release
2244   * @for p5.MonoSynth
2245   */
2246
2247
2248  Object.defineProperties(p5.MonoSynth.prototype, {
2249    'attack': {
2250      get: function get() {
2251        return this.env.aTime;
2252      },
2253      set: function set(attack) {
2254        this.env.setADSR(attack, this.env.dTime, this.env.sPercent, this.env.rTime);
2255      }
2256    },
2257    'decay': {
2258      get: function get() {
2259        return this.env.dTime;
2260      },
2261      set: function set(decay) {
2262        this.env.setADSR(this.env.aTime, decay, this.env.sPercent, this.env.rTime);
2263      }
2264    },
2265    'sustain': {
2266      get: function get() {
2267        return this.env.sPercent;
2268      },
2269      set: function set(sustain) {
2270        this.env.setADSR(this.env.aTime, this.env.dTime, sustain, this.env.rTime);
2271      }
2272    },
2273    'release': {
2274      get: function get() {
2275        return this.env.rTime;
2276      },
2277      set: function set(release) {
2278        this.env.setADSR(this.env.aTime, this.env.dTime, this.env.sPercent, release);
2279      }
2280    }
2281  });
2282  /**
2283   * MonoSynth amp
2284   * @method  amp
2285   * @for p5.MonoSynth
2286   * @param  {Number} vol      desired volume
2287   * @param  {Number} [rampTime] Time to reach new volume
2288   * @return {Number}          new volume value
2289   */
2290
2291  p5.MonoSynth.prototype.amp = function (vol, rampTime) {
2292    var t = rampTime || 0;
2293
2294    if (typeof vol !== 'undefined') {
2295      this.oscillator.amp(vol, t);
2296    }
2297
2298    return this.oscillator.amp().value;
2299  };
2300  /**
2301   *  Connect to a p5.sound / Web Audio object.
2302   *
2303   *  @method  connect
2304   *  @for p5.MonoSynth
2305   *  @param  {Object} unit A p5.sound or Web Audio object
2306   */
2307
2308
2309  p5.MonoSynth.prototype.connect = function (unit) {
2310    var u = unit || p5sound.input;
2311    this.output.connect(u.input ? u.input : u);
2312  };
2313  /**
2314   *  Disconnect all outputs
2315   *
2316   *  @method  disconnect
2317   *  @for p5.MonoSynth
2318   */
2319
2320
2321  p5.MonoSynth.prototype.disconnect = function () {
2322    if (this.output) {
2323      this.output.disconnect();
2324    }
2325  };
2326  /**
2327   *  Get rid of the MonoSynth and free up its resources / memory.
2328   *
2329   *  @method  dispose
2330   *  @for p5.MonoSynth
2331   */
2332
2333
2334  p5.MonoSynth.prototype.dispose = function () {
2335    AudioVoice.prototype.dispose.apply(this);
2336
2337    if (this.env) {
2338      this.env.dispose();
2339    }
2340
2341    if (this.oscillator) {
2342      this.oscillator.dispose();
2343    }
2344  };
2345}).call(exports, __webpack_require__, exports, module),
2346				__WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));
2347
2348 }),
2349 (function(module, exports, __webpack_require__) {
2350
2351"use strict";
2352var __WEBPACK_AMD_DEFINE_RESULT__;
2353
2354!(__WEBPACK_AMD_DEFINE_RESULT__ = (function () {
2355  var p5sound = __webpack_require__(1);
2356  /**
2357   * Base class for monophonic synthesizers. Any extensions of this class
2358   * should follow the API and implement the methods below in order to
2359   * remain compatible with p5.PolySynth();
2360   *
2361   * @class p5.AudioVoice
2362   * @constructor
2363   */
2364
2365
2366  p5.AudioVoice = function () {
2367    this.ac = p5sound.audiocontext;
2368    this.output = this.ac.createGain();
2369    this.connect();
2370    p5sound.soundArray.push(this);
2371  };
2372
2373  p5.AudioVoice.prototype.play = function (note, velocity, secondsFromNow, sustime) {};
2374
2375  p5.AudioVoice.prototype.triggerAttack = function (note, velocity, secondsFromNow) {};
2376
2377  p5.AudioVoice.prototype.triggerRelease = function (secondsFromNow) {};
2378
2379  p5.AudioVoice.prototype.amp = function (vol, rampTime) {};
2380  /**
2381   * Connect to p5 objects or Web Audio Nodes
2382   * @method  connect
2383   * @for p5.AudioVoice
2384   * @param {Object} unit
2385   */
2386
2387
2388  p5.AudioVoice.prototype.connect = function (unit) {
2389    var u = unit || p5sound.input;
2390    this.output.connect(u.input ? u.input : u);
2391  };
2392  /**
2393   * Disconnect from soundOut
2394   * @method  disconnect
2395   * @for p5.AudioVoice
2396   */
2397
2398
2399  p5.AudioVoice.prototype.disconnect = function () {
2400    this.output.disconnect();
2401  };
2402
2403  p5.AudioVoice.prototype.dispose = function () {
2404    if (this.output) {
2405      this.output.disconnect();
2406      delete this.output;
2407    }
2408  };
2409
2410  return p5.AudioVoice;
2411}).call(exports, __webpack_require__, exports, module),
2412				__WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));
2413
2414 }),
2415 (function(module, exports, __webpack_require__) {
2416
2417"use strict";
2418var __WEBPACK_AMD_DEFINE_RESULT__;
2419
2420!(__WEBPACK_AMD_DEFINE_RESULT__ = (function (require) {
2421  var p5sound = __webpack_require__(1);
2422
2423  var TimelineSignal = __webpack_require__(14);
2424
2425  var noteToFreq = __webpack_require__(6).noteToFreq;
2426  /**
2427    *  An AudioVoice is used as a single voice for sound synthesis.
2428    *  The PolySynth class holds an array of AudioVoice, and deals
2429    *  with voices allocations, with setting notes to be played, and
2430    *  parameters to be set.
2431    *
2432    *  @class p5.PolySynth
2433    *  @constructor
2434    *
2435    *  @param {Number} [synthVoice]   A monophonic synth voice inheriting
2436    *                                 the AudioVoice class. Defaults to p5.MonoSynth
2437    *  @param {Number} [maxVoices] Number of voices, defaults to 8;
2438    *  @example
2439    *  <div><code>
2440    *  let polySynth;
2441    *
2442    *  function setup() {
2443    *    let cnv = createCanvas(100, 100);
2444    *    cnv.mousePressed(playSynth);
2445    *    background(220);
2446    *    text('click to play', 20, 20);
2447    *
2448    *    polySynth = new p5.PolySynth();
2449    *  }
2450    *
2451    *  function playSynth() {
2452    *    userStartAudio();
2453    *
2454    *    // note duration (in seconds)
2455    *    let dur = 1.5;
2456    *
2457    *    // time from now (in seconds)
2458    *    let time = 0;
2459    *
2460    *    // velocity (volume, from 0 to 1)
2461    *    let vel = 0.1;
2462    *
2463    *    // notes can overlap with each other
2464    *    polySynth.play('G2', vel, 0, dur);
2465    *    polySynth.play('C3', vel, time += 1/3, dur);
2466    *    polySynth.play('G3', vel, time += 1/3, dur);
2467    *  }
2468    *  </code></div>
2469    **/
2470
2471
2472  p5.PolySynth = function (audioVoice, maxVoices) {
2473    this.audiovoices = [];
2474    /**
2475     * An object that holds information about which notes have been played and
2476     * which notes are currently being played. New notes are added as keys
2477     * on the fly. While a note has been attacked, but not released, the value of the
2478     * key is the audiovoice which is generating that note. When notes are released,
2479     * the value of the key becomes undefined.
2480     * @property notes
2481     */
2482
2483    this.notes = {}; 
2484
2485    this._newest = 0;
2486    this._oldest = 0;
2487    /**
2488     * A PolySynth must have at least 1 voice, defaults to 8
2489     * @property polyvalue
2490     */
2491
2492    this.maxVoices = maxVoices || 8;
2493    /**
2494     * Monosynth that generates the sound for each note that is triggered. The
2495     * p5.PolySynth defaults to using the p5.MonoSynth as its voice.
2496     * @property AudioVoice
2497     */
2498
2499    this.AudioVoice = audioVoice === undefined ? p5.MonoSynth : audioVoice;
2500    /**
2501     * This value must only change as a note is attacked or released. Due to delay
2502     * and sustain times, Tone.TimelineSignal is required to schedule the change in value.
2503    * @private
2504     * @property {Tone.TimelineSignal} _voicesInUse
2505     */
2506
2507    this._voicesInUse = new TimelineSignal(0);
2508    this.output = p5sound.audiocontext.createGain();
2509    this.connect(); 
2510
2511    this._allocateVoices();
2512
2513    p5sound.soundArray.push(this);
2514  };
2515  /**
2516   * Construct the appropriate number of audiovoices
2517   * @private
2518   * @for p5.PolySynth
2519   * @method  _allocateVoices
2520   */
2521
2522
2523  p5.PolySynth.prototype._allocateVoices = function () {
2524    for (var i = 0; i < this.maxVoices; i++) {
2525      this.audiovoices.push(new this.AudioVoice());
2526      this.audiovoices[i].disconnect();
2527      this.audiovoices[i].connect(this.output);
2528    }
2529  };
2530  /**
2531   *  Play a note by triggering noteAttack and noteRelease with sustain time
2532   *
2533   *  @method  play
2534   *  @for p5.PolySynth
2535   *  @param  {Number} [note] midi note to play (ranging from 0 to 127 - 60 being a middle C)
2536   *  @param  {Number} [velocity] velocity of the note to play (ranging from 0 to 1)
2537   *  @param  {Number} [secondsFromNow]  time from now (in seconds) at which to play
2538   *  @param  {Number} [sustainTime] time to sustain before releasing the envelope
2539   *  @example
2540   *  <div><code>
2541   *  let polySynth;
2542   *
2543   *  function setup() {
2544   *    let cnv = createCanvas(100, 100);
2545   *    cnv.mousePressed(playSynth);
2546   *    background(220);
2547   *    text('click to play', 20, 20);
2548   *
2549   *    polySynth = new p5.PolySynth();
2550   *  }
2551   *
2552   *  function playSynth() {
2553   *    userStartAudio();
2554   *
2555   *    // note duration (in seconds)
2556   *    let dur = 1.5;
2557   *
2558   *    // time from now (in seconds)
2559   *    let time = 0;
2560   *
2561   *    // velocity (volume, from 0 to 1)
2562   *    let vel = 0.1;
2563   *
2564   *    // notes can overlap with each other
2565   *    polySynth.play('G2', vel, 0, dur);
2566   *    polySynth.play('C3', vel, time += 1/3, dur);
2567   *    polySynth.play('G3', vel, time += 1/3, dur);
2568   *  }
2569   *  </code></div>
2570   */
2571
2572
2573  p5.PolySynth.prototype.play = function (note, velocity, secondsFromNow, susTime) {
2574    var susTime = susTime || 1;
2575    this.noteAttack(note, velocity, secondsFromNow);
2576    this.noteRelease(note, secondsFromNow + susTime);
2577  };
2578  /**
2579   *  noteADSR sets the envelope for a specific note that has just been triggered.
2580   *  Using this method modifies the envelope of whichever audiovoice is being used
2581   *  to play the desired note. The envelope should be reset before noteRelease is called
2582   *  in order to prevent the modified envelope from being used on other notes.
2583   *
2584   *  @method  noteADSR
2585   *  @for p5.PolySynth
2586   *  @param {Number} [note]        Midi note on which ADSR should be set.
2587   *  @param {Number} [attackTime]  Time (in seconds before envelope
2588   *                                reaches Attack Level
2589   *  @param {Number} [decayTime]   Time (in seconds) before envelope
2590   *                                reaches Decay/Sustain Level
2591   *  @param {Number} [susRatio]    Ratio between attackLevel and releaseLevel, on a scale from 0 to 1,
2592   *                                where 1.0 = attackLevel, 0.0 = releaseLevel.
2593   *                                The susRatio determines the decayLevel and the level at which the
2594   *                                sustain portion of the envelope will sustain.
2595   *                                For example, if attackLevel is 0.4, releaseLevel is 0,
2596   *                                and susAmt is 0.5, the decayLevel would be 0.2. If attackLevel is
2597   *                                increased to 1.0 (using <code>setRange</code>),
2598   *                                then decayLevel would increase proportionally, to become 0.5.
2599   *  @param {Number} [releaseTime]   Time in seconds from now (defaults to 0)
2600   **/
2601
2602
2603  p5.PolySynth.prototype.noteADSR = function (note, a, d, s, r, timeFromNow) {
2604    var now = p5sound.audiocontext.currentTime;
2605    var timeFromNow = timeFromNow || 0;
2606    var t = now + timeFromNow;
2607    this.audiovoices[this.notes[note].getValueAtTime(t)].setADSR(a, d, s, r);
2608  };
2609  /**
2610   * Set the PolySynths global envelope. This method modifies the envelopes of each
2611   * monosynth so that all notes are played with this envelope.
2612   *
2613   *  @method  setADSR
2614   *  @for p5.PolySynth
2615   *  @param {Number} [attackTime]  Time (in seconds before envelope
2616   *                                reaches Attack Level
2617   *  @param {Number} [decayTime]   Time (in seconds) before envelope
2618   *                                reaches Decay/Sustain Level
2619   *  @param {Number} [susRatio]    Ratio between attackLevel and releaseLevel, on a scale from 0 to 1,
2620   *                                where 1.0 = attackLevel, 0.0 = releaseLevel.
2621   *                                The susRatio determines the decayLevel and the level at which the
2622   *                                sustain portion of the envelope will sustain.
2623   *                                For example, if attackLevel is 0.4, releaseLevel is 0,
2624   *                                and susAmt is 0.5, the decayLevel would be 0.2. If attackLevel is
2625   *                                increased to 1.0 (using <code>setRange</code>),
2626   *                                then decayLevel would increase proportionally, to become 0.5.
2627   *  @param {Number} [releaseTime]   Time in seconds from now (defaults to 0)
2628   **/
2629
2630
2631  p5.PolySynth.prototype.setADSR = function (a, d, s, r) {
2632    this.audiovoices.forEach(function (voice) {
2633      voice.setADSR(a, d, s, r);
2634    });
2635  };
2636  /**
2637   *  Trigger the Attack, and Decay portion of a MonoSynth.
2638   *  Similar to holding down a key on a piano, but it will
2639   *  hold the sustain level until you let go.
2640   *
2641   *  @method  noteAttack
2642   *  @for p5.PolySynth
2643   *  @param  {Number} [note]           midi note on which attack should be triggered.
2644   *  @param  {Number} [velocity]       velocity of the note to play (ranging from 0 to 1)/
2645   *  @param  {Number} [secondsFromNow] time from now (in seconds)
2646   *  @example
2647   *  <div><code>
2648   *  let polySynth = new p5.PolySynth();
2649   *  let pitches = ['G', 'D', 'G', 'C'];
2650   *  let octaves = [2, 3, 4];
2651   *
2652   *  function setup() {
2653   *    let cnv = createCanvas(100, 100);
2654   *    cnv.mousePressed(playChord);
2655   *    background(220);
2656   *    text('tap to play', 20, 20);
2657   *  }
2658   *
2659   *  function playChord() {
2660   *    userStartAudio();
2661   *
2662   *    // play a chord: multiple notes at the same time
2663   *    for (let i = 0; i < 4; i++) {
2664   *      let note = random(pitches) + random(octaves);
2665   *      polySynth.noteAttack(note, 0.1);
2666   *    }
2667   *  }
2668   *
2669   *  function mouseReleased() {
2670   *    // release all voices
2671   *    polySynth.noteRelease();
2672   *  }
2673   *  </code></div>
2674   */
2675
2676
2677  p5.PolySynth.prototype.noteAttack = function (_note, _velocity, secondsFromNow) {
2678    var secondsFromNow = ~~secondsFromNow; 
2679
2680    var acTime = p5sound.audiocontext.currentTime + secondsFromNow; 
2681
2682    var note = noteToFreq(_note);
2683    var velocity = _velocity || 0.1;
2684    var currentVoice; 
2685
2686    if (this.notes[note] && this.notes[note].getValueAtTime(acTime) !== null) {
2687      this.noteRelease(note, 0);
2688    } 
2689
2690
2691    if (this._voicesInUse.getValueAtTime(acTime) < this.maxVoices) {
2692      currentVoice = Math.max(~~this._voicesInUse.getValueAtTime(acTime), 0);
2693    } 
2694    else {
2695        currentVoice = this._oldest;
2696        var oldestNote = p5.prototype.freqToMidi(this.audiovoices[this._oldest].oscillator.freq().value);
2697        this.noteRelease(oldestNote);
2698        this._oldest = (this._oldest + 1) % (this.maxVoices - 1);
2699      } 
2700
2701
2702    this.notes[note] = new TimelineSignal();
2703    this.notes[note].setValueAtTime(currentVoice, acTime); 
2704
2705    var previousVal = this._voicesInUse._searchBefore(acTime) === null ? 0 : this._voicesInUse._searchBefore(acTime).value;
2706
2707    this._voicesInUse.setValueAtTime(previousVal + 1, acTime); 
2708
2709
2710    this._updateAfter(acTime, 1);
2711
2712    this._newest = currentVoice; 
2713
2714    if (typeof velocity === 'number') {
2715      var maxRange = 1 / this._voicesInUse.getValueAtTime(acTime) * 2;
2716      velocity = velocity > maxRange ? maxRange : velocity;
2717    }
2718
2719    this.audiovoices[currentVoice].triggerAttack(note, velocity, secondsFromNow);
2720  };
2721  /**
2722   * Private method to ensure accurate values of this._voicesInUse
2723   * Any time a new value is scheduled, it is necessary to increment all subsequent
2724   * scheduledValues after attack, and decrement all subsequent
2725   * scheduledValues after release
2726   *
2727   * @private
2728   * @for p5.PolySynth
2729   * @param  {[type]} time  [description]
2730   * @param  {[type]} value [description]
2731   * @return {[type]}       [description]
2732   */
2733
2734
2735  p5.PolySynth.prototype._updateAfter = function (time, value) {
2736    if (this._voicesInUse._searchAfter(time) === null) {
2737      return;
2738    } else {
2739      this._voicesInUse._searchAfter(time).value += value;
2740
2741      var nextTime = this._voicesInUse._searchAfter(time).time;
2742
2743      this._updateAfter(nextTime, value);
2744    }
2745  };
2746  /**
2747   *  Trigger the Release of an AudioVoice note. This is similar to releasing
2748   *  the key on a piano and letting the sound fade according to the
2749   *  release level and release time.
2750   *
2751   *  @method  noteRelease
2752   *  @for p5.PolySynth
2753   *  @param  {Number} [note]           midi note on which attack should be triggered.
2754   *                                    If no value is provided, all notes will be released.
2755   *  @param  {Number} [secondsFromNow] time to trigger the release
2756   *  @example
2757   *  <div><code>
2758   *  let polySynth = new p5.PolySynth();
2759   *  let pitches = ['G', 'D', 'G', 'C'];
2760   *  let octaves = [2, 3, 4];
2761   *
2762   *  function setup() {
2763   *    let cnv = createCanvas(100, 100);
2764   *    cnv.mousePressed(playChord);
2765   *    background(220);
2766   *    text('tap to play', 20, 20);
2767   *  }
2768   *
2769   *  function playChord() {
2770   *    userStartAudio();
2771   *
2772   *    // play a chord: multiple notes at the same time
2773   *    for (let i = 0; i < 4; i++) {
2774   *      let note = random(pitches) + random(octaves);
2775   *      polySynth.noteAttack(note, 0.1);
2776   *    }
2777   *  }
2778   *
2779   *  function mouseReleased() {
2780   *    // release all voices
2781   *    polySynth.noteRelease();
2782   *  }
2783   *  </code></div>
2784   *
2785   */
2786
2787
2788  p5.PolySynth.prototype.noteRelease = function (_note, secondsFromNow) {
2789    var now = p5sound.audiocontext.currentTime;
2790    var tFromNow = secondsFromNow || 0;
2791    var t = now + tFromNow; 
2792
2793    if (!_note) {
2794      this.audiovoices.forEach(function (voice) {
2795        voice.triggerRelease(tFromNow);
2796      });
2797
2798      this._voicesInUse.setValueAtTime(0, t);
2799
2800      for (var n in this.notes) {
2801        this.notes[n].dispose();
2802        delete this.notes[n];
2803      }
2804
2805      return;
2806    } 
2807
2808
2809    var note = noteToFreq(_note);
2810
2811    if (!this.notes[note] || this.notes[note].getValueAtTime(t) === null) {
2812      console.warn('Cannot release a note that is not already playing');
2813    } else {
2814      var previousVal = Math.max(~~this._voicesInUse.getValueAtTime(t).value, 1);
2815
2816      this._voicesInUse.setValueAtTime(previousVal - 1, t); 
2817
2818
2819      if (previousVal > 0) {
2820        this._updateAfter(t, -1);
2821      }
2822
2823      this.audiovoices[this.notes[note].getValueAtTime(t)].triggerRelease(tFromNow);
2824      this.notes[note].dispose();
2825      delete this.notes[note];
2826      this._newest = this._newest === 0 ? 0 : (this._newest - 1) % (this.maxVoices - 1);
2827    }
2828  };
2829  /**
2830    *  Connect to a p5.sound / Web Audio object.
2831    *
2832    *  @method  connect
2833    *  @for p5.PolySynth
2834    *  @param  {Object} unit A p5.sound or Web Audio object
2835    */
2836
2837
2838  p5.PolySynth.prototype.connect = function (unit) {
2839    var u = unit || p5sound.input;
2840    this.output.connect(u.input ? u.input : u);
2841  };
2842  /**
2843  *  Disconnect all outputs
2844  *
2845  *  @method  disconnect
2846  *  @for p5.PolySynth
2847  */
2848
2849
2850  p5.PolySynth.prototype.disconnect = function () {
2851    if (this.output) {
2852      this.output.disconnect();
2853    }
2854  };
2855  /**
2856    *  Get rid of the MonoSynth and free up its resources / memory.
2857    *
2858    *  @method  dispose
2859    *  @for p5.PolySynth
2860    */
2861
2862
2863  p5.PolySynth.prototype.dispose = function () {
2864    this.audiovoices.forEach(function (voice) {
2865      voice.dispose();
2866    });
2867
2868    if (this.output) {
2869      this.output.disconnect();
2870      delete this.output;
2871    }
2872  };
2873}).call(exports, __webpack_require__, exports, module),
2874				__WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));
2875
2876 }),
2877 (function(module, exports, __webpack_require__) {
2878
2879"use strict";
2880var __WEBPACK_AMD_DEFINE_RESULT__;
2881
2882!(__WEBPACK_AMD_DEFINE_RESULT__ = (function (require) {
2883  __webpack_require__(32);
2884
2885  __webpack_require__(33);
2886
2887  __webpack_require__(17);
2888
2889  var p5SOUND = __webpack_require__(1);
2890
2891  __webpack_require__(6);
2892
2893  __webpack_require__(11);
2894
2895  __webpack_require__(36);
2896
2897  __webpack_require__(40);
2898
2899  __webpack_require__(41);
2900
2901  __webpack_require__(42);
2902
2903  __webpack_require__(43);
2904
2905  __webpack_require__(44);
2906
2907  __webpack_require__(23);
2908
2909  __webpack_require__(47);
2910
2911  __webpack_require__(48);
2912
2913  __webpack_require__(49);
2914
2915  __webpack_require__(50);
2916
2917  __webpack_require__(15);
2918
2919  __webpack_require__(59);
2920
2921  __webpack_require__(61);
2922
2923  __webpack_require__(62);
2924
2925  __webpack_require__(63);
2926
2927  __webpack_require__(64);
2928
2929  __webpack_require__(65);
2930
2931  __webpack_require__(67);
2932
2933  __webpack_require__(68);
2934
2935  __webpack_require__(69);
2936
2937  __webpack_require__(70);
2938
2939  __webpack_require__(71);
2940
2941  __webpack_require__(72);
2942
2943  __webpack_require__(28);
2944
2945  __webpack_require__(30);
2946
2947  __webpack_require__(73);
2948
2949  __webpack_require__(29);
2950
2951  __webpack_require__(28);
2952
2953  __webpack_require__(30);
2954
2955  return p5SOUND;
2956}).call(exports, __webpack_require__, exports, module),
2957				__WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));
2958
2959 }),
2960 (function(module, exports) {
2961
2962!function(){var l,s=[];function p(e){var o=this,n={},i=-1;this.parameters.forEach(function(e,t){var r=s[++i]||(s[i]=new Float32Array(o.bufferSize));r.fill(e.value),n[t]=r}),this.processor.realm.exec("self.sampleRate=sampleRate="+this.context.sampleRate+";self.currentTime=currentTime="+this.context.currentTime);var t=a(e.inputBuffer),r=a(e.outputBuffer);this.instance.process([t],[r],n)}function a(e){for(var t=[],r=0;r<e.numberOfChannels;r++)t[r]=e.getChannelData(r);return t}function f(e){return e.$$processors||(e.$$processors={})}function e(e){this.$$context=e}"function"!=typeof AudioWorkletNode&&(self.AudioWorkletNode=function(e,t,r){var o=f(e)[t],n=e.createScriptProcessor(void 0,2,r&&r.outputChannelCount?r.outputChannelCount[0]:2);if(n.parameters=new Map,o.properties)for(var i=0;i<o.properties.length;i++){var s=o.properties[i],a=e.createGain().gain;a.value=s.defaultValue,n.parameters.set(s.name,a)}var u=new MessageChannel;l=u.port2;var c=new o.Processor(r||{});return l=null,n.port=u.port1,n.processor=o,n.instance=c,n.onaudioprocess=p,n},Object.defineProperty((self.AudioContext||self.webkitAudioContext).prototype,"audioWorklet",{get:function(){return this.$$audioWorklet||(this.$$audioWorklet=new self.AudioWorklet(this))}}),self.AudioWorklet=(e.prototype.addModule=function(e,t){var n=this;return fetch(e).then(function(e){if(!e.ok)throw Error(e.status);return e.text()}).then(function(e){var r={sampleRate:0,currentTime:0,AudioWorkletProcessor:function(){this.port=l},registerProcessor:function(e,t){f(n.$$context)[e]={realm:o,context:r,Processor:t,properties:t.parameterDescriptors||[]}}},o=new function(e,t){var r=document.createElement("iframe");r.style.cssText="position:absolute;left:0;top:-999px;width:1px;height:1px;",t.appendChild(r);var o=r.contentWindow,n=o.document,i="var window,$hook";for(var s in o)s in e||"eval"===s||(i+=",",i+=s);for(var a in e)i+=",",i+=a,i+="=self.",i+=a;var u=n.createElement("script");u.appendChild(n.createTextNode('function $hook(self,console) {"use strict";\n        '+i+";return function() {return eval(arguments[0])}}")),n.body.appendChild(u),this.exec=o.$hook(e,console)}(r.self=r,document.documentElement);return o.exec((t&&t.transpile||String)(e)),null})},e))}();
2963
2964 }),
2965 (function(module, exports, __webpack_require__) {
2966
2967"use strict";
2968var __WEBPACK_AMD_DEFINE_RESULT__;
2969/**
2970 * This module has shims
2971 */
2972
2973!(__WEBPACK_AMD_DEFINE_RESULT__ = (function () {
2974  (function () {
2975    function fixSetTarget(param) {
2976      if (!param) 
2977        return;
2978      if (!param.setTargetAtTime) param.setTargetAtTime = param.setTargetValueAtTime;
2979    }
2980
2981    if (window.hasOwnProperty('webkitAudioContext') && !window.hasOwnProperty('AudioContext')) {
2982      window.AudioContext = window.webkitAudioContext;
2983      if (typeof AudioContext.prototype.createGain !== 'function') AudioContext.prototype.createGain = AudioContext.prototype.createGainNode;
2984      if (typeof AudioContext.prototype.createDelay !== 'function') AudioContext.prototype.createDelay = AudioContext.prototype.createDelayNode;
2985      if (typeof AudioContext.prototype.createScriptProcessor !== 'function') AudioContext.prototype.createScriptProcessor = AudioContext.prototype.createJavaScriptNode;
2986      if (typeof AudioContext.prototype.createPeriodicWave !== 'function') AudioContext.prototype.createPeriodicWave = AudioContext.prototype.createWaveTable;
2987      AudioContext.prototype.internal_createGain = AudioContext.prototype.createGain;
2988
2989      AudioContext.prototype.createGain = function () {
2990        var node = this.internal_createGain();
2991        fixSetTarget(node.gain);
2992        return node;
2993      };
2994
2995      AudioContext.prototype.internal_createDelay = AudioContext.prototype.createDelay;
2996
2997      AudioContext.prototype.createDelay = function (maxDelayTime) {
2998        var node = maxDelayTime ? this.internal_createDelay(maxDelayTime) : this.internal_createDelay();
2999        fixSetTarget(node.delayTime);
3000        return node;
3001      };
3002
3003      AudioContext.prototype.internal_createBufferSource = AudioContext.prototype.createBufferSource;
3004
3005      AudioContext.prototype.createBufferSource = function () {
3006        var node = this.internal_createBufferSource();
3007
3008        if (!node.start) {
3009          node.start = function (when, offset, duration) {
3010            if (offset || duration) this.noteGrainOn(when || 0, offset, duration);else this.noteOn(when || 0);
3011          };
3012        } else {
3013          node.internal_start = node.start;
3014
3015          node.start = function (when, offset, duration) {
3016            if (typeof duration !== 'undefined') node.internal_start(when || 0, offset, duration);else node.internal_start(when || 0, offset || 0);
3017          };
3018        }
3019
3020        if (!node.stop) {
3021          node.stop = function (when) {
3022            this.noteOff(when || 0);
3023          };
3024        } else {
3025          node.internal_stop = node.stop;
3026
3027          node.stop = function (when) {
3028            node.internal_stop(when || 0);
3029          };
3030        }
3031
3032        fixSetTarget(node.playbackRate);
3033        return node;
3034      };
3035
3036      AudioContext.prototype.internal_createDynamicsCompressor = AudioContext.prototype.createDynamicsCompressor;
3037
3038      AudioContext.prototype.createDynamicsCompressor = function () {
3039        var node = this.internal_createDynamicsCompressor();
3040        fixSetTarget(node.threshold);
3041        fixSetTarget(node.knee);
3042        fixSetTarget(node.ratio);
3043        fixSetTarget(node.reduction);
3044        fixSetTarget(node.attack);
3045        fixSetTarget(node.release);
3046        return node;
3047      };
3048
3049      AudioContext.prototype.internal_createBiquadFilter = AudioContext.prototype.createBiquadFilter;
3050
3051      AudioContext.prototype.createBiquadFilter = function () {
3052        var node = this.internal_createBiquadFilter();
3053        fixSetTarget(node.frequency);
3054        fixSetTarget(node.detune);
3055        fixSetTarget(node.Q);
3056        fixSetTarget(node.gain);
3057        return node;
3058      };
3059
3060      if (typeof AudioContext.prototype.createOscillator !== 'function') {
3061        AudioContext.prototype.internal_createOscillator = AudioContext.prototype.createOscillator;
3062
3063        AudioContext.prototype.createOscillator = function () {
3064          var node = this.internal_createOscillator();
3065
3066          if (!node.start) {
3067            node.start = function (when) {
3068              this.noteOn(when || 0);
3069            };
3070          } else {
3071            node.internal_start = node.start;
3072
3073            node.start = function (when) {
3074              node.internal_start(when || 0);
3075            };
3076          }
3077
3078          if (!node.stop) {
3079            node.stop = function (when) {
3080              this.noteOff(when || 0);
3081            };
3082          } else {
3083            node.internal_stop = node.stop;
3084
3085            node.stop = function (when) {
3086              node.internal_stop(when || 0);
3087            };
3088          }
3089
3090          if (!node.setPeriodicWave) node.setPeriodicWave = node.setWaveTable;
3091          fixSetTarget(node.frequency);
3092          fixSetTarget(node.detune);
3093          return node;
3094        };
3095      }
3096    }
3097
3098    if (window.hasOwnProperty('webkitOfflineAudioContext') && !window.hasOwnProperty('OfflineAudioContext')) {
3099      window.OfflineAudioContext = window.webkitOfflineAudioContext;
3100    }
3101  })(window); 
3102
3103
3104  navigator.getUserMedia = navigator.getUserMedia || navigator.webkitGetUserMedia || navigator.mozGetUserMedia || navigator.msGetUserMedia;
3105  /**
3106   * Determine which filetypes are supported (inspired by buzz.js)
3107   * The audio element (el) will only be used to test browser support for various audio formats
3108   */
3109
3110  var el = document.createElement('audio');
3111
3112  p5.prototype.isSupported = function () {
3113    return !!el.canPlayType;
3114  };
3115
3116  var isOGGSupported = function isOGGSupported() {
3117    return !!el.canPlayType && el.canPlayType('audio/ogg; codecs="vorbis"');
3118  };
3119
3120  var isMP3Supported = function isMP3Supported() {
3121    return !!el.canPlayType && el.canPlayType('audio/mpeg;');
3122  };
3123
3124  var isWAVSupported = function isWAVSupported() {
3125    return !!el.canPlayType && el.canPlayType('audio/wav; codecs="1"');
3126  };
3127
3128  var isAACSupported = function isAACSupported() {
3129    return !!el.canPlayType && (el.canPlayType('audio/x-m4a;') || el.canPlayType('audio/aac;'));
3130  };
3131
3132  var isAIFSupported = function isAIFSupported() {
3133    return !!el.canPlayType && el.canPlayType('audio/x-aiff;');
3134  };
3135
3136  p5.prototype.isFileSupported = function (extension) {
3137    switch (extension.toLowerCase()) {
3138      case 'mp3':
3139        return isMP3Supported();
3140
3141      case 'wav':
3142        return isWAVSupported();
3143
3144      case 'ogg':
3145        return isOGGSupported();
3146
3147      case 'aac':
3148      case 'm4a':
3149      case 'mp4':
3150        return isAACSupported();
3151
3152      case 'aif':
3153      case 'aiff':
3154        return isAIFSupported();
3155
3156      default:
3157        return false;
3158    }
3159  };
3160}).call(exports, __webpack_require__, exports, module),
3161				__WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));
3162
3163 }),
3164 (function(module, exports) {
3165
3166var g;g=function(){return this}();try{g=g||new Function("return this")()}catch(t){"object"==typeof window&&(g=window)}module.exports=g;
3167
3168 }),
3169 (function(module, exports, __webpack_require__) {
3170
3171var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;!function(e,t){ true?!(__WEBPACK_AMD_DEFINE_ARRAY__ = [], __WEBPACK_AMD_DEFINE_FACTORY__ = (t),
3172				__WEBPACK_AMD_DEFINE_RESULT__ = (typeof __WEBPACK_AMD_DEFINE_FACTORY__ === 'function' ?
3173				(__WEBPACK_AMD_DEFINE_FACTORY__.apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__)) : __WEBPACK_AMD_DEFINE_FACTORY__),
3174				__WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)):undefined}(this,function(){var r=function(e,t){this._dragged=!1,this._element=e,this._bindedMove=this._moved.bind(this),this._bindedEnd=this._ended.bind(this,t),e.addEventListener("touchstart",this._bindedEnd),e.addEventListener("touchmove",this._bindedMove),e.addEventListener("touchend",this._bindedEnd),e.addEventListener("mouseup",this._bindedEnd)};function o(e){return"running"===e.state}return r.prototype._moved=function(e){this._dragged=!0},r.prototype._ended=function(e){this._dragged||function(e){var t=e.createBuffer(1,1,e.sampleRate),n=e.createBufferSource();n.buffer=t,n.connect(e.destination),n.start(0),e.resume&&e.resume()}(e),this._dragged=!1},r.prototype.dispose=function(){this._element.removeEventListener("touchstart",this._bindedEnd),this._element.removeEventListener("touchmove",this._bindedMove),this._element.removeEventListener("touchend",this._bindedEnd),this._element.removeEventListener("mouseup",this._bindedEnd),this._bindedMove=null,this._bindedEnd=null,this._element=null},function(t,e,n){var i=new Promise(function(e){!function(t,n){o(t)?n():function e(){o(t)?n():(requestAnimationFrame(e),t.resume&&t.resume())}()}(t,e)}),d=[];return function e(t,n,i){if(Array.isArray(t)||NodeList&&t instanceof NodeList)for(var d=0;d<t.length;d++)e(t[d],n,i);else if("string"==typeof t)e(document.querySelectorAll(t),n,i);else if(t.jquery&&"function"==typeof t.toArray)e(t.toArray(),n,i);else if(Element&&t instanceof Element){var o=new r(t,i);n.push(o)}}(e=e||document.body,d,t),i.then(function(){for(var e=0;e<d.length;e++)d[e].dispose();d=null,n&&n()}),i}});
3175
3176 }),
3177 (function(module, exports, __webpack_require__) {
3178
3179var p5sound = __webpack_require__(1);
3180
3181var moduleSources = [__webpack_require__(37)["default"], __webpack_require__(38)["default"], __webpack_require__(39)["default"]];
3182var ac = p5sound.audiocontext;
3183var initializedAudioWorklets = false;
3184
3185function loadAudioWorkletModules() {
3186  return Promise.all(moduleSources.map(function (moduleSrc) {
3187    var blob = new Blob([moduleSrc], {
3188      type: 'application/javascript'
3189    });
3190    var objectURL = URL.createObjectURL(blob);
3191    return ac.audioWorklet.addModule(objectURL);
3192  }));
3193}
3194
3195p5.prototype.registerMethod('init', function () {
3196  if (initializedAudioWorklets) return; 
3197
3198  if (!this.preload && !window.preload) {
3199    this.preload = function () {};
3200  } 
3201
3202
3203  this._incrementPreload();
3204
3205  var onWorkletModulesLoad = function () {
3206    initializedAudioWorklets = true;
3207
3208    this._decrementPreload();
3209  }.bind(this);
3210
3211  loadAudioWorkletModules().then(onWorkletModulesLoad);
3212});
3213
3214 }),
3215 (function(module, __webpack_exports__, __webpack_require__) {
3216
3217"use strict";
3218__webpack_require__.r(__webpack_exports__);
3219 __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 _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, { c
3219onstructor: { 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\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\n// import dependencies via preval.require so that they're available as values at compile time\nvar processorNames = {\n  \"recorderProcessor\": \"recorder-processor\",\n  \"soundFileProcessor\": \"sound-file-processor\",\n  \"amplitudeProcessor\": \"amplitude-processor\"\n};\nvar RingBuffer = {\n  \"default\":\n  /*#__PURE__*/\n  function () {\n    /**\n     * @constructor\n     * @param  {number} length Buffer length in frames.\n     * @param  {number} channelCount Buffer channel count.\n     */\n    function RingBuffer(length, channelCount) {\n      _classCallCheck(this, RingBuffer);\n\n      this._readIndex = 0;\n      this._writeIndex = 0;\n      this._framesAvailable = 0;\n      this._channelCount = channelCount;\n      this._length = length;\n      this._channelData = [];\n\n      for (var i = 0; i < this._channelCount; ++i) {\n        this._channelData[i] = new Float32Array(length);\n      }\n    }\n    /**\n     * Getter for Available frames in buffer.\n     *\n     * @return {number} Available frames in buffer.\n     */\n\n\n    _createClass(RingBuffer, [{\n      key: \"push\",\n\n      /**\n       * Push a sequence of Float32Arrays to buffer.\n       *\n       * @param  {array} arraySequence A sequence of Float32Arrays.\n       */\n      value: function push(arraySequence) {\n        // The channel count of arraySequence and the length of each channel must\n        // match with this buffer obejct.\n        // Transfer data from the |arraySequence| storage to the internal buffer.\n        var sourceLength = arraySequence[0].length;\n\n        for (var i = 0; i < sourceLength;
3219 ++i) {\n          var writeIndex = (this._writeIndex + i) % this._length;\n\n          for (var channel = 0; channel < this._channelCount; ++channel) {\n            this._channelData[channel][writeIndex] = arraySequence[channel][i];\n          }\n        }\n\n        this._writeIndex += sourceLength;\n\n        if (this._writeIndex >= this._length) {\n          this._writeIndex = 0;\n        } // For excessive frames, the buffer will be overwritten.\n\n\n        this._framesAvailable += sourceLength;\n\n        if (this._framesAvailable > this._length) {\n          this._framesAvailable = this._length;\n        }\n      }\n      /**\n       * Pull data out of buffer and fill a given sequence of Float32Arrays.\n       *\n       * @param  {array} arraySequence An array of Float32Arrays.\n       */\n\n    }, {\n      key: \"pull\",\n      value: function pull(arraySequence) {\n        // The channel count of arraySequence and the length of each channel must\n        // match with this buffer obejct.\n        // If the FIFO is completely empty, do nothing.\n        if (this._framesAvailable === 0) {\n          return;\n        }\n\n        var destinationLength = arraySequence[0].length; // Transfer data from the internal buffer to the |arraySequence| storage.\n\n        for (var i = 0; i < destinationLength; ++i) {\n          var readIndex = (this._readIndex + i) % this._length;\n\n          for (var channel = 0; channel < this._channelCount; ++channel) {\n            arraySequence[channel][i] = this._channelData[channel][readIndex];\n          }\n        }\n\n        this._readIndex += destinationLength;\n\n        if (this._readIndex >= this._length) {\n          this._readIndex = 0;\n        }\n\n        this._framesAvailable -= destinationLength;\n\n        if (this._framesAvailable < 0) {\n          this._framesAvailable = 0;\n        }\n      }\n    }, {\n      key: \"framesAvailable\",\n      get: function get() {\n        return this._framesAvailable;\n      }\n    }]);\n\n    return RingBuffer;\n  }()\n}[\"default\"];\n\nvar RecorderProcessor =\n/*#__PURE__*/\nfunction (_AudioWorkletProcesso) {\n  _inherits(RecorderProcessor, _AudioWorkletProcesso);\n\n  function RecorderProcessor(options) {\n    var _this;\n\n    _classCallCheck(this, RecorderProcessor);\n\n    _this = _possibleConstructorReturn(this, _getPrototypeOf(RecorderProcessor).call(this));\n    var processorOptions = options.processorOptions || {};\n    _this.numOutputChannels = options.outputChannelCount || 2;\n    _this.numInputChannels = processorOptions.numInputChannels || 2;\n    _this.bufferSize = processorOptions.bufferSize || 1024;\n    _this.recording = false;\n\n    _this.clear();\n\n    _this.port.onmessage = function (event) {\n      var data = event.data;\n\n      if (data.name === 'start') {\n        _this.record(data.duration);\n      } else if (data.name === 'stop') {\n        _this.stop();\n      }\n    };\n\n    return _this;\n  }\n\n  _createClass(RecorderProcessor, [{\n    key: \"process\",\n    value: function process(inputs) {\n      if (!this.recording) {\n        return true;\n      } else if (this.sampleLimit && this.recordedSamples >= this.sampleLimit) {\n        this.stop();\n        return true;\n      }\n\n      var input = inputs[0];\n      this.inputRingBuffer.push(input);\n\n      if (this.inputRingBuffer.framesAvailable >= this.bufferSize) {\n        this.inputRingBuffer.pull(this.inputRingBufferArraySequence);\n\n        for (var channel = 0; channel < this.numOutputChannels; ++channel) {\n          var inputChannelCopy = this.inputRingBufferArraySequence[channel].slice();\n\n          if (channel === 0) {\n            this.leftBuffers.push(inputChannelCopy);\n\n            if (this.numInputChannels === 1) {\n              this.rightBuffers.push(inputChannelCopy);\n            }\n          } else if (channel === 1 && this.numInputChannels > 1) {\n            this.rightBuffers.push(inputChannelCopy);\n          }\n        }\n\n        this.recordedSamples += this.bufferSize;\n      }\n\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;
3219 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      var _this2 = this;\n\n      this.leftBuffers = [];\n      this.rightBuffers = [];\n      this.inputRingBuffer = new RingBuffer(this.bufferSize, this.numInputChannels);\n      this.inputRingBufferArraySequence = new Array(this.numInputChannels).fill(null).map(function () {\n        return new Float32Array(_this2.bufferSize);\n      });\n      this.recordedSamples = 0;\n      this.sampleLimit = null;\n    }\n  }]);\n\n  return RecorderProcessor;\n}(_wrapNativeSuper(AudioWorkletProcessor));\n\nregisterProcessor(processorNames.recorderProcessor, RecorderProcessor);");
3220
3221 }),
3222 (function(module, __webpack_exports__, __webpack_require__) {
3223
3224"use strict";
3225__webpack_require__.r(__webpack_exports__);
3226 __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 _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\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\n// import dependencies via preval.require so that they're available as values at compile time\nvar processorNames = {\n  \"recorderProcessor\": \"recorder-processor\",\n  \"soundFileProcessor\": \"sound-file-processor\",\n  \"amplitudeProcessor\": \"amplitude-processor\"\n};\nvar RingBuffer = {\n  \"default\":\n  /*#__PURE__*/\n  function () {\n    /**\n     * @constructor\n     * @param  {number} length Buffer length in frames.\n     * @param  {number} channelCount Buffer channel count.\n     */\n    function RingBuffer(length, channelCount) {\n      _classCallCheck(this, RingBuffer);\n\n      this._readIndex = 0;\n      this._writeIndex = 0;\n      this._framesAvailable = 0;\n      this._channelCount = channelCount;\n      this._length = length;\n      this._channelData = [];\n\n      for (var i = 0; i < this._channelCount; ++i) {\n        this._channelData[i] = new Float32Array(length);\n      }\n    }\n    /**\n     * Getter for Available frames in buffer.\n     *\n     * @return {number} Available frames in buffer.\n     */\n\n\n    _createClass(RingBuffer, [{\
3226n      key: \"push\",\n\n      /**\n       * Push a sequence of Float32Arrays to buffer.\n       *\n       * @param  {array} arraySequence A sequence of Float32Arrays.\n       */\n      value: function push(arraySequence) {\n        // The channel count of arraySequence and the length of each channel must\n        // match with this buffer obejct.\n        // Transfer data from the |arraySequence| storage to the internal buffer.\n        var sourceLength = arraySequence[0].length;\n\n        for (var i = 0; i < sourceLength; ++i) {\n          var writeIndex = (this._writeIndex + i) % this._length;\n\n          for (var channel = 0; channel < this._channelCount; ++channel) {\n            this._channelData[channel][writeIndex] = arraySequence[channel][i];\n          }\n        }\n\n        this._writeIndex += sourceLength;\n\n        if (this._writeIndex >= this._length) {\n          this._writeIndex = 0;\n        } // For excessive frames, the buffer will be overwritten.\n\n\n        this._framesAvailable += sourceLength;\n\n        if (this._framesAvailable > this._length) {\n          this._framesAvailable = this._length;\n        }\n      }\n      /**\n       * Pull data out of buffer and fill a given sequence of Float32Arrays.\n       *\n       * @param  {array} arraySequence An array of Float32Arrays.\n       */\n\n    }, {\n      key: \"pull\",\n      value: function pull(arraySequence) {\n        // The channel count of arraySequence and the length of each channel must\n        // match with this buffer obejct.\n        // If the FIFO is completely empty, do nothing.\n        if (this._framesAvailable === 0) {\n          return;\n        }\n\n        var destinationLength = arraySequence[0].length; // Transfer data from the internal buffer to the |arraySequence| storage.\n\n        for (var i = 0; i < destinationLength; ++i) {\n          var readIndex = (this._readIndex + i) % this._length;\n\n          for (var channel = 0; channel < this._channelCount; ++channel) {\n            arraySequence[channel][i] = this._channelData[channel][readIndex];\n          }\n        }\n\n        this._readIndex += destinationLength;\n\n        if (this._readIndex >= this._length) {\n          this._readIndex = 0;\n        }\n\n        this._framesAvailable -= destinationLength;\n\n        if (this._framesAvailable < 0) {\n          this._framesAvailable = 0;\n        }\n      }\n    }, {\n      key: \"framesAvailable\",\n      get: function get() {\n        return this._framesAvailable;\n      }\n    }]);\n\n    return RingBuffer;\n  }()\n}[\"default\"];\n\nvar SoundFileProcessor =\n/*#__PURE__*/\nfunction (_AudioWorkletProcesso) {\n  _inherits(SoundFileProcessor, _AudioWorkletProcesso);\n\n  function SoundFileProcessor(options) {\n    var _this;\n\n    _classCallCheck(this, SoundFileProcessor);\n\n    _this = _possibleConstructorReturn(this, _getPrototypeOf(SoundFileProcessor).call(this));\n    var processorOptions = options.processorOptions || {};\n    _this.bufferSize = processorOptions.bufferSize || 256;\n    _this.inputRingBuffer = new RingBuffer(_this.bufferSize, 1);\n    _this.inputRingBufferArraySequence = [new Float32Array(_this.bufferSize)];\n    return _this;\n  }\n\n  _createClass(SoundFileProcessor, [{\n    key: \"process\",\n    value: function process(inputs) {\n      var input = inputs[0]; // we only care about the first input channel, because that contains the position data\n\n      this.inputRingBuffer.push([input[0]]);\n\n      if (this.inputRingBuffer.framesAvailable >= this.bufferSize) {\n        this.inputRingBuffer.pull(this.inputRingBufferArraySequence);\n        var inputChannel = this.inputRingBufferArraySequence[0];\n        var position = inputChannel[inputChannel.length - 1] || 0;\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);");
3227
3228 }),
3229 (function(module, __webpack_exports__, __webpack_require__) {
3230
3231"use strict";
3232__webpack_require__.r(__webpack_exports__);
3233 __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 _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, { c
3233onstructor: { 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\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\n// import dependencies via preval.require so that they're available as values at compile time\nvar processorNames = {\n  \"recorderProcessor\": \"recorder-processor\",\n  \"soundFileProcessor\": \"sound-file-processor\",\n  \"amplitudeProcessor\": \"amplitude-processor\"\n};\nvar RingBuffer = {\n  \"default\":\n  /*#__PURE__*/\n  function () {\n    /**\n     * @constructor\n     * @param  {number} length Buffer length in frames.\n     * @param  {number} channelCount Buffer channel count.\n     */\n    function RingBuffer(length, channelCount) {\n      _classCallCheck(this, RingBuffer);\n\n      this._readIndex = 0;\n      this._writeIndex = 0;\n      this._framesAvailable = 0;\n      this._channelCount = channelCount;\n      this._length = length;\n      this._channelData = [];\n\n      for (var i = 0; i < this._channelCount; ++i) {\n        this._channelData[i] = new Float32Array(length);\n      }\n    }\n    /**\n     * Getter for Available frames in buffer.\n     *\n     * @return {number} Available frames in buffer.\n     */\n\n\n    _createClass(RingBuffer, [{\n      key: \"push\",\n\n      /**\n       * Push a sequence of Float32Arrays to buffer.\n       *\n       * @param  {array} arraySequence A sequence of Float32Arrays.\n       */\n      value: function push(arraySequence) {\n        // The channel count of arraySequence and the length of each channel must\n        // match with this buffer obejct.\n        // Transfer data from the |arraySequence| storage to the internal buffer.\n        var sourceLength = arraySequence[0].length;\n\n        for (var i = 0; i < sourceLength;
3233 ++i) {\n          var writeIndex = (this._writeIndex + i) % this._length;\n\n          for (var channel = 0; channel < this._channelCount; ++channel) {\n            this._channelData[channel][writeIndex] = arraySequence[channel][i];\n          }\n        }\n\n        this._writeIndex += sourceLength;\n\n        if (this._writeIndex >= this._length) {\n          this._writeIndex = 0;\n        } // For excessive frames, the buffer will be overwritten.\n\n\n        this._framesAvailable += sourceLength;\n\n        if (this._framesAvailable > this._length) {\n          this._framesAvailable = this._length;\n        }\n      }\n      /**\n       * Pull data out of buffer and fill a given sequence of Float32Arrays.\n       *\n       * @param  {array} arraySequence An array of Float32Arrays.\n       */\n\n    }, {\n      key: \"pull\",\n      value: function pull(arraySequence) {\n        // The channel count of arraySequence and the length of each channel must\n        // match with this buffer obejct.\n        // If the FIFO is completely empty, do nothing.\n        if (this._framesAvailable === 0) {\n          return;\n        }\n\n        var destinationLength = arraySequence[0].length; // Transfer data from the internal buffer to the |arraySequence| storage.\n\n        for (var i = 0; i < destinationLength; ++i) {\n          var readIndex = (this._readIndex + i) % this._length;\n\n          for (var channel = 0; channel < this._channelCount; ++channel) {\n            arraySequence[channel][i] = this._channelData[channel][readIndex];\n          }\n        }\n\n        this._readIndex += destinationLength;\n\n        if (this._readIndex >= this._length) {\n          this._readIndex = 0;\n        }\n\n        this._framesAvailable -= destinationLength;\n\n        if (this._framesAvailable < 0) {\n          this._framesAvailable = 0;\n        }\n      }\n    }, {\n      key: \"framesAvailable\",\n      get: function get() {\n        return this._framesAvailable;\n      }\n    }]);\n\n    return RingBuffer;\n  }()\n}[\"default\"];\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.numOutputChannels = options.outputChannelCount || 1;\n    _this.numInputChannels = processorOptions.numInputChannels || 2;\n    _this.normalize = processorOptions.normalize || false;\n    _this.smoothing = processorOptions.smoothing || 0;\n    _this.bufferSize = processorOptions.bufferSize || 2048;\n    _this.inputRingBuffer = new RingBuffer(_this.bufferSize, _this.numInputChannels);\n    _this.outputRingBuffer = new RingBuffer(_this.bufferSize, _this.numOutputChannels);\n    _this.inputRingBufferArraySequence = new Array(_this.numInputChannels).fill(null).map(function () {\n      return new Float32Array(_this.bufferSize);\n    });\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      this.inputRingBuffer.push(input);\n\n      if (this.inputRingBuffer.framesAvailable >= this.bufferSize) {\n        this.inputRingBuffer.pull(this.inputRingBufferArraySequence);\n\n        for (var channel = 0; channel < this.numInputChannels; ++channel) {\n          var inputBuffer = this.inputRingBufferArraySequence[channel];\n          var bufLength = inputBuffer.length;\n          var sum = 0;\n\n          for (var i = 0; i < bufLength;
3233 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        this.outputRingBuffer.push(this.inputRingBufferArraySequence);\n      } // pull 128 frames out of the ring buffer\n      // if the ring buffer does not have enough frames, the output will be silent\n\n\n      this.outputRingBuffer.pull(output);\n      return true;\n    }\n  }]);\n\n  return AmplitudeProcessor;\n}(_wrapNativeSuper(AudioWorkletProcessor));\n\nregisterProcessor(processorNames.amplitudeProcessor, AmplitudeProcessor);");
3234
3235 }),
3236 (function(module, exports, __webpack_require__) {
3237
3238"use strict";
3239var __WEBPACK_AMD_DEFINE_RESULT__;
3240
3241function _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); }
3242
3243!(__WEBPACK_AMD_DEFINE_RESULT__ = (function (require) {
3244  var p5sound = __webpack_require__(1);
3245
3246  var ac = p5sound.audiocontext; 
3247
3248  if (typeof ac.createStereoPanner !== 'undefined') {
3249    p5.Panner = function (input, output) {
3250      this.stereoPanner = this.input = ac.createStereoPanner();
3251      input.connect(this.stereoPanner);
3252      this.stereoPanner.connect(output);
3253    };
3254
3255    p5.Panner.prototype.pan = function (val, tFromNow) {
3256      var time = tFromNow || 0;
3257      var t = ac.currentTime + time;
3258      this.stereoPanner.pan.linearRampToValueAtTime(val, t);
3259    }; 
3260
3261
3262    p5.Panner.prototype.inputChannels = function () {};
3263
3264    p5.Panner.prototype.connect = function (obj) {
3265      this.stereoPanner.connect(obj);
3266    };
3267
3268    p5.Panner.prototype.disconnect = function () {
3269      if (this.stereoPanner) {
3270        this.stereoPanner.disconnect();
3271      }
3272    };
3273  } else {
3274    p5.Panner = function (input, output, numInputChannels) {
3275      this.input = ac.createGain();
3276      input.connect(this.input);
3277      this.left = ac.createGain();
3278      this.right = ac.createGain();
3279      this.left.channelInterpretation = 'discrete';
3280      this.right.channelInterpretation = 'discrete'; 
3281
3282      if (numInputChannels > 1) {
3283        this.splitter = ac.createChannelSplitter(2);
3284        this.input.connect(this.splitter);
3285        this.splitter.connect(this.left, 1);
3286        this.splitter.connect(this.right, 0);
3287      } else {
3288        this.input.connect(this.left);
3289        this.input.connect(this.right);
3290      }
3291
3292      this.output = ac.createChannelMerger(2);
3293      this.left.connect(this.output, 0, 1);
3294      this.right.connect(this.output, 0, 0);
3295      this.output.connect(output);
3296    }; 
3297
3298
3299    p5.Panner.prototype.pan = function (val, tFromNow) {
3300      var time = tFromNow || 0;
3301      var t = ac.currentTime + time;
3302      var v = (val + 1) / 2;
3303      var rightVal = Math.cos(v * Math.PI / 2);
3304      var leftVal = Math.sin(v * Math.PI / 2);
3305      this.left.gain.linearRampToValueAtTime(leftVal, t);
3306      this.right.gain.linearRampToValueAtTime(rightVal, t);
3307    };
3308
3309    p5.Panner.prototype.inputChannels = function (numChannels) {
3310      if (numChannels === 1) {
3311        this.input.disconnect();
3312        this.input.connect(this.left);
3313        this.input.connect(this.right);
3314      } else if (numChannels === 2) {
3315        if (_typeof(this.splitter === 'undefined')) {
3316          this.splitter = ac.createChannelSplitter(2);
3317        }
3318
3319        this.input.disconnect();
3320        this.input.connect(this.splitter);
3321        this.splitter.connect(this.left, 1);
3322        this.splitter.connect(this.right, 0);
3323      }
3324    };
3325
3326    p5.Panner.prototype.connect = function (obj) {
3327      this.output.connect(obj);
3328    };
3329
3330    p5.Panner.prototype.disconnect = function () {
3331      if (this.output) {
3332        this.output.disconnect();
3333      }
3334    };
3335  }
3336}).call(exports, __webpack_require__, exports, module),
3337				__WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));
3338
3339 }),
3340 (function(module, exports, __webpack_require__) {
3341
3342"use strict";
3343var __WEBPACK_AMD_DEFINE_RESULT__;
3344
3345function _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); }
3346
3347!(__WEBPACK_AMD_DEFINE_RESULT__ = (function (require) {
3348  var CustomError = __webpack_require__(11);
3349
3350  var p5sound = __webpack_require__(1);
3351
3352  var ac = p5sound.audiocontext;
3353
3354  var _require = __webpack_require__(6),
3355      midiToFreq = _require.midiToFreq,
3356      convertToWav = _require.convertToWav,
3357      safeBufferSize = _require.safeBufferSize;
3358
3359  var processorNames = __webpack_require__(10);
3360  /**
3361   *  <p>SoundFile object with a path to a file.</p>
3362   *
3363   *  <p>The p5.SoundFile may not be available immediately because
3364   *  it loads the file information asynchronously.</p>
3365   *
3366   *  <p>To do something with the sound as soon as it loads
3367   *  pass the name of a function as the second parameter.</p>
3368   *
3369   *  <p>Only one file path is required. However, audio file formats
3370   *  (i.e. mp3, ogg, wav and m4a/aac) are not supported by all
3371   *  web browsers. If you want to ensure compatability, instead of a single
3372   *  file path, you may include an Array of filepaths, and the browser will
3373   *  choose a format that works.</p>
3374   *
3375   *  @class p5.SoundFile
3376   *  @constructor
3377   *  @param {String|Array} path   path to a sound file (String). Optionally,
3378   *                               you may include multiple file formats in
3379   *                               an array. Alternately, accepts an object
3380   *                               from the HTML5 File API, or a p5.File.
3381   *  @param {Function} [successCallback]   Name of a function to call once file loads
3382   *  @param {Function} [errorCallback]   Name of a function to call if file fails to
3383   *                                      load. This function will receive an error or
3384   *                                     XMLHttpRequest object with information
3385   *                                     about what went wrong.
3386   *  @param {Function} [whileLoadingCallback]   Name of a function to call while file
3387   *                                             is loading. That function will
3388   *                                             receive progress of the request to
3389   *                                             load the sound file
3390   *                                             (between 0 and 1) as its first
3391   *                                             parameter. This progress
3392   *                                             does not account for the additional
3393   *                                             time needed to decode the audio data.
3394   *
3395   *  @example
3396   *  <div><code>
3397   *  let mySound;
3398   *  function preload() {
3399   *    soundFormats('mp3', 'ogg');
3400   *    mySound = loadSound('assets/doorbell');
3401   *  }
3402   *
3403   *  function setup() {
3404   *    let cnv = createCanvas(100, 100);
3405   *    cnv.mousePressed(canvasPressed);
3406   *    background(220);
3407   *    text('tap here to play', 10, 20);
3408   *  }
3409   *
3410   *  function canvasPressed() {
3411   *    // playing a sound file on a user gesture
3412   *    // is equivalent to `userStartAudio()`
3413   *    mySound.play();
3414   *  }
3415   * </code></div>
3416   */
3417
3418
3419  p5.SoundFile = function (paths, onload, onerror, whileLoading) {
3420    if (typeof paths !== 'undefined') {
3421      if (typeof paths === 'string' || typeof paths[0] === 'string') {
3422        var path = p5.prototype._checkFileFormats(paths);
3423
3424        this.url = path;
3425      } else if (_typeof(paths) === 'object') {
3426        if (!(window.File && window.FileReader && window.FileList && window.Blob)) {
3427          throw 'Unable to load file because the File API is not supported';
3428        }
3429      } 
3430
3431
3432      if (paths.file) {
3433        paths = paths.file;
3434      }
3435
3436      this.file = paths;
3437    } 
3438
3439
3440    this._onended = function () {};
3441
3442    this._looping = false;
3443    this._playing = false;
3444    this._paused = false;
3445    this._pauseTime = 0; 
3446
3447    this._cues = [];
3448    this._cueIDCounter = 0; 
3449
3450    this._lastPos = 0;
3451    this._counterNode = null;
3452    this._workletNode = null; 
3453
3454    this.bufferSourceNodes = []; 
3455
3456    this.bufferSourceNode = null;
3457    this.buffer = null;
3458    this.playbackRate = 1;
3459    this.input = p5sound.audiocontext.createGain();
3460    this.output = p5sound.audiocontext.createGain();
3461    this.reversed = false; 
3462
3463    this.startTime = 0;
3464    this.endTime = null;
3465    this.pauseTime = 0; 
3466
3467    this.mode = 'sustain'; 
3468
3469    this.startMillis = null; 
3470
3471    this.panPosition = 0.0;
3472    this.panner = new p5.Panner(this.output, p5sound.input, 2); 
3473
3474    if (this.url || this.file) {
3475      this.load(onload, onerror);
3476    } 
3477
3478
3479    p5sound.soundArray.push(this);
3480
3481    if (typeof whileLoading === 'function') {
3482      this._whileLoading = whileLoading;
3483    } else {
3484      this._whileLoading = function () {};
3485    }
3486
3487    this._clearOnEnd = _clearOnEnd.bind(this);
3488  }; 
3489
3490
3491  p5.prototype.registerPreloadMethod('loadSound', p5.prototype);
3492  /**
3493   *  loadSound() returns a new p5.SoundFile from a specified
3494   *  path. If called during preload(), the p5.SoundFile will be ready
3495   *  to play in time for setup() and draw(). If called outside of
3496   *  preload, the p5.SoundFile will not be ready immediately, so
3497   *  loadSound accepts a callback as the second parameter. Using a
3498   *  <a href="https://github.com/processing/p5.js/wiki/Local-server">
3499   *  local server</a> is recommended when loading external files.
3500   *
3501   *  @method loadSound
3502   *  @for p5
3503   *  @param  {String|Array}   path     Path to the sound file, or an array with
3504   *                                    paths to soundfiles in multiple formats
3505   *                                    i.e. ['sound.ogg', 'sound.mp3'].
3506   *                                    Alternately, accepts an object: either
3507   *                                    from the HTML5 File API, or a p5.File.
3508   *  @param {Function} [successCallback]   Name of a function to call once file loads
3509   *  @param {Function} [errorCallback]   Name of a function to call if there is
3510   *                                      an error loading the file.
3511   *  @param {Function} [whileLoading] Name of a function to call while file is loading.
3512   *                                 This function will receive the percentage loaded
3513   *                                 so far, from 0.0 to 1.0.
3514   *  @return {SoundFile}            Returns a p5.SoundFile
3515   *  @example
3516   *  <div><code>
3517   *  let mySound;
3518   *  function preload() {
3519   *    soundFormats('mp3', 'ogg');
3520   *    mySound = loadSound('assets/doorbell');
3521   *  }
3522   *
3523   *  function setup() {
3524   *    let cnv = createCanvas(100, 100);
3525   *    cnv.mousePressed(canvasPressed);
3526   *    background(220);
3527   *    text('tap here to play', 10, 20);
3528   *  }
3529   *
3530   *  function canvasPressed() {
3531   *    // playing a sound file on a user gesture
3532   *    // is equivalent to `userStartAudio()`
3533   *    mySound.play();
3534   *  }
3535   *  </code></div>
3536   */
3537
3538  p5.prototype.loadSound = function (path, callback, onerror, whileLoading) {
3539    if (window.location.origin.indexOf('file://') > -1 && window.cordova === 'undefined') {
3540      window.alert('This sketch may require a server to load external files. Please see http://bit.ly/1qcInwS');
3541    }
3542
3543    var self = this;
3544    var s = new p5.SoundFile(path, function () {
3545      if (typeof callback === 'function') {
3546        callback.apply(self, arguments);
3547      }
3548
3549      if (typeof self._decrementPreload === 'function') {
3550        self._decrementPreload();
3551      }
3552    }, onerror, whileLoading);
3553    return s;
3554  };
3555  /**
3556   * This is a helper function that the p5.SoundFile calls to load
3557   * itself. Accepts a callback (the name of another function)
3558   * as an optional parameter.
3559   *
3560   * @private
3561   * @for p5.SoundFile
3562   * @param {Function} [successCallback]   Name of a function to call once file loads
3563   * @param {Function} [errorCallback]   Name of a function to call if there is an error
3564   */
3565
3566
3567  p5.SoundFile.prototype.load = function (callback, errorCallback) {
3568    var self = this;
3569    var errorTrace = new Error().stack;
3570
3571    if (this.url !== undefined && this.url !== '') {
3572      var request = new XMLHttpRequest();
3573      request.addEventListener('progress', function (evt) {
3574        self._updateProgress(evt);
3575      }, false);
3576      request.open('GET', this.url, true);
3577      request.responseType = 'arraybuffer';
3578
3579      request.onload = function () {
3580        if (request.status === 200) {
3581          if (!self.panner) return;
3582          ac.decodeAudioData(request.response, 
3583          function (buff) {
3584            if (!self.panner) return;
3585            self.buffer = buff;
3586            self.panner.inputChannels(buff.numberOfChannels);
3587
3588            if (callback) {
3589              callback(self);
3590            }
3591          }, 
3592          function () {
3593            if (!self.panner) return;
3594            var err = new CustomError('decodeAudioData', errorTrace, self.url);
3595            var msg = 'AudioContext error at decodeAudioData for ' + self.url;
3596
3597            if (errorCallback) {
3598              err.msg = msg;
3599              errorCallback(err);
3600            } else {
3601              console.error(msg + '\n The error stack trace includes: \n' + err.stack);
3602            }
3603          });
3604        } 
3605        else {
3606            if (!self.panner) return;
3607            var err = new CustomError('loadSound', errorTrace, self.url);
3608            var msg = 'Unable to load ' + self.url + '. The request status was: ' + request.status + ' (' + request.statusText + ')';
3609
3610            if (errorCallback) {
3611              err.message = msg;
3612              errorCallback(err);
3613            } else {
3614              console.error(msg + '\n The error stack trace includes: \n' + err.stack);
3615            }
3616          }
3617      }; 
3618
3619
3620      request.onerror = function () {
3621        var err = new CustomError('loadSound', errorTrace, self.url);
3622        var msg = 'There was no response from the server at ' + self.url + '. Check the url and internet connectivity.';
3623
3624        if (errorCallback) {
3625          err.message = msg;
3626          errorCallback(err);
3627        } else {
3628          console.error(msg + '\n The error stack trace includes: \n' + err.stack);
3629        }
3630      };
3631
3632      request.send();
3633    } else if (this.file !== undefined) {
3634      var reader = new FileReader();
3635
3636      reader.onload = function () {
3637        if (!self.panner) return;
3638        ac.decodeAudioData(reader.result, function (buff) {
3639          if (!self.panner) return;
3640          self.buffer = buff;
3641          self.panner.inputChannels(buff.numberOfChannels);
3642
3643          if (callback) {
3644            callback(self);
3645          }
3646        });
3647      };
3648
3649      reader.onerror = function (e) {
3650        if (!self.panner) return;
3651
3652        if (onerror) {
3653          onerror(e);
3654        }
3655      };
3656
3657      reader.readAsArrayBuffer(this.file);
3658    }
3659  }; 
3660
3661
3662  p5.SoundFile.prototype._updateProgress = function (evt) {
3663    if (evt.lengthComputable) {
3664      var percentComplete = evt.loaded / evt.total * 0.99;
3665
3666      this._whileLoading(percentComplete, evt); 
3667
3668    } else {
3669      this._whileLoading('size unknown');
3670    }
3671  };
3672  /**
3673   *  Returns true if the sound file finished loading successfully.
3674   *
3675   *  @method  isLoaded
3676   *  @for p5.SoundFile
3677   *  @return {Boolean}
3678   */
3679
3680
3681  p5.SoundFile.prototype.isLoaded = function () {
3682    if (this.buffer) {
3683      return true;
3684    } else {
3685      return false;
3686    }
3687  };
3688  /**
3689   * Play the p5.SoundFile
3690   *
3691   * @method play
3692   * @for p5.SoundFile
3693   * @param {Number} [startTime]            (optional) schedule playback to start (in seconds from now).
3694   * @param {Number} [rate]             (optional) playback rate
3695   * @param {Number} [amp]              (optional) amplitude (volume)
3696   *                                     of playback
3697   * @param {Number} [cueStart]        (optional) cue start time in seconds
3698   * @param {Number} [duration]          (optional) duration of playback in seconds
3699   */
3700
3701
3702  p5.SoundFile.prototype.play = function (startTime, rate, amp, _cueStart, duration) {
3703    if (!this.output) {
3704      console.warn('SoundFile.play() called after dispose');
3705      return;
3706    }
3707
3708    var now = p5sound.audiocontext.currentTime;
3709    var cueStart, cueEnd;
3710    var time = startTime || 0;
3711
3712    if (time < 0) {
3713      time = 0;
3714    }
3715
3716    time = time + now;
3717
3718    if (typeof rate !== 'undefined') {
3719      this.rate(rate);
3720    }
3721
3722    if (typeof amp !== 'undefined') {
3723      this.setVolume(amp);
3724    } 
3725
3726
3727    if (this.buffer) {
3728      this._pauseTime = 0; 
3729
3730      if (this.mode === 'restart' && this.buffer && this.bufferSourceNode) {
3731        this.bufferSourceNode.stop(time);
3732
3733        this._counterNode.stop(time);
3734      } 
3735
3736
3737      if (this.mode === 'untildone' && this.isPlaying()) {
3738        return;
3739      } 
3740
3741
3742      this.bufferSourceNode = this._initSourceNode(); 
3743
3744      delete this._counterNode;
3745      this._counterNode = this._initCounterNode();
3746
3747      if (_cueStart) {
3748        if (_cueStart >= 0 && _cueStart < this.buffer.duration) {
3749          cueStart = _cueStart;
3750        } else {
3751          throw 'start time out of range';
3752        }
3753      } else {
3754        cueStart = 0;
3755      }
3756
3757      if (duration) {
3758        duration = duration <= this.buffer.duration - cueStart ? duration : this.buffer.duration;
3759      } 
3760
3761
3762      if (this._paused) {
3763        this.bufferSourceNode.start(time, this.pauseTime, duration);
3764
3765        this._counterNode.start(time, this.pauseTime, duration);
3766      } else {
3767        this.bufferSourceNode.start(time, cueStart, duration);
3768
3769        this._counterNode.start(time, cueStart, duration);
3770      }
3771
3772      this._playing = true;
3773      this._paused = false; 
3774
3775      this.bufferSourceNodes.push(this.bufferSourceNode);
3776      this.bufferSourceNode._arrayIndex = this.bufferSourceNodes.length - 1;
3777      this.bufferSourceNode.addEventListener('ended', this._clearOnEnd);
3778    } 
3779    else {
3780        throw 'not ready to play file, buffer has yet to load. Try preload()';
3781      } 
3782
3783
3784    this.bufferSourceNode.loop = this._looping;
3785    this._counterNode.loop = this._looping;
3786
3787    if (this._looping === true) {
3788      cueEnd = duration ? duration : cueStart - 0.000000000000001;
3789      this.bufferSourceNode.loopStart = cueStart;
3790      this.bufferSourceNode.loopEnd = cueEnd;
3791      this._counterNode.loopStart = cueStart;
3792      this._counterNode.loopEnd = cueEnd;
3793    }
3794  };
3795  /**
3796   *  p5.SoundFile has two play modes: <code>restart</code> and
3797   *  <code>sustain</code>. Play Mode determines what happens to a
3798   *  p5.SoundFile if it is triggered while in the middle of playback.
3799   *  In sustain mode, playback will continue simultaneous to the
3800   *  new playback. In restart mode, play() will stop playback
3801   *  and start over. With untilDone, a sound will play only if it's
3802   *  not already playing. Sustain is the default mode.
3803   *
3804   *  @method  playMode
3805   *  @for p5.SoundFile
3806   *  @param  {String} str 'restart' or 'sustain' or 'untilDone'
3807   *  @example
3808   *  <div><code>
3809   *  let mySound;
3810   *  function preload(){
3811   *    mySound = loadSound('assets/Damscray_DancingTiger.mp3');
3812   *  }
3813   *  function setup() {
3814   *    let cnv = createCanvas(100, 100);
3815   *    cnv.mousePressed(canvasPressed);
3816   *    noFill();
3817   *    rect(0, height/2, width - 1, height/2 - 1);
3818   *    rect(0, 0, width - 1, height/2);
3819   *    textAlign(CENTER, CENTER);
3820   *    fill(20);
3821   *    text('restart', width/2, 1 * height/4);
3822   *    text('sustain', width/2, 3 * height/4);
3823   *  }
3824   *  function canvasPressed() {
3825   *    if (mouseX < height/2) {
3826   *      mySound.playMode('restart');
3827   *    } else {
3828   *      mySound.playMode('sustain');
3829   *    }
3830   *    mySound.play();
3831   *  }
3832   *
3833   * </code></div>
3834   */
3835
3836
3837  p5.SoundFile.prototype.playMode = function (str) {
3838    var s = str.toLowerCase(); 
3839
3840    if (s === 'restart' && this.buffer && this.bufferSourceNode) {
3841      for (var i = 0; i < this.bufferSourceNodes.length - 1; i++) {
3842        var now = p5sound.audiocontext.currentTime;
3843        this.bufferSourceNodes[i].stop(now);
3844      }
3845    } 
3846
3847
3848    if (s === 'restart' || s === 'sustain' || s === 'untildone') {
3849      this.mode = s;
3850    } else {
3851      throw 'Invalid play mode. Must be either "restart" or "sustain"';
3852    }
3853  };
3854  /**
3855   *  Pauses a file that is currently playing. If the file is not
3856   *  playing, then nothing will happen.
3857   *
3858   *  After pausing, .play() will resume from the paused
3859   *  position.
3860   *  If p5.SoundFile had been set to loop before it was paused,
3861   *  it will continue to loop after it is unpaused with .play().
3862   *
3863   *  @method pause
3864   *  @for p5.SoundFile
3865   *  @param {Number} [startTime] (optional) schedule event to occur
3866   *                               seconds from now
3867   *  @example
3868   *  <div><code>
3869   *  let soundFile;
3870   *  function preload() {
3871   *    soundFormats('ogg', 'mp3');
3872   *    soundFile = loadSound('assets/Damscray_-_Dancing_Tiger_02.mp3');
3873   *  }
3874   *  function setup() {
3875   *    let cnv = createCanvas(100, 100);
3876   *    cnv.mousePressed(canvasPressed);
3877   *    background(220);
3878   *    text('tap to play, release to pause', 10, 20, width - 20);
3879   *  }
3880   *  function canvasPressed() {
3881   *    soundFile.loop();
3882   *    background(0, 200, 50);
3883   *  }
3884   *  function mouseReleased() {
3885   *    soundFile.pause();
3886   *    background(220);
3887   *  }
3888   *  </code>
3889   *  </div>
3890   */
3891
3892
3893  p5.SoundFile.prototype.pause = function (startTime) {
3894    var now = p5sound.audiocontext.currentTime;
3895    var time = startTime || 0;
3896    var pTime = time + now;
3897
3898    if (this.isPlaying() && this.buffer && this.bufferSourceNode) {
3899      this._paused = true;
3900      this._playing = false;
3901      this.pauseTime = this.currentTime();
3902      this.bufferSourceNode.stop(pTime);
3903
3904      this._counterNode.stop(pTime);
3905
3906      this._pauseTime = this.currentTime(); 
3907    } else {
3908      this._pauseTime = 0;
3909    }
3910  };
3911  /**
3912   * Loop the p5.SoundFile. Accepts optional parameters to set the
3913   * playback rate, playback volume, loopStart, loopEnd.
3914   *
3915   * @method loop
3916   * @for p5.SoundFile
3917   * @param {Number} [startTime] (optional) schedule event to occur
3918   *                             seconds from now
3919   * @param {Number} [rate]        (optional) playback rate
3920   * @param {Number} [amp]         (optional) playback volume
3921   * @param {Number} [cueLoopStart] (optional) startTime in seconds
3922   * @param {Number} [duration]  (optional) loop duration in seconds
3923   * @example
3924   *  <div><code>
3925   *  let soundFile;
3926   *  let loopStart = 0.5;
3927   *  let loopDuration = 0.2;
3928   *  function preload() {
3929   *    soundFormats('ogg', 'mp3');
3930   *    soundFile = loadSound('assets/Damscray_-_Dancing_Tiger_02.mp3');
3931   *  }
3932   *  function setup() {
3933   *    let cnv = createCanvas(100, 100);
3934   *    cnv.mousePressed(canvasPressed);
3935   *    background(220);
3936   *    text('tap to play, release to pause', 10, 20, width - 20);
3937   *  }
3938   *  function canvasPressed() {
3939   *    soundFile.loop();
3940   *    background(0, 200, 50);
3941   *  }
3942   *  function mouseReleased() {
3943   *    soundFile.pause();
3944   *    background(220);
3945   *  }
3946   *  </code>
3947   *  </div>
3948   */
3949
3950
3951  p5.SoundFile.prototype.loop = function (startTime, rate, amp, loopStart, duration) {
3952    this._looping = true;
3953    this.play(startTime, rate, amp, loopStart, duration);
3954  };
3955  /**
3956   * Set a p5.SoundFile's looping flag to true or false. If the sound
3957   * is currently playing, this change will take effect when it
3958   * reaches the end of the current playback.
3959   *
3960   * @method setLoop
3961   * @for p5.SoundFile
3962   * @param {Boolean} Boolean   set looping to true or false
3963   */
3964
3965
3966  p5.SoundFile.prototype.setLoop = function (bool) {
3967    if (bool === true) {
3968      this._looping = true;
3969    } else if (bool === false) {
3970      this._looping = false;
3971    } else {
3972      throw 'Error: setLoop accepts either true or false';
3973    }
3974
3975    if (this.bufferSourceNode) {
3976      this.bufferSourceNode.loop = this._looping;
3977      this._counterNode.loop = this._looping;
3978    }
3979  };
3980  /**
3981   * Returns 'true' if a p5.SoundFile is currently looping and playing, 'false' if not.
3982   *
3983   * @method isLooping
3984   * @for p5.SoundFile
3985   * @return {Boolean}
3986   */
3987
3988
3989  p5.SoundFile.prototype.isLooping = function () {
3990    if (!this.bufferSourceNode) {
3991      return false;
3992    }
3993
3994    if (this._looping === true && this.isPlaying() === true) {
3995      return true;
3996    }
3997
3998    return false;
3999  };
4000  /**
4001   *  Returns true if a p5.SoundFile is playing, false if not (i.e.
4002   *  paused or stopped).
4003   *
4004   *  @method isPlaying
4005   *  @for p5.SoundFile
4006   *  @return {Boolean}
4007   */
4008
4009
4010  p5.SoundFile.prototype.isPlaying = function () {
4011    return this._playing;
4012  };
4013  /**
4014   *  Returns true if a p5.SoundFile is paused, false if not (i.e.
4015   *  playing or stopped).
4016   *
4017   *  @method  isPaused
4018   *  @for p5.SoundFile
4019   *  @return {Boolean}
4020   */
4021
4022
4023  p5.SoundFile.prototype.isPaused = function () {
4024    return this._paused;
4025  };
4026  /**
4027   * Stop soundfile playback.
4028   *
4029   * @method stop
4030   * @for p5.SoundFile
4031   * @param {Number} [startTime] (optional) schedule event to occur
4032   *                             in seconds from now
4033   */
4034
4035
4036  p5.SoundFile.prototype.stop = function (timeFromNow) {
4037    var time = timeFromNow || 0;
4038
4039    if (this.mode === 'sustain' || this.mode === 'untildone') {
4040      this.stopAll(time);
4041      this._playing = false;
4042      this.pauseTime = 0;
4043      this._paused = false;
4044    } else if (this.buffer && this.bufferSourceNode) {
4045      var now = p5sound.audiocontext.currentTime;
4046      var t = time || 0;
4047      this.pauseTime = 0;
4048      this.bufferSourceNode.stop(now + t);
4049
4050      this._counterNode.stop(now + t);
4051
4052      this._playing = false;
4053      this._paused = false;
4054    }
4055  };
4056  /**
4057   *  Stop playback on all of this soundfile's sources.
4058   *  @private
4059   */
4060
4061
4062  p5.SoundFile.prototype.stopAll = function (_time) {
4063    var now = p5sound.audiocontext.currentTime;
4064    var time = _time || 0;
4065
4066    if (this.buffer && this.bufferSourceNode) {
4067      for (var i in this.bufferSourceNodes) {
4068        var bufferSourceNode = this.bufferSourceNodes[i];
4069
4070        if (!!bufferSourceNode) {
4071          try {
4072            bufferSourceNode.stop(now + time);
4073          } catch (e) {
4074          }
4075        }
4076      }
4077
4078      this._counterNode.stop(now + time);
4079
4080      this._onended(this);
4081    }
4082  };
4083  /**
4084   *  Multiply the output volume (amplitude) of a sound file
4085   *  between 0.0 (silence) and 1.0 (full volume).
4086   *  1.0 is the maximum amplitude of a digital sound, so multiplying
4087   *  by greater than 1.0 may cause digital distortion. To
4088   *  fade, provide a <code>rampTime</code> parameter. For more
4089   *  complex fades, see the Envelope class.
4090   *
4091   *  Alternately, you can pass in a signal source such as an
4092   *  oscillator to modulate the amplitude with an audio signal.
4093   *
4094   *  @method  setVolume
4095   *  @for p5.SoundFile
4096   *  @param {Number|Object} volume  Volume (amplitude) between 0.0
4097   *                                     and 1.0 or modulating signal/oscillator
4098   *  @param {Number} [rampTime]  Fade for t seconds
4099   *  @param {Number} [timeFromNow]  Schedule this event to happen at
4100   *                                 t seconds in the future
4101   */
4102
4103
4104  p5.SoundFile.prototype.setVolume = function (vol, _rampTime, _tFromNow) {
4105    if (typeof vol === 'number') {
4106      var rampTime = _rampTime || 0;
4107      var tFromNow = _tFromNow || 0;
4108      var now = p5sound.audiocontext.currentTime;
4109      var currentVol = this.output.gain.value;
4110      this.output.gain.cancelScheduledValues(now + tFromNow);
4111      this.output.gain.linearRampToValueAtTime(currentVol, now + tFromNow);
4112      this.output.gain.linearRampToValueAtTime(vol, now + tFromNow + rampTime);
4113    } else if (vol) {
4114      vol.connect(this.output.gain);
4115    } else {
4116      return this.output.gain;
4117    }
4118  }; 
4119
4120
4121  p5.SoundFile.prototype.amp = p5.SoundFile.prototype.setVolume; 
4122
4123  p5.SoundFile.prototype.fade = p5.SoundFile.prototype.setVolume;
4124
4125  p5.SoundFile.prototype.getVolume = function () {
4126    return this.output.gain.value;
4127  };
4128  /**
4129   * Set the stereo panning of a p5.sound object to
4130   * a floating point number between -1.0 (left) and 1.0 (right).
4131   * Default is 0.0 (center).
4132   *
4133   * @method pan
4134   * @for p5.SoundFile
4135   * @param {Number} [panValue]     Set the stereo panner
4136   * @param {Number} [timeFromNow]  schedule this event to happen
4137   *                                 seconds from now
4138   * @example
4139   * <div><code>
4140   *  let ballX = 0;
4141   *  let soundFile;
4142   *
4143   *  function preload() {
4144   *    soundFormats('ogg', 'mp3');
4145   *    soundFile = loadSound('assets/beatbox.mp3');
4146   *  }
4147   *
4148   *  function draw() {
4149   *    let cnv = createCanvas(100, 100);
4150   *    cnv.mousePressed(canvasPressed);
4151   *    background(220);
4152   *    ballX = constrain(mouseX, 0, width);
4153   *    ellipse(ballX, height/2, 20, 20);
4154   *  }
4155   *
4156   *  function canvasPressed(){
4157   *    // map the ball's x location to a panning degree
4158   *    // between -1.0 (left) and 1.0 (right)
4159   *    let panning = map(ballX, 0., width,-1.0, 1.0);
4160   *    soundFile.pan(panning);
4161   *    soundFile.play();
4162   *  }
4163   *  </div></code>
4164   */
4165
4166
4167  p5.SoundFile.prototype.pan = function (pval, tFromNow) {
4168    this.panPosition = pval;
4169    this.panner.pan(pval, tFromNow);
4170  };
4171  /**
4172   * Returns the current stereo pan position (-1.0 to 1.0)
4173   *
4174   * @method getPan
4175   * @for p5.SoundFile
4176   * @return {Number} Returns the stereo pan setting of the Oscillator
4177   *                          as a number between -1.0 (left) and 1.0 (right).
4178   *                          0.0 is center and default.
4179   */
4180
4181
4182  p5.SoundFile.prototype.getPan = function () {
4183    return this.panPosition;
4184  };
4185  /**
4186   *  Set the playback rate of a sound file. Will change the speed and the pitch.
4187   *  Values less than zero will reverse the audio buffer.
4188   *
4189   *  @method rate
4190   *  @for p5.SoundFile
4191   *  @param {Number} [playbackRate]     Set the playback rate. 1.0 is normal,
4192   *                                     .5 is half-speed, 2.0 is twice as fast.
4193   *                                     Values less than zero play backwards.
4194   *  @example
4195   *  <div><code>
4196   *  let mySound;
4197   *
4198   *  function preload() {
4199   *    mySound = loadSound('assets/Damscray_DancingTiger.mp3');
4200   *  }
4201   *
4202   *  function setup() {
4203   *    let cnv = createCanvas(100, 100);
4204   *    cnv.mousePressed(canvasPressed);
4205   *  }
4206   *  function canvasPressed() {
4207   *    mySound.loop();
4208   *  }
4209   *  function mouseReleased() {
4210   *    mySound.pause();
4211   *  }
4212   *  function draw() {
4213   *    background(220);
4214   *
4215   *    // Set the rate to a range between 0.1 and 4
4216   *    // Changing the rate also alters the pitch
4217   *    let playbackRate = map(mouseY, 0.1, height, 2, 0);
4218   *    playbackRate = constrain(playbackRate, 0.01, 4);
4219   *    mySound.rate(playbackRate);
4220   *
4221   *    line(0, mouseY, width, mouseY);
4222   *    text('rate: ' + round(playbackRate * 100) + '%', 10, 20);
4223   *  }
4224   *
4225   * </code>
4226   * </div>
4227   *
4228   */
4229
4230
4231  p5.SoundFile.prototype.rate = function (playbackRate) {
4232    var reverse = false;
4233
4234    if (typeof playbackRate === 'undefined') {
4235      return this.playbackRate;
4236    }
4237
4238    this.playbackRate = playbackRate;
4239
4240    if (playbackRate === 0) {
4241      playbackRate = 0.0000000000001;
4242    } else if (playbackRate < 0 && !this.reversed) {
4243      playbackRate = Math.abs(playbackRate);
4244      reverse = true;
4245    } else if (playbackRate > 0 && this.reversed) {
4246      reverse = true;
4247    }
4248
4249    if (this.bufferSourceNode) {
4250      var now = p5sound.audiocontext.currentTime;
4251      this.bufferSourceNode.playbackRate.cancelScheduledValues(now);
4252      this.bufferSourceNode.playbackRate.linearRampToValueAtTime(Math.abs(playbackRate), now);
4253
4254      this._counterNode.playbackRate.cancelScheduledValues(now);
4255
4256      this._counterNode.playbackRate.linearRampToValueAtTime(Math.abs(playbackRate), now);
4257    }
4258
4259    if (reverse) {
4260      this.reverseBuffer();
4261    }
4262
4263    return this.playbackRate;
4264  }; 
4265
4266
4267  p5.SoundFile.prototype.setPitch = function (num) {
4268    var newPlaybackRate = midiToFreq(num) / midiToFreq(60);
4269    this.rate(newPlaybackRate);
4270  };
4271
4272  p5.SoundFile.prototype.getPlaybackRate = function () {
4273    return this.playbackRate;
4274  };
4275  /**
4276   * Returns the duration of a sound file in seconds.
4277   *
4278   * @method duration
4279   * @for p5.SoundFile
4280   * @return {Number} The duration of the soundFile in seconds.
4281   */
4282
4283
4284  p5.SoundFile.prototype.duration = function () {
4285    if (this.buffer) {
4286      return this.buffer.duration;
4287    } else {
4288      return 0;
4289    }
4290  };
4291  /**
4292   * Return the current position of the p5.SoundFile playhead, in seconds.
4293   * Time is relative to the normal buffer direction, so if `reverseBuffer`
4294   * has been called, currentTime will count backwards.
4295   *
4296   * @method currentTime
4297   * @for p5.SoundFile
4298   * @return {Number}   currentTime of the soundFile in seconds.
4299   */
4300
4301
4302  p5.SoundFile.prototype.currentTime = function () {
4303    return this.reversed ? Math.abs(this._lastPos - this.buffer.length) / ac.sampleRate : this._lastPos / ac.sampleRate;
4304  };
4305  /**
4306   * Move the playhead of a soundfile that is currently playing to a
4307   * new position and a new duration, in seconds.
4308   * If none are given, will reset the file to play entire duration
4309   * from start to finish. To set the position of a soundfile that is
4310   * not currently playing, use the `play` or `loop` methods.
4311   *
4312   * @method jump
4313   * @for p5.SoundFile
4314   * @param {Number} cueTime    cueTime of the soundFile in seconds.
4315   * @param {Number} duration    duration in seconds.
4316   */
4317
4318
4319  p5.SoundFile.prototype.jump = function (cueTime, duration) {
4320    if (cueTime < 0 || cueTime > this.buffer.duration) {
4321      throw 'jump time out of range';
4322    }
4323
4324    if (duration > this.buffer.duration - cueTime) {
4325      throw 'end time out of range';
4326    }
4327
4328    var cTime = cueTime || 0;
4329    var dur = duration || undefined;
4330
4331    if (this.isPlaying()) {
4332      this.stop(0);
4333      this.play(0, this.playbackRate, this.output.gain.value, cTime, dur);
4334    }
4335  };
4336  /**
4337    * Return the number of channels in a sound file.
4338    * For example, Mono = 1, Stereo = 2.
4339    *
4340    * @method channels
4341    * @for p5.SoundFile
4342    * @return {Number} [channels]
4343    */
4344
4345
4346  p5.SoundFile.prototype.channels = function () {
4347    return this.buffer.numberOfChannels;
4348  };
4349  /**
4350    * Return the sample rate of the sound file.
4351    *
4352    * @method sampleRate
4353    * @for p5.SoundFile
4354    * @return {Number} [sampleRate]
4355    */
4356
4357
4358  p5.SoundFile.prototype.sampleRate = function () {
4359    return this.buffer.sampleRate;
4360  };
4361  /**
4362    * Return the number of samples in a sound file.
4363    * Equal to sampleRate * duration.
4364    *
4365    * @method frames
4366    * @for p5.SoundFile
4367    * @return {Number} [sampleCount]
4368    */
4369
4370
4371  p5.SoundFile.prototype.frames = function () {
4372    return this.buffer.length;
4373  };
4374  /**
4375   * Returns an array of amplitude peaks in a p5.SoundFile that can be
4376   * used to draw a static waveform. Scans through the p5.SoundFile's
4377   * audio buffer to find the greatest amplitudes. Accepts one
4378   * parameter, 'length', which determines size of the array.
4379   * Larger arrays result in more precise waveform visualizations.
4380   *
4381   * Inspired by Wavesurfer.js.
4382   *
4383   * @method  getPeaks
4384   * @for p5.SoundFile
4385   * @params {Number} [length] length is the size of the returned array.
4386   *                          Larger length results in more precision.
4387   *                          Defaults to 5*width of the browser window.
4388   * @returns {Float32Array} Array of peaks.
4389   */
4390
4391
4392  p5.SoundFile.prototype.getPeaks = function (length) {
4393    if (this.buffer) {
4394      if (!length) {
4395        length = window.width * 5;
4396      }
4397
4398      if (this.buffer) {
4399        var buffer = this.buffer;
4400        var sampleSize = buffer.length / length;
4401        var sampleStep = ~~(sampleSize / 10) || 1;
4402        var channels = buffer.numberOfChannels;
4403        var peaks = new Float32Array(Math.round(length));
4404
4405        for (var c = 0; c < channels; c++) {
4406          var chan = buffer.getChannelData(c);
4407
4408          for (var i = 0; i < length; i++) {
4409            var start = ~~(i * sampleSize);
4410            var end = ~~(start + sampleSize);
4411            var max = 0;
4412
4413            for (var j = start; j < end; j += sampleStep) {
4414              var value = chan[j];
4415
4416              if (value > max) {
4417                max = value; 
4418              } else if (-value > max) {
4419                max = value;
4420              }
4421            }
4422
4423            if (c === 0 || Math.abs(max) > peaks[i]) {
4424              peaks[i] = max;
4425            }
4426          }
4427        }
4428
4429        return peaks;
4430      }
4431    } else {
4432      throw 'Cannot load peaks yet, buffer is not loaded';
4433    }
4434  };
4435  /**
4436   *  Reverses the p5.SoundFile's buffer source.
4437   *  Playback must be handled separately (see example).
4438   *
4439   *  @method  reverseBuffer
4440   *  @for p5.SoundFile
4441   *  @example
4442   *  <div><code>
4443   *  let drum;
4444   *  function preload() {
4445   *    drum = loadSound('assets/drum.mp3');
4446   *  }
4447   *
4448   *  function setup() {
4449   *    let cnv = createCanvas(100, 100);
4450   *    cnv.mousePressed(canvasPressed);
4451   *    background(220);
4452   *    text('tap to play', 20, 20);
4453   *  }
4454   *
4455   *  function canvasPressed() {
4456   *    drum.stop();
4457   *    drum.reverseBuffer();
4458   *    drum.play();
4459   *  }
4460   * </code>
4461   * </div>
4462   */
4463
4464
4465  p5.SoundFile.prototype.reverseBuffer = function () {
4466    if (this.buffer) {
4467      var currentPos = this._lastPos / ac.sampleRate;
4468      var curVol = this.getVolume();
4469      this.setVolume(0, 0.001);
4470      var numChannels = this.buffer.numberOfChannels;
4471
4472      for (var i = 0; i < numChannels; i++) {
4473        this.buffer.getChannelData(i).reverse();
4474      } 
4475
4476
4477      this.reversed = !this.reversed;
4478
4479      if (this.isPlaying() && currentPos) {
4480        this.jump(this.duration() - currentPos);
4481      }
4482
4483      this.setVolume(curVol, 0.001);
4484    } else {
4485      throw 'SoundFile is not done loading';
4486    }
4487  };
4488  /**
4489   *  Schedule an event to be called when the soundfile
4490   *  reaches the end of a buffer. If the soundfile is
4491   *  playing through once, this will be called when it
4492   *  ends. If it is looping, it will be called when
4493   *  stop is called.
4494   *
4495   *  @method  onended
4496   *  @for p5.SoundFile
4497   *  @param  {Function} callback function to call when the
4498   *                              soundfile has ended.
4499   */
4500
4501
4502  p5.SoundFile.prototype.onended = function (callback) {
4503    this._onended = callback;
4504    return this;
4505  };
4506
4507  p5.SoundFile.prototype.add = function () {
4508  };
4509
4510  p5.SoundFile.prototype.dispose = function () {
4511    var now = p5sound.audiocontext.currentTime; 
4512
4513    var index = p5sound.soundArray.indexOf(this);
4514    p5sound.soundArray.splice(index, 1);
4515    this.stop(now);
4516
4517    if (this.buffer && this.bufferSourceNode) {
4518      for (var i = 0; i < this.bufferSourceNodes.length - 1; i++) {
4519        if (this.bufferSourceNodes[i] !== null) {
4520          this.bufferSourceNodes[i].disconnect();
4521
4522          try {
4523            this.bufferSourceNodes[i].stop(now);
4524          } catch (e) {
4525            console.warn('no buffer source node to dispose');
4526          }
4527
4528          this.bufferSourceNodes[i] = null;
4529        }
4530      }
4531
4532      if (this.isPlaying()) {
4533        try {
4534          this._counterNode.stop(now);
4535        } catch (e) {
4536          console.log(e);
4537        }
4538
4539        this._counterNode = null;
4540      }
4541    }
4542
4543    if (this.output) {
4544      this.output.disconnect();
4545      this.output = null;
4546    }
4547
4548    if (this.panner) {
4549      this.panner.disconnect();
4550      this.panner = null;
4551    }
4552  };
4553  /**
4554   * Connects the output of a p5sound object to input of another
4555   * p5.sound object. For example, you may connect a p5.SoundFile to an
4556   * FFT or an Effect. If no parameter is given, it will connect to
4557   * the master output. Most p5sound objects connect to the master
4558   * output when they are created.
4559   *
4560   * @method connect
4561   * @for p5.SoundFile
4562   * @param {Object} [object] Audio object that accepts an input
4563   */
4564
4565
4566  p5.SoundFile.prototype.connect = function (unit) {
4567    if (!unit) {
4568      this.panner.connect(p5sound.input);
4569    } else {
4570      if (unit.hasOwnProperty('input')) {
4571        this.panner.connect(unit.input);
4572      } else {
4573        this.panner.connect(unit);
4574      }
4575    }
4576  };
4577  /**
4578   * Disconnects the output of this p5sound object.
4579   *
4580   * @method disconnect
4581   * @for p5.SoundFile
4582   */
4583
4584
4585  p5.SoundFile.prototype.disconnect = function () {
4586    if (this.panner) {
4587      this.panner.disconnect();
4588    }
4589  };
4590  /**
4591   */
4592
4593
4594  p5.SoundFile.prototype.getLevel = function () {
4595    console.warn('p5.SoundFile.getLevel has been removed from the library. Use p5.Amplitude instead');
4596  };
4597  /**
4598   *  Reset the source for this SoundFile to a
4599   *  new path (URL).
4600   *
4601   *  @method  setPath
4602   *  @for p5.SoundFile
4603   *  @param {String}   path     path to audio file
4604   *  @param {Function} callback Callback
4605   */
4606
4607
4608  p5.SoundFile.prototype.setPath = function (p, callback) {
4609    var path = p5.prototype._checkFileFormats(p);
4610
4611    this.url = path;
4612    this.load(callback);
4613  };
4614  /**
4615   *  Replace the current Audio Buffer with a new Buffer.
4616   *
4617   *  @method setBuffer
4618   *  @for p5.SoundFile
4619   *  @param {Array} buf Array of Float32 Array(s). 2 Float32 Arrays
4620   *                     will create a stereo source. 1 will create
4621   *                     a mono source.
4622   */
4623
4624
4625  p5.SoundFile.prototype.setBuffer = function (buf) {
4626    var numChannels = buf.length;
4627    var size = buf[0].length;
4628    var newBuffer = ac.createBuffer(numChannels, size, ac.sampleRate);
4629
4630    if (!(buf[0] instanceof Float32Array)) {
4631      buf[0] = new Float32Array(buf[0]);
4632    }
4633
4634    for (var channelNum = 0; channelNum < numChannels; channelNum++) {
4635      var channel = newBuffer.getChannelData(channelNum);
4636      channel.set(buf[channelNum]);
4637    }
4638
4639    this.buffer = newBuffer; 
4640
4641    this.panner.inputChannels(numChannels);
4642  }; 
4643
4644
4645  var _createCounterBuffer = function _createCounterBuffer(buffer) {
4646    var len = buffer.length;
4647    var audioBuf = ac.createBuffer(1, buffer.length, ac.sampleRate);
4648    var arrayBuffer = audioBuf.getChannelData(0);
4649
4650    for (var index = 0; index < len; index++) {
4651      arrayBuffer[index] = index;
4652    }
4653
4654    return audioBuf;
4655  }; 
4656
4657
4658  p5.SoundFile.prototype._initCounterNode = function () {
4659    var _this = this;
4660
4661    var self = this;
4662    var now = ac.currentTime;
4663    var cNode = ac.createBufferSource();
4664    var workletBufferSize = safeBufferSize(256); 
4665
4666    if (self._workletNode) {
4667      self._workletNode.disconnect();
4668
4669      delete self._workletNode;
4670    }
4671
4672    self._workletNode = new AudioWorkletNode(ac, processorNames.soundFileProcessor, {
4673      processorOptions: {
4674        bufferSize: workletBufferSize
4675      }
4676    });
4677
4678    self._workletNode.port.onmessage = function (event) {
4679      if (event.data.name === 'position') {
4680        if (event.data.position === 0) {
4681          return;
4682        }
4683
4684        _this._lastPos = event.data.position; 
4685
4686        _this._onTimeUpdate(self._lastPos);
4687      }
4688    }; 
4689
4690
4691    cNode.buffer = _createCounterBuffer(self.buffer);
4692    cNode.playbackRate.setValueAtTime(self.playbackRate, now);
4693    cNode.connect(self._workletNode);
4694
4695    self._workletNode.connect(p5.soundOut._silentNode);
4696
4697    return cNode;
4698  }; 
4699
4700
4701  p5.SoundFile.prototype._initSourceNode = function () {
4702    var bufferSourceNode = ac.createBufferSource();
4703    bufferSourceNode.buffer = this.buffer;
4704    bufferSourceNode.playbackRate.value = this.playbackRate;
4705    bufferSourceNode.connect(this.output);
4706    return bufferSourceNode;
4707  };
4708  /**
4709   *  processPeaks returns an array of timestamps where it thinks there is a beat.
4710   *
4711   *  This is an asynchronous function that processes the soundfile in an offline audio context,
4712   *  and sends the results to your callback function.
4713   *
4714   *  The process involves running the soundfile through a lowpass filter, and finding all of the
4715   *  peaks above the initial threshold. If the total number of peaks are below the minimum number of peaks,
4716   *  it decreases the threshold and re-runs the analysis until either minPeaks or minThreshold are reached.
4717   *
4718   *  @method  processPeaks
4719   *  @for p5.SoundFile
4720   *  @param  {Function} callback       a function to call once this data is returned
4721   *  @param  {Number}   [initThreshold] initial threshold defaults to 0.9
4722   *  @param  {Number}   [minThreshold]   minimum threshold defaults to 0.22
4723   *  @param  {Number}   [minPeaks]       minimum number of peaks defaults to 200
4724   *  @return {Array}                  Array of timestamped peaks
4725   */
4726
4727
4728  p5.SoundFile.prototype.processPeaks = function (callback, _initThreshold, _minThreshold, _minPeaks) {
4729    var bufLen = this.buffer.length;
4730    var sampleRate = this.buffer.sampleRate;
4731    var buffer = this.buffer;
4732    var allPeaks = [];
4733    var initialThreshold = _initThreshold || 0.9,
4734        threshold = initialThreshold,
4735        minThreshold = _minThreshold || 0.22,
4736        minPeaks = _minPeaks || 200; 
4737
4738    var offlineContext = new window.OfflineAudioContext(1, bufLen, sampleRate); 
4739
4740    var source = offlineContext.createBufferSource();
4741    source.buffer = buffer; 
4742
4743    var filter = offlineContext.createBiquadFilter();
4744    filter.type = 'lowpass';
4745    source.connect(filter);
4746    filter.connect(offlineContext.destination); 
4747
4748    source.start(0);
4749    offlineContext.startRendering(); 
4750
4751    offlineContext.oncomplete = function (e) {
4752      if (!self.panner) return;
4753      var filteredBuffer = e.renderedBuffer;
4754      var bufferData = filteredBuffer.getChannelData(0); 
4755
4756      do {
4757        allPeaks = getPeaksAtThreshold(bufferData, threshold);
4758        threshold -= 0.005;
4759      } while (Object.keys(allPeaks).length < minPeaks && threshold >= minThreshold); 
4760
4761
4762      var intervalCounts = countIntervalsBetweenNearbyPeaks(allPeaks); 
4763
4764      var groups = groupNeighborsByTempo(intervalCounts, filteredBuffer.sampleRate); 
4765
4766      var topTempos = groups.sort(function (intA, intB) {
4767        return intB.count - intA.count;
4768      }).splice(0, 5); 
4769
4770      this.tempo = topTempos[0].tempo; 
4771
4772      var bpmVariance = 5;
4773      var tempoPeaks = getPeaksAtTopTempo(allPeaks, topTempos[0].tempo, filteredBuffer.sampleRate, bpmVariance);
4774      callback(tempoPeaks);
4775    };
4776  }; 
4777
4778
4779  var Peak = function Peak(amp, i) {
4780    this.sampleIndex = i;
4781    this.amplitude = amp;
4782    this.tempos = [];
4783    this.intervals = [];
4784  }; 
4785
4786
4787  function getPeaksAtThreshold(data, threshold) {
4788    var peaksObj = {};
4789    var length = data.length;
4790
4791    for (var i = 0; i < length; i++) {
4792      if (data[i] > threshold) {
4793        var amp = data[i];
4794        var peak = new Peak(amp, i);
4795        peaksObj[i] = peak; 
4796
4797        i += 6000;
4798      }
4799
4800      i++;
4801    }
4802
4803    return peaksObj;
4804  } 
4805
4806
4807  function countIntervalsBetweenNearbyPeaks(peaksObj) {
4808    var intervalCounts = [];
4809    var peaksArray = Object.keys(peaksObj).sort();
4810
4811    for (var index = 0; index < peaksArray.length; index++) {
4812      for (var i = 0; i < 10; i++) {
4813        var startPeak = peaksObj[peaksArray[index]];
4814        var endPeak = peaksObj[peaksArray[index + i]];
4815
4816        if (startPeak && endPeak) {
4817          var startPos = startPeak.sampleIndex;
4818          var endPos = endPeak.sampleIndex;
4819          var interval = endPos - startPos; 
4820
4821          if (interval > 0) {
4822            startPeak.intervals.push(interval);
4823          } 
4824
4825
4826          var foundInterval = intervalCounts.some(function (intervalCount) {
4827            if (intervalCount.interval === interval) {
4828              intervalCount.count++;
4829              return intervalCount;
4830            }
4831          }); 
4832
4833          if (!foundInterval) {
4834            intervalCounts.push({
4835              interval: interval,
4836              count: 1
4837            });
4838          }
4839        }
4840      }
4841    }
4842
4843    return intervalCounts;
4844  } 
4845
4846
4847  function groupNeighborsByTempo(intervalCounts, sampleRate) {
4848    var tempoCounts = [];
4849    intervalCounts.forEach(function (intervalCount) {
4850      try {
4851        var theoreticalTempo = Math.abs(60 / (intervalCount.interval / sampleRate));
4852        theoreticalTempo = mapTempo(theoreticalTempo);
4853        var foundTempo = tempoCounts.some(function (tempoCount) {
4854          if (tempoCount.tempo === theoreticalTempo) return tempoCount.count += intervalCount.count;
4855        });
4856
4857        if (!foundTempo) {
4858          if (isNaN(theoreticalTempo)) {
4859            return;
4860          }
4861
4862          tempoCounts.push({
4863            tempo: Math.round(theoreticalTempo),
4864            count: intervalCount.count
4865          });
4866        }
4867      } catch (e) {
4868        throw e;
4869      }
4870    });
4871    return tempoCounts;
4872  } 
4873
4874
4875  function getPeaksAtTopTempo(peaksObj, tempo, sampleRate, bpmVariance) {
4876    var peaksAtTopTempo = [];
4877    var peaksArray = Object.keys(peaksObj).sort(); 
4878
4879    for (var i = 0; i < peaksArray.length; i++) {
4880      var key = peaksArray[i];
4881      var peak = peaksObj[key];
4882
4883      for (var j = 0; j < peak.intervals.length; j++) {
4884        var intervalBPM = Math.round(Math.abs(60 / (peak.intervals[j] / sampleRate)));
4885        intervalBPM = mapTempo(intervalBPM);
4886
4887        if (Math.abs(intervalBPM - tempo) < bpmVariance) {
4888          peaksAtTopTempo.push(peak.sampleIndex / sampleRate);
4889        }
4890      }
4891    } 
4892
4893
4894    peaksAtTopTempo = peaksAtTopTempo.filter(function (peakTime, index, arr) {
4895      var dif = arr[index + 1] - peakTime;
4896
4897      if (dif > 0.01) {
4898        return true;
4899      }
4900    });
4901    return peaksAtTopTempo;
4902  } 
4903
4904
4905  function mapTempo(theoreticalTempo) {
4906    if (!isFinite(theoreticalTempo) || theoreticalTempo === 0) {
4907      return;
4908    } 
4909
4910
4911    while (theoreticalTempo < 90) {
4912      theoreticalTempo *= 2;
4913    }
4914
4915    while (theoreticalTempo > 180 && theoreticalTempo > 90) {
4916      theoreticalTempo /= 2;
4917    }
4918
4919    return theoreticalTempo;
4920  }
4921
4922
4923  var Cue = function Cue(callback, time, id, val) {
4924    this.callback = callback;
4925    this.time = time;
4926    this.id = id;
4927    this.val = val;
4928  };
4929  /**
4930   *  Schedule events to trigger every time a MediaElement
4931   *  (audio/video) reaches a playback cue point.
4932   *
4933   *  Accepts a callback function, a time (in seconds) at which to trigger
4934   *  the callback, and an optional parameter for the callback.
4935   *
4936   *  Time will be passed as the first parameter to the callback function,
4937   *  and param will be the second parameter.
4938   *
4939   *
4940   *  @method  addCue
4941   *  @for p5.SoundFile
4942   *  @param {Number}   time     Time in seconds, relative to this media
4943   *                             element's playback. For example, to trigger
4944   *                             an event every time playback reaches two
4945   *                             seconds, pass in the number 2. This will be
4946   *                             passed as the first parameter to
4947   *                             the callback function.
4948   *  @param {Function} callback Name of a function that will be
4949   *                             called at the given time. The callback will
4950   *                             receive time and (optionally) param as its
4951   *                             two parameters.
4952   *  @param {Object} [value]    An object to be passed as the
4953   *                             second parameter to the
4954   *                             callback function.
4955   *  @return {Number} id ID of this cue,
4956   *                      useful for removeCue(id)
4957   *  @example
4958   *  <div><code>
4959   *  let mySound;
4960   *  function preload() {
4961   *    mySound = loadSound('assets/Damscray_DancingTiger.mp3');
4962   *  }
4963   *
4964   *  function setup() {
4965   *    let cnv = createCanvas(100, 100);
4966   *    cnv.mousePressed(canvasPressed);
4967   *    background(220);
4968   *    text('tap to play', 10, 20);
4969   *
4970   *    // schedule calls to changeText
4971   *    mySound.addCue(0, changeText, "hello" );
4972   *    mySound.addCue(0.5, changeText, "hello," );
4973   *    mySound.addCue(1, changeText, "hello, p5!");
4974   *    mySound.addCue(1.5, changeText, "hello, p5!!");
4975   *    mySound.addCue(2, changeText, "hello, p5!!!!!");
4976   *  }
4977   *
4978   *  function changeText(val) {
4979   *    background(220);
4980   *    text(val, 10, 20);
4981   *  }
4982   *
4983   *  function canvasPressed() {
4984   *    mySound.play();
4985   *  }
4986   *  </code></div>
4987   */
4988
4989
4990  p5.SoundFile.prototype.addCue = function (time, callback, val) {
4991    var id = this._cueIDCounter++;
4992    var cue = new Cue(callback, time, id, val);
4993
4994    this._cues.push(cue); 
4995
4996
4997    return id;
4998  };
4999  /**
5000   *  Remove a callback based on its ID. The ID is returned by the
5001   *  addCue method.
5002   *
5003   *  @method removeCue
5004   *  @for p5.SoundFile
5005   *  @param  {Number} id ID of the cue, as returned by addCue
5006   */
5007
5008
5009  p5.SoundFile.prototype.removeCue = function (id) {
5010    var cueLength = this._cues.length;
5011
5012    for (var i = 0; i < cueLength; i++) {
5013      var cue = this._cues[i];
5014
5015      if (cue.id === id) {
5016        this._cues.splice(i, 1);
5017
5018        break;
5019      }
5020    }
5021
5022    if (this._cues.length === 0) {
5023    }
5024  };
5025  /**
5026   *  Remove all of the callbacks that had originally been scheduled
5027   *  via the addCue method.
5028   *
5029   *  @method  clearCues
5030   */
5031
5032
5033  p5.SoundFile.prototype.clearCues = function () {
5034    this._cues = []; 
5035  }; 
5036
5037
5038  p5.SoundFile.prototype._onTimeUpdate = function (position) {
5039    var playbackTime = position / this.buffer.sampleRate;
5040    var cueLength = this._cues.length;
5041
5042    for (var i = 0; i < cueLength; i++) {
5043      var cue = this._cues[i];
5044      var callbackTime = cue.time;
5045      var val = cue.val;
5046
5047      if (~~this._prevUpdateTime <= callbackTime && callbackTime <= playbackTime) {
5048        cue.callback(val);
5049      }
5050    }
5051
5052    this._prevUpdateTime = playbackTime;
5053  };
5054  /**
5055   * Save a p5.SoundFile as a .wav file. The browser will prompt the user
5056   * to download the file to their device. To upload a file to a server, see
5057   * <a href="/docs/reference/#/p5.SoundFile/getBlob">getBlob</a>
5058   *
5059   * @method save
5060   * @for p5.SoundFile
5061   * @param  {String} [fileName]      name of the resulting .wav file.
5062   * @example
5063   *  <div><code>
5064   *  let mySound;
5065   *  function preload() {
5066   *    mySound = loadSound('assets/doorbell.mp3');
5067   *  }
5068   *  function setup() {
5069   *    let cnv = createCanvas(100, 100);
5070   *    cnv.mousePressed(canvasPressed);
5071   *    background(220);
5072   *    text('tap to download', 10, 20);
5073   *  }
5074   *
5075   *  function canvasPressed() {
5076   *    mySound.save('my cool filename');
5077   *  }
5078   * </code></div>
5079   */
5080
5081
5082  p5.SoundFile.prototype.save = function (fileName) {
5083    p5.prototype.saveSound(this, fileName, 'wav');
5084  };
5085  /**
5086   * This method is useful for sending a SoundFile to a server. It returns the
5087   * .wav-encoded audio data as a "<a target="_blank" title="Blob reference at
5088   * MDN" href="https://developer.mozilla.org/en-US/docs/Web/API/Blob">Blob</a>".
5089   * A Blob is a file-like data object that can be uploaded to a server
5090   * with an <a href="/docs/reference/#/p5/httpDo">http</a> request. We'll
5091   * use the `httpDo` options object to send a POST request with some
5092   * specific options: we encode the request as `multipart/form-data`,
5093   * and attach the blob as one of the form values using `FormData`.
5094   *
5095   *
5096   * @method getBlob
5097   * @for p5.SoundFile
5098   * @returns {Blob} A file-like data object
5099   * @example
5100   *  <div><code>
5101   *  function preload() {
5102   *    mySound = loadSound('assets/doorbell.mp3');
5103   *  }
5104   *
5105   *  function setup() {
5106   *    noCanvas();
5107   *    let soundBlob = mySound.getBlob();
5108   *
5109   *    // Now we can send the blob to a server...
5110   *    let serverUrl = 'https://jsonplaceholder.typicode.com/posts';
5111   *    let httpRequestOptions = {
5112   *      method: 'POST',
5113   *      body: new FormData().append('soundBlob', soundBlob),
5114   *      headers: new Headers({
5115   *        'Content-Type': 'multipart/form-data'
5116   *      })
5117   *    };
5118   *    httpDo(serverUrl, httpRequestOptions);
5119   *
5120   *    // We can also create an `ObjectURL` pointing to the Blob
5121   *    let blobUrl = URL.createObjectURL(soundBlob);
5122   *
5123   *    // The `<Audio>` Element accepts Object URL's
5124   *    createAudio(blobUrl).showControls();
5125   *
5126   *    createDiv();
5127   *
5128   *    // The ObjectURL exists as long as this tab is open
5129   *    let input = createInput(blobUrl);
5130   *    input.attribute('readonly', true);
5131   *    input.mouseClicked(function() { input.elt.select() });
5132   *  }
5133   *
5134   * </code></div>
5135   */
5136
5137
5138  p5.SoundFile.prototype.getBlob = function () {
5139    var dataView = convertToWav(this.buffer);
5140    return new Blob([dataView], {
5141      type: 'audio/wav'
5142    });
5143  }; 
5144
5145
5146  function _clearOnEnd(e) {
5147    var thisBufferSourceNode = e.target;
5148    var soundFile = this; 
5149
5150    thisBufferSourceNode._playing = false;
5151    thisBufferSourceNode.removeEventListener('ended', soundFile._clearOnEnd); 
5152
5153    soundFile._onended(soundFile); 
5154
5155
5156    soundFile.bufferSourceNodes.map(function (_, i) {
5157      return i;
5158    }).reverse().forEach(function (i) {
5159      var n = soundFile.bufferSourceNodes[i];
5160
5161      if (n._playing === false) {
5162        soundFile.bufferSourceNodes.splice(i, 1);
5163      }
5164    });
5165
5166    if (soundFile.bufferSourceNodes.length === 0) {
5167      soundFile._playing = false;
5168    }
5169  }
5170}).call(exports, __webpack_require__, exports, module),
5171				__WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));
5172
5173 }),
5174 (function(module, exports, __webpack_require__) {
5175
5176"use strict";
5177var __WEBPACK_AMD_DEFINE_RESULT__;
5178
5179!(__WEBPACK_AMD_DEFINE_RESULT__ = (function (require) {
5180  var p5sound = __webpack_require__(1);
5181
5182  var _require = __webpack_require__(6),
5183      safeBufferSize = _require.safeBufferSize;
5184
5185  var processorNames = __webpack_require__(10);
5186  /**
5187   *  Amplitude measures volume between 0.0 and 1.0.
5188   *  Listens to all p5sound by default, or use setInput()
5189   *  to listen to a specific sound source. Accepts an optional
5190   *  smoothing value, which defaults to 0.
5191   *
5192   *  @class p5.Amplitude
5193   *  @constructor
5194   *  @param {Number} [smoothing] between 0.0 and .999 to smooth
5195   *                             amplitude readings (defaults to 0)
5196   *  @example
5197   *  <div><code>
5198   *  let sound, amplitude;
5199   *
5200   *  function preload(){
5201   *    sound = loadSound('assets/beat.mp3');
5202   *  }
5203   *  function setup() {
5204   *    let cnv = createCanvas(100,100);
5205   *    cnv.mouseClicked(toggleSound);
5206   *    amplitude = new p5.Amplitude();
5207   *  }
5208   *
5209   *  function draw() {
5210   *    background(220);
5211   *    text('tap to play', 20, 20);
5212   *
5213   *    let level = amplitude.getLevel();
5214   *    let size = map(level, 0, 1, 0, 200);
5215   *    ellipse(width/2, height/2, size, size);
5216   *  }
5217   *
5218   *  function toggleSound() {
5219   *    if (sound.isPlaying() ){
5220   *      sound.stop();
5221   *    } else {
5222   *      sound.play();
5223   *    }
5224   *  }
5225   *
5226   *  </code></div>
5227   */
5228
5229
5230  p5.Amplitude = function (smoothing) {
5231    this.bufferSize = safeBufferSize(2048); 
5232
5233    this.audiocontext = p5sound.audiocontext;
5234    this._workletNode = new AudioWorkletNode(this.audiocontext, processorNames.amplitudeProcessor, {
5235      outputChannelCount: [1],
5236      parameterData: {
5237        smoothing: smoothing || 0
5238      },
5239      processorOptions: {
5240        normalize: false,
5241        smoothing: smoothing || 0,
5242        numInputChannels: 2,
5243        bufferSize: this.bufferSize
5244      }
5245    });
5246
5247    this._workletNode.port.onmessage = function (event) {
5248      if (event.data.name === 'amplitude') {
5249        this.volume = event.data.volume;
5250        this.volNorm = event.data.volNorm;
5251        this.stereoVol = event.data.stereoVol;
5252        this.stereoVolNorm = event.data.stereoVolNorm;
5253      }
5254    }.bind(this); 
5255
5256
5257    this.input = this._workletNode;
5258    this.output = this.audiocontext.createGain(); 
5259
5260    this.volume = 0;
5261    this.volNorm = 0;
5262    this.stereoVol = [0, 0];
5263    this.stereoVolNorm = [0, 0];
5264    this.normalize = false;
5265
5266    this._workletNode.connect(this.output);
5267
5268    this.output.gain.value = 0; 
5269
5270    this.output.connect(this.audiocontext.destination); 
5271
5272    p5sound.meter.connect(this._workletNode); 
5273
5274    p5sound.soundArray.push(this);
5275  };
5276  /**
5277   *  Connects to the p5sound instance (master output) by default.
5278   *  Optionally, you can pass in a specific source (i.e. a soundfile).
5279   *
5280   *  @method setInput
5281   *  @for p5.Amplitude
5282   *  @param {soundObject|undefined} [snd] set the sound source
5283   *                                       (optional, defaults to
5284   *                                       master output)
5285   *  @param {Number|undefined} [smoothing] a range between 0.0 and 1.0
5286   *                                        to smooth amplitude readings
5287   *  @example
5288   *  <div><code>
5289   *  function preload(){
5290   *    sound1 = loadSound('assets/beat.mp3');
5291   *    sound2 = loadSound('assets/drum.mp3');
5292   *  }
5293   *  function setup(){
5294   *    cnv = createCanvas(100, 100);
5295   *    cnv.mouseClicked(toggleSound);
5296   *
5297   *    amplitude = new p5.Amplitude();
5298   *    amplitude.setInput(sound2);
5299   *  }
5300   *
5301   *  function draw() {
5302   *    background(220);
5303   *    text('tap to play', 20, 20);
5304   *
5305   *    let level = amplitude.getLevel();
5306   *    let size = map(level, 0, 1, 0, 200);
5307   *    ellipse(width/2, height/2, size, size);
5308   *  }
5309   *
5310   *  function toggleSound(){
5311   *    if (sound1.isPlaying() && sound2.isPlaying()) {
5312   *      sound1.stop();
5313   *      sound2.stop();
5314   *    } else {
5315   *      sound1.play();
5316   *      sound2.play();
5317   *    }
5318   *  }
5319   *  </code></div>
5320   */
5321
5322
5323  p5.Amplitude.prototype.setInput = function (source, smoothing) {
5324    p5sound.meter.disconnect();
5325
5326    if (smoothing) {
5327      this._workletNode.parameters.get('smoothing').value = smoothing;
5328    } 
5329
5330
5331    if (source == null) {
5332      console.log('Amplitude input source is not ready! Connecting to master output instead');
5333      p5sound.meter.connect(this._workletNode);
5334    } 
5335    else if (source instanceof p5.Signal) {
5336        source.output.connect(this._workletNode);
5337      } 
5338      else if (source) {
5339          source.connect(this._workletNode);
5340
5341          this._workletNode.disconnect();
5342
5343          this._workletNode.connect(this.output);
5344        } 
5345        else {
5346            p5sound.meter.connect(this._workletNode);
5347          }
5348  };
5349
5350  p5.Amplitude.prototype.connect = function (unit) {
5351    if (unit) {
5352      if (unit.hasOwnProperty('input')) {
5353        this.output.connect(unit.input);
5354      } else {
5355        this.output.connect(unit);
5356      }
5357    } else {
5358      this.output.connect(this.panner.connect(p5sound.input));
5359    }
5360  };
5361
5362  p5.Amplitude.prototype.disconnect = function () {
5363    if (this.output) {
5364      this.output.disconnect();
5365    }
5366  };
5367  /**
5368   *  Returns a single Amplitude reading at the moment it is called.
5369   *  For continuous readings, run in the draw loop.
5370   *
5371   *  @method getLevel
5372   *  @for p5.Amplitude
5373   *  @param {Number} [channel] Optionally return only channel 0 (left) or 1 (right)
5374   *  @return {Number}       Amplitude as a number between 0.0 and 1.0
5375   *  @example
5376   *  <div><code>
5377   *  function preload(){
5378   *    sound = loadSound('assets/beat.mp3');
5379   *  }
5380   *
5381   *  function setup() {
5382   *    let cnv = createCanvas(100, 100);
5383   *    cnv.mouseClicked(toggleSound);
5384   *    amplitude = new p5.Amplitude();
5385   *  }
5386   *
5387   *  function draw() {
5388   *    background(220, 150);
5389   *    textAlign(CENTER);
5390   *    text('tap to play', width/2, 20);
5391   *
5392   *    let level = amplitude.getLevel();
5393   *    let size = map(level, 0, 1, 0, 200);
5394   *    ellipse(width/2, height/2, size, size);
5395   *  }
5396   *
5397   *  function toggleSound(){
5398   *    if (sound.isPlaying()) {
5399   *      sound.stop();
5400   *    } else {
5401   *      sound.play();
5402   *    }
5403   *  }
5404   *  </code></div>
5405   */
5406
5407
5408  p5.Amplitude.prototype.getLevel = function (channel) {
5409    if (typeof channel !== 'undefined') {
5410      if (this.normalize) {
5411        return this.stereoVolNorm[channel];
5412      } else {
5413        return this.stereoVol[channel];
5414      }
5415    } else if (this.normalize) {
5416      return this.volNorm;
5417    } else {
5418      return this.volume;
5419    }
5420  };
5421  /**
5422   * Determines whether the results of Amplitude.process() will be
5423   * Normalized. To normalize, Amplitude finds the difference the
5424   * loudest reading it has processed and the maximum amplitude of
5425   * 1.0. Amplitude adds this difference to all values to produce
5426   * results that will reliably map between 0.0 and 1.0. However,
5427   * if a louder moment occurs, the amount that Normalize adds to
5428   * all the values will change. Accepts an optional boolean parameter
5429   * (true or false). Normalizing is off by default.
5430   *
5431   * @method toggleNormalize
5432   * @for p5.Amplitude
5433   * @param {boolean} [boolean] set normalize to true (1) or false (0)
5434   */
5435
5436
5437  p5.Amplitude.prototype.toggleNormalize = function (bool) {
5438    if (typeof bool === 'boolean') {
5439      this.normalize = bool;
5440    } else {
5441      this.normalize = !this.normalize;
5442    }
5443
5444    this._workletNode.port.postMessage({
5445      name: 'toggleNormalize',
5446      normalize: this.normalize
5447    });
5448  };
5449  /**
5450   *  Smooth Amplitude analysis by averaging with the last analysis
5451   *  frame. Off by default.
5452   *
5453   *  @method smooth
5454   *  @for p5.Amplitude
5455   *  @param {Number} set smoothing from 0.0 <= 1
5456   */
5457
5458
5459  p5.Amplitude.prototype.smooth = function (s) {
5460    if (s >= 0 && s < 1) {
5461      this._workletNode.port.postMessage({
5462        name: 'smoothing',
5463        smoothing: s
5464      });
5465    } else {
5466      console.log('Error: smoothing must be between 0 and 1');
5467    }
5468  };
5469
5470  p5.Amplitude.prototype.dispose = function () {
5471    var index = p5sound.soundArray.indexOf(this);
5472    p5sound.soundArray.splice(index, 1);
5473
5474    if (this.input) {
5475      this.input.disconnect();
5476      delete this.input;
5477    }
5478
5479    if (this.output) {
5480      this.output.disconnect();
5481      delete this.output;
5482    }
5483
5484    this._workletNode.disconnect();
5485
5486    delete this._workletNode;
5487  };
5488}).call(exports, __webpack_require__, exports, module),
5489				__WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));
5490
5491 }),
5492 (function(module, exports, __webpack_require__) {
5493
5494"use strict";
5495var __WEBPACK_AMD_DEFINE_RESULT__;
5496
5497!(__WEBPACK_AMD_DEFINE_RESULT__ = (function (require) {
5498  var p5sound = __webpack_require__(1);
5499  /**
5500   *  <p>FFT (Fast Fourier Transform) is an analysis algorithm that
5501   *  isolates individual
5502   *  <a href="https://en.wikipedia.org/wiki/Audio_frequency">
5503   *  audio frequencies</a> within a waveform.</p>
5504   *
5505   *  <p>Once instantiated, a p5.FFT object can return an array based on
5506   *  two types of analyses: <br> • <code>FFT.waveform()</code> computes
5507   *  amplitude values along the time domain. The array indices correspond
5508   *  to samples across a brief moment in time. Each value represents
5509   *  amplitude of the waveform at that sample of time.<br>
5510   *  • <code>FFT.analyze() </code> computes amplitude values along the
5511   *  frequency domain. The array indices correspond to frequencies (i.e.
5512   *  pitches), from the lowest to the highest that humans can hear. Each
5513   *  value represents amplitude at that slice of the frequency spectrum.
5514   *  Use with <code>getEnergy()</code> to measure amplitude at specific
5515   *  frequencies, or within a range of frequencies. </p>
5516   *
5517   *  <p>FFT analyzes a very short snapshot of sound called a sample
5518   *  buffer. It returns an array of amplitude measurements, referred
5519   *  to as <code>bins</code>. The array is 1024 bins long by default.
5520   *  You can change the bin array length, but it must be a power of 2
5521   *  between 16 and 1024 in order for the FFT algorithm to function
5522   *  correctly. The actual size of the FFT buffer is twice the
5523   *  number of bins, so given a standard sample rate, the buffer is
5524   *  2048/44100 seconds long.</p>
5525   *
5526   *
5527   *  @class p5.FFT
5528   *  @constructor
5529   *  @param {Number} [smoothing]   Smooth results of Freq Spectrum.
5530   *                                0.0 < smoothing < 1.0.
5531   *                                Defaults to 0.8.
5532   *  @param {Number} [bins]    Length of resulting array.
5533   *                            Must be a power of two between
5534   *                            16 and 1024. Defaults to 1024.
5535   *  @example
5536   *  <div><code>
5537   *  function preload(){
5538   *    sound = loadSound('assets/Damscray_DancingTiger.mp3');
5539   *  }
5540   *
5541   *  function setup(){
5542   *    let cnv = createCanvas(100,100);
5543   *    cnv.mouseClicked(togglePlay);
5544   *    fft = new p5.FFT();
5545   *    sound.amp(0.2);
5546   *  }
5547   *
5548   *  function draw(){
5549   *    background(220);
5550   *
5551   *    let spectrum = fft.analyze();
5552   *    noStroke();
5553   *    fill(255, 0, 255);
5554   *    for (let i = 0; i< spectrum.length; i++){
5555   *      let x = map(i, 0, spectrum.length, 0, width);
5556   *      let h = -height + map(spectrum[i], 0, 255, height, 0);
5557   *      rect(x, height, width / spectrum.length, h )
5558   *    }
5559   *
5560   *    let waveform = fft.waveform();
5561   *    noFill();
5562   *    beginShape();
5563   *    stroke(20);
5564   *    for (let i = 0; i < waveform.length; i++){
5565   *      let x = map(i, 0, waveform.length, 0, width);
5566   *      let y = map( waveform[i], -1, 1, 0, height);
5567   *      vertex(x,y);
5568   *    }
5569   *    endShape();
5570   *
5571   *    text('tap to play', 20, 20);
5572   *  }
5573   *
5574   *  function togglePlay() {
5575   *    if (sound.isPlaying()) {
5576   *      sound.pause();
5577   *    } else {
5578   *      sound.loop();
5579   *    }
5580   *  }
5581   *  </code></div>
5582   */
5583
5584
5585  p5.FFT = function (smoothing, bins) {
5586    this.input = this.analyser = p5sound.audiocontext.createAnalyser();
5587    Object.defineProperties(this, {
5588      bins: {
5589        get: function get() {
5590          return this.analyser.fftSize / 2;
5591        },
5592        set: function set(b) {
5593          this.analyser.fftSize = b * 2;
5594        },
5595        configurable: true,
5596        enumerable: true
5597      },
5598      smoothing: {
5599        get: function get() {
5600          return this.analyser.smoothingTimeConstant;
5601        },
5602        set: function set(s) {
5603          this.analyser.smoothingTimeConstant = s;
5604        },
5605        configurable: true,
5606        enumerable: true
5607      }
5608    }); 
5609
5610    this.smooth(smoothing);
5611    this.bins = bins || 1024; 
5612
5613    p5sound.fftMeter.connect(this.analyser);
5614    this.freqDomain = new Uint8Array(this.analyser.frequencyBinCount);
5615    this.timeDomain = new Uint8Array(this.analyser.frequencyBinCount); 
5616
5617    this.bass = [20, 140];
5618    this.lowMid = [140, 400];
5619    this.mid = [400, 2600];
5620    this.highMid = [2600, 5200];
5621    this.treble = [5200, 14000]; 
5622
5623    p5sound.soundArray.push(this);
5624  };
5625  /**
5626   *  Set the input source for the FFT analysis. If no source is
5627   *  provided, FFT will analyze all sound in the sketch.
5628   *
5629   *  @method  setInput
5630   *  @for p5.FFT
5631   *  @param {Object} [source] p5.sound object (or web audio API source node)
5632   */
5633
5634
5635  p5.FFT.prototype.setInput = function (source) {
5636    if (!source) {
5637      p5sound.fftMeter.connect(this.analyser);
5638    } else {
5639      if (source.output) {
5640        source.output.connect(this.analyser);
5641      } else if (source.connect) {
5642        source.connect(this.analyser);
5643      }
5644
5645      p5sound.fftMeter.disconnect();
5646    }
5647  };
5648  /**
5649   *  Returns an array of amplitude values (between -1.0 and +1.0) that represent
5650   *  a snapshot of amplitude readings in a single buffer. Length will be
5651   *  equal to bins (defaults to 1024). Can be used to draw the waveform
5652   *  of a sound.
5653   *
5654   *  @method waveform
5655   *  @for p5.FFT
5656   *  @param {Number} [bins]    Must be a power of two between
5657   *                            16 and 1024. Defaults to 1024.
5658   *  @param {String} [precision] If any value is provided, will return results
5659   *                              in a Float32 Array which is more precise
5660   *                              than a regular array.
5661   *  @return {Array}  Array    Array of amplitude values (-1 to 1)
5662   *                            over time. Array length = bins.
5663   *
5664   */
5665
5666
5667  p5.FFT.prototype.waveform = function () {
5668    var bins, mode, normalArray;
5669
5670    for (var i = 0; i < arguments.length; i++) {
5671      if (typeof arguments[i] === 'number') {
5672        bins = arguments[i];
5673        this.analyser.fftSize = bins * 2;
5674      }
5675
5676      if (typeof arguments[i] === 'string') {
5677        mode = arguments[i];
5678      }
5679    } 
5680
5681
5682    if (mode && !p5.prototype._isSafari()) {
5683      timeToFloat(this, this.timeDomain);
5684      this.analyser.getFloatTimeDomainData(this.timeDomain);
5685      return this.timeDomain;
5686    } else {
5687      timeToInt(this, this.timeDomain);
5688      this.analyser.getByteTimeDomainData(this.timeDomain);
5689      var normalArray = new Array();
5690
5691      for (var j = 0; j < this.timeDomain.length; j++) {
5692        var scaled = p5.prototype.map(this.timeDomain[j], 0, 255, -1, 1);
5693        normalArray.push(scaled);
5694      }
5695
5696      return normalArray;
5697    }
5698  };
5699  /**
5700   *  Returns an array of amplitude values (between 0 and 255)
5701   *  across the frequency spectrum. Length is equal to FFT bins
5702   *  (1024 by default). The array indices correspond to frequencies
5703   *  (i.e. pitches), from the lowest to the highest that humans can
5704   *  hear. Each value represents amplitude at that slice of the
5705   *  frequency spectrum. Must be called prior to using
5706   *  <code>getEnergy()</code>.
5707   *
5708   *  @method analyze
5709   *  @for p5.FFT
5710   *  @param {Number} [bins]    Must be a power of two between
5711   *                             16 and 1024. Defaults to 1024.
5712   *  @param {Number} [scale]    If "dB," returns decibel
5713   *                             float measurements between
5714   *                             -140 and 0 (max).
5715   *                             Otherwise returns integers from 0-255.
5716   *  @return {Array} spectrum    Array of energy (amplitude/volume)
5717   *                              values across the frequency spectrum.
5718   *                              Lowest energy (silence) = 0, highe
5718st
5719   *                              possible is 255.
5720   *  @example
5721   *  <div><code>
5722   *  let osc, fft;
5723   *
5724   *  function setup(){
5725   *    let cnv = createCanvas(100,100);
5726   *    cnv.mousePressed(startSound);
5727   *    osc = new p5.Oscillator();
5728   *    osc.amp(0);
5729   *    fft = new p5.FFT();
5730   *  }
5731   *
5732   *  function draw(){
5733   *    background(220);
5734   *
5735   *    let freq = map(mouseX, 0, windowWidth, 20, 10000);
5736   *    freq = constrain(freq, 1, 20000);
5737   *    osc.freq(freq);
5738   *
5739   *    let spectrum = fft.analyze();
5740   *    noStroke();
5741   *    fill(255, 0, 255);
5742   *    for (let i = 0; i< spectrum.length; i++){
5743   *      let x = map(i, 0, spectrum.length, 0, width);
5744   *      let h = -height + map(spectrum[i], 0, 255, height, 0);
5745   *      rect(x, height, width / spectrum.length, h );
5746   *    }
5747   *
5748   *    stroke(255);
5749   *    if (!osc.started) {
5750   *      text('tap here and drag to change frequency', 10, 20, width - 20);
5751   *    } else {
5752   *      text(round(freq)+'Hz', 10, 20);
5753   *    }
5754   *  }
5755   *
5756   *  function startSound() {
5757   *    osc.start();
5758   *    osc.amp(0.5, 0.2);
5759   *  }
5760   *
5761   *  function mouseReleased() {
5762   *    osc.amp(0, 0.2);
5763   *  }
5764   *  </code></div>
5765   *
5766   *
5767   */
5768
5769
5770  p5.FFT.prototype.analyze = function () {
5771    var mode;
5772
5773    for (var i = 0; i < arguments.length; i++) {
5774      if (typeof arguments[i] === 'number') {
5775        this.bins = arguments[i];
5776        this.analyser.fftSize = this.bins * 2;
5777      }
5778
5779      if (typeof arguments[i] === 'string') {
5780        mode = arguments[i];
5781      }
5782    }
5783
5784    if (mode && mode.toLowerCase() === 'db') {
5785      freqToFloat(this);
5786      this.analyser.getFloatFrequencyData(this.freqDomain);
5787      return this.freqDomain;
5788    } else {
5789      freqToInt(this, this.freqDomain);
5790      this.analyser.getByteFrequencyData(this.freqDomain);
5791      var normalArray = Array.apply([], this.freqDomain);
5792      return normalArray;
5793    }
5794  };
5795  /**
5796   *  Returns the amount of energy (volume) at a specific
5797   *  <a href="https://en.wikipedia.org/wiki/Audio_frequency" target="_blank">
5798   *  frequency</a>, or the average amount of energy between two
5799   *  frequencies. Accepts Number(s) corresponding
5800   *  to frequency (in Hz), or a String corresponding to predefined
5801   *  frequency ranges ("bass", "lowMid", "mid", "highMid", "treble").
5802   *  Returns a range between 0 (no energy/volume at that frequency) and
5803   *  255 (maximum energy).
5804   *  <em>NOTE: analyze() must be called prior to getEnergy(). Analyze()
5805   *  tells the FFT to analyze frequency data, and getEnergy() uses
5806   *  the results determine the value at a specific frequency or
5807   *  range of frequencies.</em></p>
5808   *
5809   *  @method  getEnergy
5810   *  @for p5.FFT
5811   *  @param  {Number|String} frequency1   Will return a value representing
5812   *                                energy at this frequency. Alternately,
5813   *                                the strings "bass", "lowMid" "mid",
5814   *                                "highMid", and "treble" will return
5815   *                                predefined frequency ranges.
5816   *  @param  {Number} [frequency2] If a second frequency is given,
5817   *                                will return average amount of
5818   *                                energy that exists between the
5819   *                                two frequencies.
5820   *  @return {Number}   Energy   Energy (volume/amplitude) from
5821   *                              0 and 255.
5822   *
5823   */
5824
5825
5826  p5.FFT.prototype.getEnergy = function (frequency1, frequency2) {
5827    var nyquist = p5sound.audiocontext.sampleRate / 2;
5828
5829    if (frequency1 === 'bass') {
5830      frequency1 = this.bass[0];
5831      frequency2 = this.bass[1];
5832    } else if (frequency1 === 'lowMid') {
5833      frequency1 = this.lowMid[0];
5834      frequency2 = this.lowMid[1];
5835    } else if (frequency1 === 'mid') {
5836      frequency1 = this.mid[0];
5837      frequency2 = this.mid[1];
5838    } else if (frequency1 === 'highMid') {
5839      frequency1 = this.highMid[0];
5840      frequency2 = this.highMid[1];
5841    } else if (frequency1 === 'treble') {
5842      frequency1 = this.treble[0];
5843      frequency2 = this.treble[1];
5844    }
5845
5846    if (typeof frequency1 !== 'number') {
5847      throw 'invalid input for getEnergy()';
5848    } else if (!frequency2) {
5849      var index = Math.round(frequency1 / nyquist * this.freqDomain.length);
5850      return this.freqDomain[index];
5851    } else if (frequency1 && frequency2) {
5852      if (frequency1 > frequency2) {
5853        var swap = frequency2;
5854        frequency2 = frequency1;
5855        frequency1 = swap;
5856      }
5857
5858      var lowIndex = Math.round(frequency1 / nyquist * this.freqDomain.length);
5859      var highIndex = Math.round(frequency2 / nyquist * this.freqDomain.length);
5860      var total = 0;
5861      var numFrequencies = 0; 
5862
5863      for (var i = lowIndex; i <= highIndex; i++) {
5864        total += this.freqDomain[i];
5865        numFrequencies += 1;
5866      } 
5867
5868
5869      var toReturn = total / numFrequencies;
5870      return toReturn;
5871    } else {
5872      throw 'invalid input for getEnergy()';
5873    }
5874  }; 
5875
5876
5877  p5.FFT.prototype.getFreq = function (freq1, freq2) {
5878    console.log('getFreq() is deprecated. Please use getEnergy() instead.');
5879    var x = this.getEnergy(freq1, freq2);
5880    return x;
5881  };
5882  /**
5883   *  Returns the
5884   *  <a href="http://en.wikipedia.org/wiki/Spectral_centroid" target="_blank">
5885   *  spectral centroid</a> of the input signal.
5886   *  <em>NOTE: analyze() must be called prior to getCentroid(). Analyze()
5887   *  tells the FFT to analyze frequency data, and getCentroid() uses
5888   *  the results determine the spectral centroid.</em></p>
5889   *
5890   *  @method  getCentroid
5891   *  @for p5.FFT
5892   *  @return {Number}   Spectral Centroid Frequency   Frequency of the spectral centroid in Hz.
5893   *
5894   *
5895   * @example
5896   *  <div><code>
5897   * function setup(){
5898   *  cnv = createCanvas(100,100);
5899   *  cnv.mousePressed(userStartAudio);
5900   *  sound = new p5.AudioIn();
5901   *  sound.start();
5902   *  fft = new p5.FFT();
5903   *  sound.connect(fft);
5904   *}
5905   *
5906   *function draw() {
5907   *  if (getAudioContext().state !== 'running') {
5908   *    background(220);
5909   *    text('tap here and enable mic to begin', 10, 20, width - 20);
5910   *    return;
5911   *  }
5912   *  let centroidplot = 0.0;
5913   *  let spectralCentroid = 0;
5914   *
5915   *  background(0);
5916   *  stroke(0,255,0);
5917   *  let spectrum = fft.analyze();
5918   *  fill(0,255,0); // spectrum is green
5919   *
5920   *  //draw the spectrum
5921   *  for (let i = 0; i < spectrum.length; i++){
5922   *    let x = map(log(i), 0, log(spectrum.length), 0, width);
5923   *    let h = map(spectrum[i], 0, 255, 0, height);
5924   *    let rectangle_width = (log(i+1)-log(i))*(width/log(spectrum.length));
5925   *    rect(x, height, rectangle_width, -h )
5926   *  }
5927   *  let nyquist = 22050;
5928   *
5929   *  // get the centroid
5930   *  spectralCentroid = fft.getCentroid();
5931   *
5932   *  // the mean_freq_index calculation is for the display.
5933   *  let mean_freq_index = spectralCentroid/(nyquist/spectrum.length);
5934   *
5935   *  centroidplot = map(log(mean_freq_index), 0, log(spectrum.length), 0, width);
5936   *
5937   *  stroke(255,0,0); // the line showing where the centroid is will be red
5938   *
5939   *  rect(centroidplot, 0, width / spectrum.length, height)
5940   *  noStroke();
5941   *  fill(255,255,255);  // text is white
5942   *  text('centroid: ', 10, 20);
5943   *  text(round(spectralCentroid)+' Hz', 10, 40);
5944   *}
5945   * </code></div>
5946   */
5947
5948
5949  p5.FFT.prototype.getCentroid = function () {
5950    var nyquist = p5sound.audiocontext.sampleRate / 2;
5951    var cumulative_sum = 0;
5952    var centroid_normalization = 0;
5953
5954    for (var i = 0; i < this.freqDomain.length; i++) {
5955      cumulative_sum += i * this.freqDomain[i];
5956      centroid_normalization += this.freqDomain[i];
5957    }
5958
5959    var mean_freq_index = 0;
5960
5961    if (centroid_normalization !== 0) {
5962      mean_freq_index = cumulative_sum / centroid_normalization;
5963    }
5964
5965    var spec_centroid_freq = mean_freq_index * (nyquist / this.freqDomain.length);
5966    return spec_centroid_freq;
5967  };
5968  /**
5969   *  Smooth FFT analysis by averaging with the last analysis frame.
5970   *
5971   *  @method smooth
5972   *  @param {Number} smoothing    0.0 < smoothing < 1.0.
5973   *                               Defaults to 0.8.
5974   */
5975
5976
5977  p5.FFT.prototype.smooth = function (s) {
5978    if (typeof s !== 'undefined') {
5979      this.smoothing = s;
5980    }
5981
5982    return this.smoothing;
5983  };
5984
5985  p5.FFT.prototype.dispose = function () {
5986    var index = p5sound.soundArray.indexOf(this);
5987    p5sound.soundArray.splice(index, 1);
5988
5989    if (this.analyser) {
5990      this.analyser.disconnect();
5991      delete this.analyser;
5992    }
5993  };
5994  /**
5995   *  Returns an array of average amplitude values for a given number
5996   *  of frequency bands split equally. N defaults to 16.
5997   *  <em>NOTE: analyze() must be called prior to linAverages(). Analyze()
5998   *  tells the FFT to analyze frequency data, and linAverages() uses
5999   *  the results to group them into a smaller set of averages.</em></p>
6000   *
6001   *  @method  linAverages
6002   *  @for p5.FFT
6003   *  @param  {Number}  N                Number of returned frequency groups
6004   *  @return {Array}   linearAverages   Array of average amplitude values for each group
6005   */
6006
6007
6008  p5.FFT.prototype.linAverages = function (N) {
6009    var N = N || 16; 
6010
6011    var spectrum = this.freqDomain;
6012    var spectrumLength = spectrum.length;
6013    var spectrumStep = Math.floor(spectrumLength / N);
6014    var linearAverages = new Array(N); 
6015
6016    var groupIndex = 0;
6017
6018    for (var specIndex = 0; specIndex < spectrumLength; specIndex++) {
6019      linearAverages[groupIndex] = linearAverages[groupIndex] !== undefined ? (linearAverages[groupIndex] + spectrum[specIndex]) / 2 : spectrum[specIndex]; 
6020
6021      if (specIndex % spectrumStep === spectrumStep - 1) {
6022        groupIndex++;
6023      }
6024    }
6025
6026    return linearAverages;
6027  };
6028  /**
6029   *  Returns an array of average amplitude values of the spectrum, for a given
6030   *  set of <a href="https://en.wikipedia.org/wiki/Octave_band" target="_blank">
6031   *  Octave Bands</a>
6032   *  <em>NOTE: analyze() must be called prior to logAverages(). Analyze()
6033   *  tells the FFT to analyze frequency data, and logAverages() uses
6034   *  the results to group them into a smaller set of averages.</em></p>
6035   *
6036   *  @method  logAverages
6037   *  @for p5.FFT
6038   *  @param  {Array}   octaveBands    Array of Octave Bands objects for grouping
6039   *  @return {Array}   logAverages    Array of average amplitude values for each group
6040   */
6041
6042
6043  p5.FFT.prototype.logAverages = function (octaveBands) {
6044    var nyquist = p5sound.audiocontext.sampleRate / 2;
6045    var spectrum = this.freqDomain;
6046    var spectrumLength = spectrum.length;
6047    var logAverages = new Array(octaveBands.length); 
6048
6049    var octaveIndex = 0;
6050
6051    for (var specIndex = 0; specIndex < spectrumLength; specIndex++) {
6052      var specIndexFrequency = Math.round(specIndex * nyquist / this.freqDomain.length); 
6053
6054      if (specIndexFrequency > octaveBands[octaveIndex].hi) {
6055        octaveIndex++;
6056      }
6057
6058      logAverages[octaveIndex] = logAverages[octaveIndex] !== undefined ? (logAverages[octaveIndex] + spectrum[specIndex]) / 2 : spectrum[specIndex];
6059    }
6060
6061    return logAverages;
6062  };
6063  /**
6064   *  Calculates and Returns the 1/N
6065   *  <a href="https://en.wikipedia.org/wiki/Octave_band" target="_blank">Octave Bands</a>
6066   *  N defaults to 3 and minimum central frequency to 15.625Hz.
6067   *  (1/3 Octave Bands ~= 31 Frequency Bands)
6068   *  Setting fCtr0 to a central value of a higher octave will ignore the lower bands
6069   *  and produce less frequency groups.
6070   *
6071   *  @method   getOctaveBands
6072   *  @for p5.FFT
6073   *  @param  {Number}  N             Specifies the 1/N type of generated octave bands
6074   *  @param  {Number}  fCtr0         Minimum central frequency for the lowest band
6075   *  @return {Array}   octaveBands   Array of octave band objects with their bounds
6076   */
6077
6078
6079  p5.FFT.prototype.getOctaveBands = function (N, fCtr0) {
6080    var N = N || 3; 
6081
6082    var fCtr0 = fCtr0 || 15.625; 
6083
6084    var octaveBands = [];
6085    var lastFrequencyBand = {
6086      lo: fCtr0 / Math.pow(2, 1 / (2 * N)),
6087      ctr: fCtr0,
6088      hi: fCtr0 * Math.pow(2, 1 / (2 * N))
6089    };
6090    octaveBands.push(lastFrequencyBand);
6091    var nyquist = p5sound.audiocontext.sampleRate / 2;
6092
6093    while (lastFrequencyBand.hi < nyquist) {
6094      var newFrequencyBand = {};
6095      newFrequencyBand.lo = lastFrequencyBand.hi;
6096      newFrequencyBand.ctr = lastFrequencyBand.ctr * Math.pow(2, 1 / N);
6097      newFrequencyBand.hi = newFrequencyBand.ctr * Math.pow(2, 1 / (2 * N));
6098      octaveBands.push(newFrequencyBand);
6099      lastFrequencyBand = newFrequencyBand;
6100    }
6101
6102    return octaveBands;
6103  }; 
6104
6105
6106  var freqToFloat = function freqToFloat(fft) {
6107    if (fft.freqDomain instanceof Float32Array === false) {
6108      fft.freqDomain = new Float32Array(fft.analyser.frequencyBinCount);
6109    }
6110  };
6111
6112  var freqToInt = function freqToInt(fft) {
6113    if (fft.freqDomain instanceof Uint8Array === false) {
6114      fft.freqDomain = new Uint8Array(fft.analyser.frequencyBinCount);
6115    }
6116  };
6117
6118  var timeToFloat = function timeToFloat(fft) {
6119    if (fft.timeDomain instanceof Float32Array === false) {
6120      fft.timeDomain = new Float32Array(fft.analyser.frequencyBinCount);
6121    }
6122  };
6123
6124  var timeToInt = function timeToInt(fft) {
6125    if (fft.timeDomain instanceof Uint8Array === false) {
6126      fft.timeDomain = new Uint8Array(fft.analyser.frequencyBinCount);
6127    }
6128  };
6129}).call(exports, __webpack_require__, exports, module),
6130				__WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));
6131
6132 }),
6133 (function(module, exports, __webpack_require__) {
6134
6135"use strict";
6136var __WEBPACK_AMD_DEFINE_RESULT__;
6137
6138!(__WEBPACK_AMD_DEFINE_RESULT__ = (function (require) {
6139  var Signal = __webpack_require__(2);
6140
6141  var Add = __webpack_require__(7);
6142
6143  var Mult = __webpack_require__(3);
6144
6145  var Scale = __webpack_require__(13);
6146  /**
6147   *  <p>p5.Signal is a constant audio-rate signal used by p5.Oscillator
6148   *  and p5.Envelope for modulation math.</p>
6149   *
6150   *  <p>This is necessary because Web Audio is processed on a seprate clock.
6151   *  For example, the p5 draw loop runs about 60 times per second. But
6152   *  the audio clock must process samples 44100 times per second. If we
6153   *  want to add a value to each of those samples, we can't do it in the
6154   *  draw loop, but we can do it by adding a constant-rate audio signal.</p.
6155   *
6156   *  <p>This class mostly functions behind the scenes in p5.sound, and returns
6157   *  a Tone.Signal from the Tone.js library by Yotam Mann.
6158   *  If you want to work directly with audio signals for modular
6159   *  synthesis, check out
6160   *  <a href='http://bit.ly/1oIoEng' target=_'blank'>tone.js.</a></p>
6161   *
6162   *  @class  p5.Signal
6163   *  @constructor
6164   *  @return {Tone.Signal} A Signal object from the Tone.js library
6165   *  @example
6166   *  <div><code>
6167   *  let carrier, modulator;
6168   *
6169   *  function setup() {
6170   *    let cnv = createCanvas(100, 100);
6171   *    cnv.mousePressed(canvasPressed);
6172   *    background(220);
6173   *    text('tap to play', 20, 20);
6174   *
6175   *    carrier = new p5.Oscillator('sine');
6176   *    carrier.start();
6177   *    carrier.amp(1); // set amplitude
6178   *    carrier.freq(220); // set frequency
6179   *
6180   *    modulator = new p5.Oscillator('sawtooth');
6181   *    modulator.disconnect();
6182   *    modulator.start();
6183   *    modulator.amp(1);
6184   *    modulator.freq(4);
6185   *
6186   *    // Modulator's default amplitude range is -1 to 1.
6187   *    // Multiply it by -200, so the range is -200 to 200
6188   *    // then add 220 so the range is 20 to 420
6189   *    carrier.freq( modulator.mult(-400).add(220) );
6190   *  }
6191   *
6192   *  function canvasPressed() {
6193   *    userStartAudio();
6194   *    carrier.amp(1.0);
6195   *  }
6196   *
6197   *  function mouseReleased() {
6198   *    carrier.amp(0);
6199   *  }
6200   *  </code></div>
6201   */
6202
6203
6204  p5.Signal = function (value) {
6205    var s = new Signal(value); 
6206
6207    return s; 
6208  };
6209  /**
6210   *  Fade to value, for smooth transitions
6211   *
6212   *  @method  fade
6213   *  @for p5.Signal
6214   *  @param  {Number} value          Value to set this signal
6215   *  @param  {Number} [secondsFromNow] Length of fade, in seconds from now
6216   */
6217
6218
6219  Signal.prototype.fade = Signal.prototype.linearRampToValueAtTime;
6220  Mult.prototype.fade = Signal.prototype.fade;
6221  Add.prototype.fade = Signal.prototype.fade;
6222  Scale.prototype.fade = Signal.prototype.fade;
6223  /**
6224   *  Connect a p5.sound object or Web Audio node to this
6225   *  p5.Signal so that its amplitude values can be scaled.
6226   *
6227   *  @method setInput
6228   *  @for p5.Signal
6229   *  @param {Object} input
6230   */
6231
6232  Signal.prototype.setInput = function (_input) {
6233    _input.connect(this);
6234  };
6235
6236  Mult.prototype.setInput = Signal.prototype.setInput;
6237  Add.prototype.setInput = Signal.prototype.setInput;
6238  Scale.prototype.setInput = Signal.prototype.setInput; 
6239
6240  /**
6241   *  Add a constant value to this audio signal,
6242   *  and return the resulting audio signal. Does
6243   *  not change the value of the original signal,
6244   *  instead it returns a new p5.SignalAdd.
6245   *
6246   *  @method  add
6247   *  @for p5.Signal
6248   *  @param {Number} number
6249   *  @return {p5.Signal} object
6250   */
6251
6252  Signal.prototype.add = function (num) {
6253    var add = new Add(num); 
6254
6255    this.connect(add);
6256    return add;
6257  };
6258
6259  Mult.prototype.add = Signal.prototype.add;
6260  Add.prototype.add = Signal.prototype.add;
6261  Scale.prototype.add = Signal.prototype.add;
6262  /**
6263   *  Multiply this signal by a constant value,
6264   *  and return the resulting audio signal. Does
6265   *  not change the value of the original signal,
6266   *  instead it returns a new p5.SignalMult.
6267   *
6268   *  @method  mult
6269   *  @for p5.Signal
6270   *  @param {Number} number to multiply
6271   *  @return {p5.Signal} object
6272   */
6273
6274  Signal.prototype.mult = function (num) {
6275    var mult = new Mult(num); 
6276
6277    this.connect(mult);
6278    return mult;
6279  };
6280
6281  Mult.prototype.mult = Signal.prototype.mult;
6282  Add.prototype.mult = Signal.prototype.mult;
6283  Scale.prototype.mult = Signal.prototype.mult;
6284  /**
6285   *  Scale this signal value to a given range,
6286   *  and return the result as an audio signal. Does
6287   *  not change the value of the original signal,
6288   *  instead it returns a new p5.SignalScale.
6289   *
6290   *  @method  scale
6291   *  @for p5.Signal
6292   *  @param {Number} number to multiply
6293   *  @param  {Number} inMin  input range minumum
6294   *  @param  {Number} inMax  input range maximum
6295   *  @param  {Number} outMin input range minumum
6296   *  @param  {Number} outMax input range maximum
6297   *  @return {p5.Signal} object
6298   */
6299
6300  Signal.prototype.scale = function (inMin, inMax, outMin, outMax) {
6301    var mapOutMin, mapOutMax;
6302
6303    if (arguments.length === 4) {
6304      mapOutMin = p5.prototype.map(outMin, inMin, inMax, 0, 1) - 0.5;
6305      mapOutMax = p5.prototype.map(outMax, inMin, inMax, 0, 1) - 0.5;
6306    } else {
6307      mapOutMin = arguments[0];
6308      mapOutMax = arguments[1];
6309    }
6310
6311    var scale = new Scale(mapOutMin, mapOutMax);
6312    this.connect(scale);
6313    return scale;
6314  };
6315
6316  Mult.prototype.scale = Signal.prototype.scale;
6317  Add.prototype.scale = Signal.prototype.scale;
6318  Scale.prototype.scale = Signal.prototype.scale;
6319}).call(exports, __webpack_require__, exports, module),
6320				__WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));
6321
6322 }),
6323 (function(module, exports, __webpack_require__) {
6324
6325var __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;o<t.length;o++)n[o]=r*this.intervalToFrequencyRatio(t[o]);return n}.bind(this,this._expr,e),this},o.Frequency.prototype.toMidi=function(){return this.frequencyToMidi(this.valueOf())},o.Frequency.prototype.toNote=function(){var e=this.valueOf(),t=Math.log(e/o.Frequency.A4)/Math.LN2,r=Math.round(12*t)+57,n=Math.floor(r/12);return n<0&&(r+=-12*n),i[r%12]+n.toString()},o.Frequency.prototype.toSeconds=function(){return 1/this.valueOf()},o.Frequency.prototype.toFrequency=function(){return this.valueOf()},o.Frequency.prototype.toTicks=function(){var e=this._beatsToUnits(1),t=this.valueOf()/e;return Math.floor(t*o.Transport.PPQ)},o.Frequency.prototype._frequencyToUnits=function(e){return e},o.Frequency.prototype._ticksToUnits=function(e){return 1/(60*e/(o.Transport.bpm.value*o.Transport.PPQ))},o.Frequency.prototype._beatsToUnits=function(e){return 1/o.TimeBase.prototype._beatsToUnits.call(this,e)},o.Frequency.prototype._secondsToUnits=function(e){return 1/e},o.Frequency.prototype._defaultUnits="hz";var n={cbb:-2,cb:-1,c:0,"c#":1,cx:2,dbb:0,db:1,d:2,"d#":3,dx:4,ebb:2,eb:3,e:4,"e#":5,ex:6,fbb:3,fb:4,f:5,"f#":6,fx:7,gbb:5,gb:6,g:7,"g#":8,gx:9,abb:7,ab:8,a:9,"a#":10,ax:11,bbb:9,bb:10,b:11,"b#":12,bx:13},i=["C","C#","D","D#","E","F","F#","G","G#","A","A#","B"];return o.Frequency.A4=440,o.Frequency.prototype.midiToFrequency=function(e){return o.Frequency.A4*Math.pow(2,(e-69)/12)},o.Frequency.prototype.frequencyToMidi=function(e){return 69+12*Math.log(e/o.Frequency.A4)/Math.LN2},o.Frequency}).apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__),
6326				__WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));
6327
6328 }),
6329 (function(module, exports, __webpack_require__) {
6330
6331var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;!(__WEBPACK_AMD_DEFINE_ARRAY__ = [__webpack_require__(0),__webpack_require__(20)], __WEBPACK_AMD_DEFINE_RESULT__ = (function(o){return o.Trans
6331portTime=function(t,r){if(!(this instanceof o.TransportTime))return new o.TransportTime(t,r);o.Time.call(this,t,r)},o.extend(o.TransportTime,o.Time),o.TransportTime.prototype._unaryExpressions=Object.create(o.Time.prototype._unaryExpressions),o.TransportTime.prototype._unaryExpressions.quantize={regexp:/^@/,method:function(t){var r=this._secondsToTicks(t()),e=Math.ceil(o.Transport.ticks/r);return this._ticksToUnits(e*r)}},o.TransportTime.prototype._secondsToTicks=function(t){var r=t/this._beatsToUnits(1);return Math.round(r*o.Transport.PPQ)},o.TransportTime.prototype.valueOf=function(){return this._secondsToTicks(this._expr())+(this._plusNow?o.Transport.ticks:0)},o.TransportTime.prototype.toTicks=function(){return this.valueOf()},o.TransportTime.prototype.toSeconds=function(){return this._expr()+(this._plusNow?o.Transport.seconds:0)},o.TransportTime.prototype.toFrequency=function(){return 1/this.toSeconds()},o.TransportTime}).apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__),
6332				__WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));
6333
6334 }),
6335 (function(module, exports, __webpack_require__) {
6336
6337"use strict";
6338var __WEBPACK_AMD_DEFINE_RESULT__;
6339
6340!(__WEBPACK_AMD_DEFINE_RESULT__ = (function (require) {
6341  var p5sound = __webpack_require__(1);
6342
6343  var Add = __webpack_require__(7);
6344
6345  var Mult = __webpack_require__(3);
6346
6347  var Scale = __webpack_require__(13);
6348
6349  var TimelineSignal = __webpack_require__(14);
6350  /**
6351   *  <p>Envelopes are pre-defined amplitude distribution over time.
6352   *  Typically, envelopes are used to control the output volume
6353   *  of an object, a series of fades referred to as Attack, Decay,
6354   *  Sustain and Release (
6355   *  <a href="https://upload.wikimedia.org/wikipedia/commons/e/ea/ADSR_parameter.svg">ADSR</a>
6356   *  ). Envelopes can also control other Web Audio Parameters—for example, a p5.Envelope can
6357   *  control an Oscillator's frequency like this: <code>osc.freq(env)</code>.</p>
6358   *  <p>Use <code><a href="#/p5.Envelope/setRange">setRange</a></code> to change the attack/release level.
6359   *  Use <code><a href="#/p5.Envelope/setADSR">setADSR</a></code> to change attackTime, decayTime, sustainPercent and releaseTime.</p>
6360   *  <p>Use the <code><a href="#/p5.Envelope/play">play</a></code> method to play the entire envelope,
6361   *  the <code><a href="#/p5.Envelope/ramp">ramp</a></code> method for a pingable trigger,
6362   *  or <code><a href="#/p5.Envelope/triggerAttack">triggerAttack</a></code>/
6363   *  <code><a href="#/p5.Envelope/triggerRelease">triggerRelease</a></code> to trigger noteOn/noteOff.</p>
6364   *
6365   *  @class p5.Envelope
6366   *  @constructor
6367   *  @example
6368   *  <div><code>
6369   *  let t1 = 0.1;
6369 // attack time in seconds
6370   *  let l1 = 0.7; // attack level 0.0 to 1.0
6371   *  let t2 = 0.3; // decay time in seconds
6372   *  let l2 = 0.1; // decay level  0.0 to 1.0
6373   *
6374   *  let env;
6375   *  let triOsc;
6376   *
6377   *  function setup() {
6378   *    let cnv = createCanvas(100, 100);
6379   *    background(220);
6380   *    text('tap to play', 20, 20);
6381   *    cnv.mousePressed(playSound);
6382   *
6383   *    env = new p5.Envelope(t1, l1, t2, l2);
6384   *    triOsc = new p5.Oscillator('triangle');
6385   *  }
6386   *
6387   *  function playSound() {
6388   *    // starting the oscillator ensures that audio is enabled.
6389   *    triOsc.start();
6390   *    env.play(triOsc);
6391   *  }
6392   *  </code></div>
6393   */
6394
6395
6396  p5.Envelope = function (t1, l1, t2, l2, t3, l3) {
6397    /**
6398     * Time until envelope reaches attackLevel
6399     * @property attackTime
6400     */
6401    this.aTime = t1 || 0.1;
6402    /**
6403     * Level once attack is complete.
6404     * @property attackLevel
6405     */
6406
6407    this.aLevel = l1 || 1;
6408    /**
6409     * Time until envelope reaches decayLevel.
6410     * @property decayTime
6411     */
6412
6413    this.dTime = t2 || 0.5;
6414    /**
6415     * Level after decay. The envelope will sustain here until it is released.
6416     * @property decayLevel
6417     */
6418
6419    this.dLevel = l2 || 0;
6420    /**
6421     * Duration of the release portion of the envelope.
6422     * @property releaseTime
6423     */
6424
6425    this.rTime = t3 || 0;
6426    /**
6427     * Level at the end of the release.
6428     * @property releaseLevel
6429     */
6430
6431    this.rLevel = l3 || 0;
6432    this._rampHighPercentage = 0.98;
6433    this._rampLowPercentage = 0.02;
6434    this.output = p5sound.audiocontext.createGain();
6435    this.control = new TimelineSignal();
6436
6437    this._init(); 
6438
6439
6440    this.control.connect(this.output); 
6441
6442    this.connection = null; 
6443
6444    this.mathOps = [this.control]; 
6445
6446    this.isExponential = false; 
6447
6448    this.sourceToClear = null; 
6449
6450    this.wasTriggered = false; 
6451
6452    p5sound.soundArray.push(this);
6453  }; 
6454
6455
6456  p5.Envelope.prototype._init = function () {
6457    var now = p5sound.audiocontext.currentTime;
6458    var t = now;
6459    this.control.setTargetAtTime(0.00001, t, .001); 
6460
6461    this._setRampAD(this.aTime, this.dTime);
6462  };
6463  /**
6464   *  Reset the envelope with a series of time/value pairs.
6465   *
6466   *  @method  set
6467   *  @for p5.Envelope
6468   *  @param {Number} attackTime     Time (in seconds) before level
6469   *                                 reaches attackLevel
6470   *  @param {Number} attackLevel    Typically an amplitude between
6471   *                                 0.0 and 1.0
6472   *  @param {Number} decayTime      Time
6473   *  @param {Number} decayLevel   Amplitude (In a standard ADSR envelope,
6474   *                                 decayLevel = sustainLevel)
6475   *  @param {Number} releaseTime   Release Time (in seconds)
6476   *  @param {Number} releaseLevel  Amplitude
6477   *  @example
6478   *  <div><code>
6479   *  let attackTime;
6480   *  let l1 = 0.7; // attack level 0.0 to 1.0
6481   *  let t2 = 0.3; // decay time in seconds
6482   *  let l2 = 0.1; // decay level  0.0 to 1.0
6483   *  let l3 = 0.2; // release time in seconds
6484   *
6485   *  let env, triOsc;
6486   *
6487   *  function setup() {
6488   *    let cnv = createCanvas(100, 100);
6489   *    cnv.mousePressed(playSound);
6490   *
6491   *    env = new p5.Envelope();
6492   *    triOsc = new p5.Oscillator('triangle');
6493   *  }
6494   *
6495   *  function draw() {
6496   *    background(220);
6497   *    text('tap here to play', 5, 20);
6498   *
6499   *    attackTime = map(mouseX, 0, width, 0.0, 1.0);
6500   *    text('attack time: ' + attackTime, 5, height - 20);
6501   *  }
6502   *
6503   *  // mouseClick triggers envelope if over canvas
6504   *  function playSound() {
6505   *    env.set(attackTime, l1, t2, l2, l3);
6506   *
6507   *    triOsc.start();
6508   *    env.play(triOsc);
6509   *  }
6510   *  </code></div>
6511   *
6512   */
6513
6514
6515  p5.Envelope.prototype.set = function (t1, l1, t2, l2, t3, l3) {
6516    this.aTime = t1;
6517    this.aLevel = l1;
6518    this.dTime = t2 || 0;
6519    this.dLevel = l2 || 0;
6520    this.rTime = t3 || 0;
6521    this.rLevel = l3 || 0; 
6522
6523    this._setRampAD(t1, t2);
6524  };
6525  /**
6526   *  Set values like a traditional
6527   *  <a href="https://en.wikipedia.org/wiki/Synthesizer#/media/File:ADSR_parameter.svg">
6528   *  ADSR envelope
6529   *  </a>.
6530   *
6531   *  @method  setADSR
6532   *  @for p5.Envelope
6533   *  @param {Number} attackTime    Time (in seconds before envelope
6534   *                                reaches Attack Level
6535   *  @param {Number} [decayTime]    Time (in seconds) before envelope
6536   *                                reaches Decay/Sustain Level
6537   *  @param {Number} [susRatio]    Ratio between attackLevel and releaseLevel, on a scale from 0 to 1,
6538   *                                where 1.0 = attackLevel, 0.0 = releaseLevel.
6539   *                                The susRatio determines the decayLevel and the level at which the
6540   *                                sustain portion of the envelope will sustain.
6541   *                                For example, if attackLevel is 0.4, releaseLevel is 0,
6542   *                                and susAmt is 0.5, the decayLevel would be 0.2. If attackLevel is
6543   *                                increased to 1.0 (using <code>setRange</code>),
6544   *                                then decayLevel would increase proportionally, to become 0.5.
6545   *  @param {Number} [releaseTime]   Time in seconds from now (defaults to 0)
6546   *  @example
6547   *  <div><code>
6548   *  let attackLevel = 1.0;
6549   *  let releaseLevel = 0;
6550   *
6551   *  let attackTime = 0.001;
6552   *  let decayTime = 0.2;
6553   *  let susPercent = 0.2;
6554   *  let releaseTime = 0.5;
6555   *
6556   *  let env, triOsc;
6557   *
6558   *  function setup() {
6559   *    let cnv = createCanvas(100, 100);
6560   *    cnv.mousePressed(playEnv);
6561   *
6562   *    env = new p5.Envelope();
6563   *    triOsc = new p5.Oscillator('triangle');
6564   *    triOsc.amp(env);
6565   *    triOsc.freq(220);
6566   *  }
6567   *
6568   *  function draw() {
6569   *    background(220);
6570   *    text('tap here to play', 5, 20);
6571   *    attackTime = map(mouseX, 0, width, 0, 1.0);
6572   *    text('attack time: ' + attackTime, 5, height - 40);
6573   *  }
6574   *
6575   *  function playEnv() {
6576   *    triOsc.start();
6577   *    env.setADSR(attackTime, decayTime, susPercent, releaseTime);
6578   *    env.play();
6579   *  }
6580   *  </code></div>
6581   */
6582
6583
6584  p5.Envelope.prototype.setADSR = function (aTime, dTime, sPercent, rTime) {
6585    this.aTime = aTime;
6586    this.dTime = dTime || 0; 
6587
6588    this.sPercent = sPercent || 0;
6589    this.dLevel = typeof sPercent !== 'undefined' ? sPercent * (this.aLevel - this.rLevel) + this.rLevel : 0;
6590    this.rTime = rTime || 0; 
6591
6592    this._setRampAD(aTime, dTime);
6593  };
6594  /**
6595   *  Set max (attackLevel) and min (releaseLevel) of envelope.
6596   *
6597   *  @method  setRange
6598   *  @for p5.Envelope
6599   *  @param {Number} aLevel attack level (defaults to 1)
6600   *  @param {Number} rLevel release level (defaults to 0)
6601   *  @example
6602   *  <div><code>
6603   *  let attackLevel = 1.0;
6604   *  let releaseLevel = 0;
6605   *
6606   *  let attackTime = 0.001;
6607   *  let decayTime = 0.2;
6608   *  let susPercent = 0.2;
6609   *  let releaseTime = 0.5;
6610   *
6611   *  let env, triOsc;
6612   *
6613   *  function setup() {
6614   *    let cnv = createCanvas(100, 100);
6615   *    cnv.mousePressed(playEnv);
6616   *
6617   *    env = new p5.Envelope();
6618   *    triOsc = new p5.Oscillator('triangle');
6619   *    triOsc.amp(env);
6620   *    triOsc.freq(220);
6621   *  }
6622   *
6623   *  function draw() {
6624   *    background(220);
6625   *    text('tap here to play', 5, 20);
6626   *    attackLevel = map(mouseY, height, 0, 0, 1.0);
6627   *    text('attack level: ' + attackLevel, 5, height - 20);
6628   *  }
6629   *
6630   *  function playEnv() {
6631   *    triOsc.start();
6632   *    env.setRange(attackLevel, releaseLevel);
6633   *    env.play();
6634   *  }
6635   *  </code></div>
6636   */
6637
6638
6639  p5.Envelope.prototype.setRange = function (aLevel, rLevel) {
6640    this.aLevel = aLevel || 1;
6641    this.rLevel = rLevel || 0; 
6642  }; 
6643
6644
6645  p5.Envelope.prototype._setRampAD = function (t1, t2) {
6646    this._rampAttackTime = this.checkExpInput(t1);
6647    this._rampDecayTime = this.checkExpInput(t2);
6648    var TCDenominator = 1.0; 
6649
6650    TCDenominator = Math.log(1.0 / this.checkExpInput(1.0 - this._rampHighPercentage));
6651    this._rampAttackTC = t1 / this.checkExpInput(TCDenominator);
6652    TCDenominator = Math.log(1.0 / this._rampLowPercentage);
6653    this._rampDecayTC = t2 / this.checkExpInput(TCDenominator);
6654  }; 
6655
6656
6657  p5.Envelope.prototype.setRampPercentages = function (p1, p2) {
6658    this._rampHighPercentage = this.checkExpInput(p1);
6659    this._rampLowPercentage = this.checkExpInput(p2);
6660    var TCDenominator = 1.0; 
6661
6662    TCDenominator = Math.log(1.0 / this.checkExpInput(1.0 - this._rampHighPercentage));
6663    this._rampAttackTC = this._rampAttackTime / this.checkExpInput(TCDenominator);
6664    TCDenominator = Math.log(1.0 / this._rampLowPercentage);
6665    this._rampDecayTC = this._rampDecayTime / this.checkExpInput(TCDenominator);
6666  };
6667  /**
6668   *  Assign a parameter to be controlled by this envelope.
6669   *  If a p5.Sound object is given, then the p5.Envelope will control its
6670   *  output gain. If multiple inputs are provided, the env will
6671   *  control all of them.
6672   *
6673   *  @method  setInput
6674   *  @for p5.Envelope
6675   *  @param  {Object} [...inputs]         A p5.sound object or
6676   *                                Web Audio Param.
6677   */
6678
6679
6680  p5.Envelope.prototype.setInput = function () {
6681    for (var i = 0; i < arguments.length; i++) {
6682      this.connect(arguments[i]);
6683    }
6684  };
6685  /**
6686   *  Set whether the envelope ramp is linear (default) or exponential.
6687   *  Exponential ramps can be useful because we perceive amplitude
6688   *  and frequency logarithmically.
6689   *
6690   *  @method  setExp
6691   *  @for p5.Envelope
6692   *  @param {Boolean} isExp true is exponential, false is linear
6693   */
6694
6695
6696  p5.Envelope.prototype.setExp = function (isExp) {
6697    this.isExponential = isExp;
6698  }; 
6699
6700
6701  p5.Envelope.prototype.checkExpInput = function (value) {
6702    if (value <= 0) {
6703      value = 0.00000001;
6704    }
6705
6706    return value;
6707  };
6708  /**
6709   *  <p>Play tells the envelope to start acting on a given input.
6710   *  If the input is a p5.sound object (i.e. AudioIn, Oscillator,
6711   *  SoundFile), then Envelope will control its output volume.
6712   *  Envelopes can also be used to control any <a href="
6713   *  http://docs.webplatform.org/wiki/apis/webaudio/AudioParam">
6714   *  Web Audio Audio Param.</a></p>
6715   *
6716   *  @method  play
6717   *  @for p5.Envelope
6718   *  @param  {Object} unit         A p5.sound object or
6719   *                                Web Audio Param.
6720   *  @param  {Number} [startTime]  time from now (in seconds) at which to play
6721   *  @param  {Number} [sustainTime] time to sustain before releasing the envelope
6722   *  @example
6723   *  <div><code>
6724   *  let attackLevel = 1.0;
6725   *  let releaseLevel = 0;
6726   *
6727   *  let attackTime = 0.001;
6728   *  let decayTime = 0.2;
6729   *  let susPercent = 0.2;
6730   *  let releaseTime = 0.5;
6731   *
6732   *  let env, triOsc;
6733   *
6734   *  function setup() {
6735   *    let cnv = createCanvas(100, 100);
6736   *    cnv.mousePressed(playEnv);
6737   *
6738   *    env = new p5.Envelope();
6739   *    triOsc = new p5.Oscillator('triangle');
6740   *    triOsc.amp(env);
6741   *    triOsc.freq(220);
6742   *    triOsc.start();
6743   *  }
6744   *
6745   *  function draw() {
6746   *    background(220);
6747   *    text('tap here to play', 5, 20);
6748   *    attackTime = map(mouseX, 0, width, 0, 1.0);
6749   *    attackLevel = map(mouseY, height, 0, 0, 1.0);
6750   *    text('attack time: ' + attackTime, 5, height - 40);
6751   *    text('attack level: ' + attackLevel, 5, height - 20);
6752   *  }
6753   *
6754   *  function playEnv() {
6755   *    // ensure that audio is enabled
6756   *    userStartAudio();
6757   *
6758   *    env.setADSR(attackTime, decayTime, susPercent, releaseTime);
6759   *    env.setRange(attackLevel, releaseLevel);
6760   *    env.play();
6761   *  }
6762   *  </code></div>
6763   */
6764
6765
6766  p5.Envelope.prototype.play = function (unit, secondsFromNow, susTime) {
6767    var tFromNow = secondsFromNow || 0;
6768    var susTime = susTime || 0;
6769
6770    if (unit) {
6771      if (this.connection !== unit) {
6772        this.connect(unit);
6773      }
6774    }
6775
6776    this.triggerAttack(unit, tFromNow);
6777    this.triggerRelease(unit, tFromNow + this.aTime + this.dTime + susTime);
6778  };
6779  /**
6780   *  Trigger the Attack, and Decay portion of the Envelope.
6781   *  Similar to holding down a key on a piano, but it will
6782   *  hold the sustain level until you let go. Input can be
6783   *  any p5.sound object, or a <a href="
6784   *  http://docs.webplatform.org/wiki/apis/webaudio/AudioParam">
6785   *  Web Audio Param</a>.
6786   *
6787   *  @method  triggerAttack
6788   *  @for p5.Envelope
6789   *  @param  {Object} unit p5.sound Object or Web Audio Param
6790   *  @param  {Number} secondsFromNow time from now (in seconds)
6791   *  @example
6792   *  <div><code>
6793   *  let attackTime = 0.001;
6794   *  let decayTime = 0.2;
6795   *  let susPercent = 0.3;
6796   *  let releaseTime = 0.4;
6797   *  let env, triOsc;
6798   *
6799   *  function setup() {
6800   *    let cnv = createCanvas(100, 100);
6801   *    background(220);
6802   *    textAlign(CENTER);
6803   *    textSize(10);
6804   *    text('tap to triggerAttack', width/2, height/2);
6805   *
6806   *    env = new p5.Envelope();
6807   *    env.setADSR(attackTime, decayTime, susPercent, releaseTime);
6808   *    env.setRange(1.0, 0.0);
6809   *    triOsc = new p5.Oscillator('triangle');
6810   *    triOsc.freq(220);
6811   *
6812   *    cnv.mousePressed(envAttack);
6813   *  }
6814   *
6815   *  function envAttack()  {
6816   *    background(0, 255, 255);
6817   *    text('release to release', width/2, height/2);
6818   *
6819   *    // ensures audio is enabled. See also: `userStartAudio`
6820   *    triOsc.start();
6821   *
6822   *    env.triggerAttack(triOsc);
6823   *  }
6824   *
6825   *  function mouseReleased() {
6826   *    background(220);
6827   *    text('tap to triggerAttack', width/2, height/2);
6828   *
6829   *    env.triggerRelease(triOsc);
6830   *  }
6831   *  </code></div>
6832   */
6833
6834
6835  p5.Envelope.prototype.triggerAttack = function (unit, secondsFromNow) {
6836    var now = p5sound.audiocontext.currentTime;
6837    var tFromNow = secondsFromNow || 0;
6838    var t = now + tFromNow;
6839    this.lastAttack = t;
6840    this.wasTriggered = true;
6841
6842    if (unit) {
6843      if (this.connection !== unit) {
6844        this.connect(unit);
6845      }
6846    } 
6847
6848
6849    var valToSet = this.control.getValueAtTime(t);
6850
6851    if (this.isExponential === true) {
6852      this.control.exponentialRampToValueAtTime(this.checkExpInput(valToSet), t);
6853    } else {
6854      this.control.linearRampToValueAtTime(valToSet, t);
6855    } 
6856
6857
6858    t += this.aTime;
6859
6860    if (this.isExponential === true) {
6861      this.control.exponentialRampToValueAtTime(this.checkExpInput(this.aLevel), t);
6862      valToSet = this.checkExpInput(this.control.getValueAtTime(t));
6863      this.control.cancelScheduledValues(t);
6864      this.control.exponentialRampToValueAtTime(valToSet, t);
6865    } else {
6866      this.control.linearRampToValueAtTime(this.aLevel, t);
6867      valToSet = this.control.getValueAtTime(t);
6868      this.control.cancelScheduledValues(t);
6869      this.control.linearRampToValueAtTime(valToSet, t);
6870    } 
6871
6872
6873    t += this.dTime;
6874
6875    if (this.isExponential === true) {
6876      this.control.exponentialRampToValueAtTime(this.checkExpInput(this.dLevel), t);
6877      valToSet = this.checkExpInput(this.control.getValueAtTime(t));
6878      this.control.cancelScheduledValues(t);
6879      this.control.exponentialRampToValueAtTime(valToSet, t);
6880    } else {
6881      this.control.linearRampToValueAtTime(this.dLevel, t);
6882      valToSet = this.control.getValueAtTime(t);
6883      this.control.cancelScheduledValues(t);
6884      this.control.linearRampToValueAtTime(valToSet, t);
6885    }
6886  };
6887  /**
6888   *  Trigger the Release of the Envelope. This is similar to releasing
6889   *  the key on a piano and letting the sound fade according to the
6890   *  release level and release time.
6891   *
6892   *  @method  triggerRelease
6893   *  @for p5.Envelope
6894   *  @param  {Object} unit p5.sound Object or Web Audio Param
6895   *  @param  {Number} secondsFromNow time to trigger the release
6896   *  @example
6897   *  <div><code>
6898   *  let attackTime = 0.001;
6899   *  let decayTime = 0.2;
6900   *  let susPercent = 0.3;
6901   *  let releaseTime = 0.4;
6902   *  let env, triOsc;
6903   *
6904   *  function setup() {
6905   *    let cnv = createCanvas(100, 100);
6906   *    background(220);
6907   *    textAlign(CENTER);
6908   *    textSize(10);
6909   *    text('tap to triggerAttack', width/2, height/2);
6910   *
6911   *    env = new p5.Envelope();
6912   *    env.setADSR(attackTime, decayTime, susPercent, releaseTime);
6913   *    env.setRange(1.0, 0.0);
6914   *    triOsc = new p5.Oscillator('triangle');
6915   *    triOsc.freq(220);
6916   *
6917   *    cnv.mousePressed(envAttack);
6918   *  }
6919   *
6920   *  function envAttack()  {
6921   *    background(0, 255, 255);
6922   *    text('release to release', width/2, height/2);
6923   *
6924   *    // ensures audio is enabled. See also: `userStartAudio`
6925   *    triOsc.start();
6926   *
6927   *    env.triggerAttack(triOsc);
6928   *  }
6929   *
6930   *  function mouseReleased() {
6931   *    background(220);
6932   *    text('tap to triggerAttack', width/2, height/2);
6933   *
6934   *    env.triggerRelease(triOsc);
6935   *  }
6936   *  </code></div>
6937   */
6938
6939
6940  p5.Envelope.prototype.triggerRelease = function (unit, secondsFromNow) {
6941    if (!this.wasTriggered) {
6942      return;
6943    }
6944
6945    var now = p5sound.audiocontext.currentTime;
6946    var tFromNow = secondsFromNow || 0;
6947    var t = now + tFromNow;
6948
6949    if (unit) {
6950      if (this.connection !== unit) {
6951        this.connect(unit);
6952      }
6953    } 
6954
6955
6956    var valToSet = this.control.getValueAtTime(t);
6957
6958    if (this.isExponential === true) {
6959      this.control.exponentialRampToValueAtTime(this.checkExpInput(valToSet), t);
6960    } else {
6961      this.control.linearRampToValueAtTime(valToSet, t);
6962    } 
6963
6964
6965    t += this.rTime;
6966
6967    if (this.isExponential === true) {
6968      this.control.exponentialRampToValueAtTime(this.checkExpInput(this.rLevel), t);
6969      valToSet = this.checkExpInput(this.control.getValueAtTime(t));
6970      this.control.cancelScheduledValues(t);
6971      this.control.exponentialRampToValueAtTime(valToSet, t);
6972    } else {
6973      this.control.linearRampToValueAtTime(this.rLevel, t);
6974      valToSet = this.control.getValueAtTime(t);
6975      this.control.cancelScheduledValues(t);
6976      this.control.linearRampToValueAtTime(valToSet, t);
6977    }
6978
6979    this.wasTriggered = false;
6980  };
6981  /**
6982   *  Exponentially ramp to a value using the first two
6983   *  values from <code><a href="#/p5.Envelope/setADSR">setADSR(attackTime, decayTime)</a></code>
6984   *  as <a href="https://en.wikipedia.org/wiki/RC_time_constant">
6985   *  time constants</a> for simple exponential ramps.
6986   *  If the value is higher than current value, it uses attackTime,
6987   *  while a decrease uses decayTime.
6988   *
6989   *  @method  ramp
6990   *  @for p5.Envelope
6991   *  @param  {Object} unit           p5.sound Object or Web Audio Param
6992   *  @param  {Number} secondsFromNow When to trigger the ramp
6993   *  @param  {Number} v              Target value
6994   *  @param  {Number} [v2]           Second target value (optional)
6995   *  @example
6996   *  <div><code>
6997   *  let env, osc, amp;
6998   *
6999   *  let attackTime = 0.001;
7000   *  let decayTime = 0.2;
7001   *  let attackLevel = 1;
7002   *  let decayLevel = 0;
7003   *
7004   *  function setup() {
7005   *    let cnv = createCanvas(100, 100);
7006   *    fill(0,255,0);
7007   *    noStroke();
7008   *
7009   *    env = new p5.Envelope();
7010   *    env.setADSR(attackTime, decayTime);
7011   *    osc = new p5.Oscillator();
7012   *    osc.amp(env);
7013   *    amp = new p5.Amplitude();
7014   *
7015   *    cnv.mousePressed(triggerRamp);
7016   *  }
7017   *
7018   *  function triggerRamp() {
7019   *    // ensures audio is enabled. See also: `userStartAudio`
7020   *    osc.start();
7021   *
7022   *    env.ramp(osc, 0, attackLevel, decayLevel);
7023   *  }
7024   *
7025   *  function draw() {
7026   *    background(20);
7027   *    text('tap to play', 10, 20);
7028   *    let h = map(amp.getLevel(), 0, 0.4, 0, height);;
7029   *    rect(0, height, width, -h);
7030   *  }
7031   *  </code></div>
7032   */
7033
7034
7035  p5.Envelope.prototype.ramp = function (unit, secondsFromNow, v1, v2) {
7036    var now = p5sound.audiocontext.currentTime;
7037    var tFromNow = secondsFromNow || 0;
7038    var t = now + tFromNow;
7039    var destination1 = this.checkExpInput(v1);
7040    var destination2 = typeof v2 !== 'undefined' ? this.checkExpInput(v2) : undefined; 
7041
7042    if (unit) {
7043      if (this.connection !== unit) {
7044        this.connect(unit);
7045      }
7046    } 
7047
7048
7049    var currentVal = this.checkExpInput(this.control.getValueAtTime(t)); 
7050
7051    if (destination1 > currentVal) {
7052      this.control.setTargetAtTime(destination1, t, this._rampAttackTC);
7053      t += this._rampAttackTime;
7054    } 
7055    else if (destination1 < currentVal) {
7056        this.control.setTargetAtTime(destination1, t, this._rampDecayTC);
7057        t += this._rampDecayTime;
7058      } 
7059
7060
7061    if (destination2 === undefined) return; 
7062
7063    if (destination2 > destination1) {
7064      this.control.setTargetAtTime(destination2, t, this._rampAttackTC);
7065    } 
7066    else if (destination2 < destination1) {
7067        this.control.setTargetAtTime(destination2, t, this._rampDecayTC);
7068      }
7069  };
7070
7071  p5.Envelope.prototype.connect = function (unit) {
7072    this.connection = unit; 
7073
7074    if (unit instanceof p5.Oscillator || unit instanceof p5.SoundFile || unit instanceof p5.AudioIn || unit instanceof p5.Reverb || unit instanceof p5.Noise || unit instanceof p5.Filter || unit instanceof p5.Delay) {
7075      unit = unit.output.gain;
7076    }
7077
7078    if (unit instanceof AudioParam) {
7079      unit.setValueAtTime(0, p5sound.audiocontext.currentTime);
7080    }
7081
7082    if (unit instanceof p5.Signal) {
7083      unit.setValue(0);
7084    }
7085
7086    this.output.connect(unit);
7087  };
7088
7089  p5.Envelope.prototype.disconnect = function () {
7090    if (this.output) {
7091      this.output.disconnect();
7092    }
7093  }; 
7094
7095  /**
7096   *  Add a value to the p5.Oscillator's output amplitude,
7097   *  and return the oscillator. Calling this method
7098   *  again will override the initial add() with new values.
7099   *
7100   *  @method  add
7101   *  @for p5.Envelope
7102   *  @param {Number}
7102 number Constant number to add
7103   *  @return {p5.Envelope} Envelope Returns this envelope
7104   *                                     with scaled output
7105   */
7106
7107
7108  p5.Envelope.prototype.add = function (num) {
7109    var add = new Add(num);
7110    var thisChain = this.mathOps.length;
7111    var nextChain = this.output;
7112    return p5.prototype._mathChain(this, add, thisChain, nextChain, Add);
7113  };
7114  /**
7115   *  Multiply the p5.Envelope's output amplitude
7116   *  by a fixed value. Calling this method
7117   *  again will override the initial mult() with new values.
7118   *
7119   *  @method  mult
7120   *  @for p5.Envelope
7121   *  @param {Number} number Constant number to multiply
7122   *  @return {p5.Envelope} Envelope Returns this envelope
7123   *                                     with scaled output
7124   */
7125
7126
7127  p5.Envelope.prototype.mult = function (num) {
7128    var mult = new Mult(num);
7129    var thisChain = this.mathOps.length;
7130    var nextChain = this.output;
7131    return p5.prototype._mathChain(this, mult, thisChain, nextChain, Mult);
7132  };
7133  /**
7134   *  Scale this envelope's amplitude values to a given
7135   *  range, and return the envelope. Calling this method
7136   *  again will override the initial scale() with new values.
7137   *
7138   *  @method  scale
7139   *  @for p5.Envelope
7140   *  @param  {Number} inMin  input range minumum
7141   *  @param  {Number} inMax  input range maximum
7142   *  @param  {Number} outMin input range minumum
7143   *  @param  {Number} outMax input range maximum
7144   *  @return {p5.Envelope} Envelope Returns this envelope
7145   *                                     with scaled output
7146   */
7147
7148
7149  p5.Envelope.prototype.scale = function (inMin, inMax, outMin, outMax) {
7150    var scale = new Scale(inMin, inMax, outMin, outMax);
7151    var thisChain = this.mathOps.length;
7152    var nextChain = this.output;
7153    return p5.prototype._mathChain(this, scale, thisChain, nextChain, Scale);
7154  }; 
7155
7156
7157  p5.Envelope.prototype.dispose = function () {
7158    var index = p5sound.soundArray.indexOf(this);
7159    p5sound.soundArray.splice(index, 1);
7160    this.disconnect();
7161
7162    if (this.control) {
7163      this.control.dispose();
7164      this.control = null;
7165    }
7166
7167    for (var i = 1; i < this.mathOps.length; i++) {
7168      this.mathOps[i].dispose();
7169    }
7170  }; 
7171
7172
7173  p5.Env = function (t1, l1, t2, l2, t3, l3) {
7174    console.warn('WARNING: p5.Env is now deprecated and may be removed in future versions. ' + 'Please use the new p5.Envelope instead.');
7175    p5.Envelope.call(this, t1, l1, t2, l2, t3, l3);
7176  };
7177
7178  p5.Env.prototype = Object.create(p5.Envelope.prototype);
7179}).call(exports, __webpack_require__, exports, module),
7180				__WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));
7181
7182 }),
7183 (function(module, exports, __webpack_require__) {
7184
7185"use strict";
7186var __WEBPACK_AMD_DEFINE_RESULT__;
7187
7188!(__WEBPACK_AMD_DEFINE_RESULT__ = (function (require) {
7189  var p5sound = __webpack_require__(1);
7190
7191  __webpack_require__(23);
7192  /**
7193   *  Creates a Pulse object, an oscillator that implements
7194   *  Pulse Width Modulation.
7195   *  The pulse is created with two oscillators.
7196   *  Accepts a parameter for frequency, and to set the
7197   *  width between the pulses. See <a href="
7198   *  http://p5js.org/reference/#/p5.Oscillator">
7199   *  <code>p5.Oscillator</code> for a full list of methods.
7200   *
7201   *  @class p5.Pulse
7202   *  @extends p5.Oscillator
7203   *  @constructor
7204   *  @param {Number} [freq] Frequency in oscillations per second (Hz)
7205   *  @param {Number} [w]    Width between the pulses (0 to 1.0,
7206   *                         defaults to 0)
7207   *  @example
7208   *  <div><code>
7209   *  let pulse;
7210   *  function setup() {
7211   *    let cnv = createCanvas(100, 100);
7212   *    cnv.mousePressed(startPulse);
7213   *    background(220);
7214   *
7215   *    pulse = new p5.Pulse();
7216   *    pulse.amp(0.5);
7217   *    pulse.freq(220);
7218   *  }
7219   *  function startPulse() {
7220   *    pulse.start();
7221   *    pulse.amp(0.5, 0.02);
7222   *  }
7223   *  function mouseReleased() {
7224   *    pulse.amp(0, 0.2);
7225   *  }
7226   *  function draw() {
7227   *    background(220);
7228   *    text('tap to play', 5, 20, width - 20);
7229   *    let w = map(mouseX, 0, width, 0, 1);
7230   *    w = constrain(w, 0, 1);
7231   *    pulse.width(w);
7232   *    text('pulse width: ' + w, 5, height - 20);
7233   *  }
7234   *  </code></div>
7235   */
7236
7237
7238  p5.Pulse = function (freq, w) {
7239    p5.Oscillator.call(this, freq, 'sawtooth'); 
7240
7241    this.w = w || 0; 
7242
7243    this.osc2 = new p5.SawOsc(freq); 
7244
7245    this.dNode = p5sound.audiocontext.createDelay(); 
7246
7247    this.dcOffset = createDCOffset();
7248    this.dcGain = p5sound.audiocontext.createGain();
7249    this.dcOffset.connect(this.dcGain);
7250    this.dcGain.connect(this.output); 
7251
7252    this.f = freq || 440;
7253    var mW = this.w / this.oscillator.frequency.value;
7254    this.dNode.delayTime.value = mW;
7255    this.dcGain.gain.value = 1.7 * (0.5 - this.w); 
7256
7257    this.osc2.disconnect();
7258    this.osc2.panner.disconnect();
7259    this.osc2.amp(-1); 
7260
7261    this.osc2.output.connect(this.dNode);
7262    this.dNode.connect(this.output);
7263    this.output.gain.value = 1;
7264    this.output.connect(this.panner);
7265  };
7266
7267  p5.Pulse.prototype = Object.create(p5.Oscillator.prototype);
7268  /**
7269   *  Set the width of a Pulse object (an oscillator that implements
7270   *  Pulse Width Modulation).
7271   *
7272   *  @method  width
7273   *  @param {Number} [width]    Width between the pulses (0 to 1.0,
7274   *                         defaults to 0)
7275   */
7276
7277  p5.Pulse.prototype.width = function (w) {
7278    if (typeof w === 'number') {
7279      if (w <= 1.0 && w >= 0.0) {
7280        this.w = w; 
7281
7282        var mW = this.w / this.oscillator.frequency.value;
7283        this.dNode.delayTime.value = mW;
7284      }
7285
7286      this.dcGain.gain.value = 1.7 * (0.5 - this.w);
7287    } else {
7288      w.connect(this.dNode.delayTime);
7289      var sig = new p5.SignalAdd(-0.5);
7290      sig.setInput(w);
7291      sig = sig.mult(-1);
7292      sig = sig.mult(1.7);
7293      sig.connect(this.dcGain.gain);
7294    }
7295  };
7296
7297  p5.Pulse.prototype.start = function (f, time) {
7298    var now = p5sound.audiocontext.currentTime;
7299    var t = time || 0;
7300
7301    if (!this.started) {
7302      var freq = f || this.f;
7303      var type = this.oscillator.type;
7304      this.oscillator = p5sound.audiocontext.createOscillator();
7305      this.oscillator.frequency.setValueAtTime(freq, now);
7306      this.oscillator.type = type;
7307      this.oscillator.connect(this.output);
7308      this.oscillator.start(t + now); 
7309
7310      this.osc2.oscillator = p5sound.audiocontext.createOscillator();
7311      this.osc2.oscillator.frequency.setValueAtTime(freq, t + now);
7312      this.osc2.oscillator.type = type;
7313      this.osc2.oscillator.connect(this.osc2.output);
7314      this.osc2.start(t + now);
7315      this.freqNode = [this.oscillator.frequency, this.osc2.oscillator.frequency]; 
7316
7317      this.dcOffset = createDCOffset();
7318      this.dcOffset.connect(this.dcGain);
7319      this.dcOffset.start(t + now); 
7320
7321      if (this.mods !== undefined && this.mods.frequency !== undefined) {
7322        this.mods.frequency.connect(this.freqNode[0]);
7323        this.mods.frequency.connect(this.freqNode[1]);
7324      }
7325
7326      this.started = true;
7327      this.osc2.started = true;
7328    }
7329  };
7330
7331  p5.Pulse.prototype.stop = function (time) {
7332    if (this.started) {
7333      var t = time || 0;
7334      var now = p5sound.audiocontext.currentTime;
7335      this.oscillator.stop(t + now);
7336
7337      if (this.osc2.oscillator) {
7338        this.osc2.oscillator.stop(t + now);
7339      }
7340
7341      this.dcOffset.stop(t + now);
7342      this.started = false;
7343      this.osc2.started = false;
7344    }
7345  };
7346
7347  p5.Pulse.prototype.freq = function (val, rampTime, tFromNow) {
7348    if (typeof val === 'number') {
7349      this.f = val;
7350      var now = p5sound.audiocontext.currentTime;
7351      var rampTime = rampTime || 0;
7352      var tFromNow = tFromNow || 0;
7353      var currentFreq = this.oscillator.frequency.value;
7354      this.oscillator.frequency.cancelScheduledValues(now);
7355      this.oscillator.frequency.setValueAtTime(currentFreq, now + tFromNow);
7356      this.oscillator.frequency.exponentialRampToValueAtTime(val, tFromNow + rampTime + now);
7357      this.osc2.oscillator.frequency.cancelScheduledValues(now);
7358      this.osc2.oscillator.frequency.setValueAtTime(currentFreq, now + tFromNow);
7359      this.osc2.oscillator.frequency.exponentialRampToValueAtTime(val, tFromNow + rampTime + now);
7360
7361      if (this.freqMod) {
7362        this.freqMod.output.disconnect();
7363        this.freqMod = null;
7364      }
7365    } else if (val.output) {
7366      val.output.disconnect();
7367      val.output.connect(this.oscillator.frequency);
7368      val.output.connect(this.osc2.oscillator.frequency);
7369      this.freqMod = val;
7370    }
7371  }; 
7372
7373
7374  function createDCOffset() {
7375    var ac = p5sound.audiocontext;
7376    var buffer = ac.createBuffer(1, 2048, ac.sampleRate);
7377    var data = buffer.getChannelData(0);
7378
7379    for (var i = 0; i < 2048; i++) {
7380      data[i] = 1.0;
7381    }
7382
7383    var bufferSource = ac.createBufferSource();
7384    bufferSource.buffer = buffer;
7385    bufferSource.loop = true;
7386    return bufferSource;
7387  }
7388}).call(exports, __webpack_require__, exports, module),
7389				__WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));
7390
7391 }),
7392 (function(module, exports, __webpack_require__) {
7393
7394"use strict";
7395var __WEBPACK_AMD_DEFINE_RESULT__;
7396
7397!(__WEBPACK_AMD_DEFINE_RESULT__ = (function (require) {
7398  var p5sound = __webpack_require__(1);
7399  /**
7400   *  Noise is a type of oscillator that generates a buffer with random values.
7401   *
7402   *  @class p5.Noise
7403   *  @extends p5.Oscillator
7404   *  @constructor
7405   *  @param {String} type Type of noise can be 'white' (default),
7406   *                       'brown' or 'pink'.
7407   */
7408
7409
7410  p5.Noise = function (type) {
7411    var assignType;
7412    p5.Oscillator.call(this);
7413    delete this.f;
7414    delete this.freq;
7415    delete this.oscillator;
7416
7417    if (type === 'brown') {
7418      assignType = _brownNoise;
7419    } else if (type === 'pink') {
7420      assignType = _pinkNoise;
7421    } else {
7422      assignType = _whiteNoise;
7423    }
7424
7425    this.buffer = assignType;
7426  };
7427
7428  p5.Noise.prototype = Object.create(p5.Oscillator.prototype); 
7429
7430  var _whiteNoise = function () {
7431    var bufferSize = 2 * p5sound.audiocontext.sampleRate;
7432    var whiteBuffer = p5sound.audiocontext.createBuffer(1, bufferSize, p5sound.audiocontext.sampleRate);
7433    var noiseData = whiteBuffer.getChannelData(0);
7434
7435    for (var i = 0; i < bufferSize; i++) {
7436      noiseData[i] = Math.random() * 2 - 1;
7437    }
7438
7439    whiteBuffer.type = 'white';
7440    return whiteBuffer;
7441  }();
7442
7443  var _pinkNoise = function () {
7444    var bufferSize = 2 * p5sound.audiocontext.sampleRate;
7445    var pinkBuffer = p5sound.audiocontext.createBuffer(1, bufferSize, p5sound.audiocontext.sampleRate);
7446    var noiseData = pinkBuffer.getChannelData(0);
7447    var b0, b1, b2, b3, b4, b5, b6;
7448    b0 = b1 = b2 = b3 = b4 = b5 = b6 = 0.0;
7449
7450    for (var i = 0; i < bufferSize; i++) {
7451      var white = Math.random() * 2 - 1;
7452      b0 = 0.99886 * b0 + white * 0.0555179;
7453      b1 = 0.99332 * b1 + white * 0.0750759;
7454      b2 = 0.96900 * b2 + white * 0.1538520;
7455      b3 = 0.86650 * b3 + white * 0.3104856;
7456      b4 = 0.55000 * b4 + white * 0.5329522;
7457      b5 = -0.7616 * b5 - white * 0.0168980;
7458      noiseData[i] = b0 + b1 + b2 + b3 + b4 + b5 + b6 + white * 0.5362;
7459      noiseData[i] *= 0.11; 
7460
7461      b6 = white * 0.115926;
7462    }
7463
7464    pinkBuffer.type = 'pink';
7465    return pinkBuffer;
7466  }();
7467
7468  var _brownNoise = function () {
7469    var bufferSize = 2 * p5sound.audiocontext.sampleRate;
7470    var brownBuffer = p5sound.audiocontext.createBuffer(1, bufferSize, p5sound.audiocontext.sampleRate);
7471    var noiseData = brownBuffer.getChannelData(0);
7472    var lastOut = 0.0;
7473
7474    for (var i = 0; i < bufferSize; i++) {
7475      var white = Math.random() * 2 - 1;
7476      noiseData[i] = (lastOut + 0.02 * white) / 1.02;
7477      lastOut = noiseData[i];
7478      noiseData[i] *= 3.5;
7479    }
7480
7481    brownBuffer.type = 'brown';
7482    return brownBuffer;
7483  }();
7484  /**
7485   *  Set type of noise to 'white', 'pink' or 'brown'.
7486   *  White is the default.
7487   *
7488   *  @method setType
7489   *  @param {String} [type] 'white', 'pink' or 'brown'
7490   */
7491
7492
7493  p5.Noise.prototype.setType = function (type) {
7494    switch (type) {
7495      case 'white':
7496        this.buffer = _whiteNoise;
7497        break;
7498
7499      case 'pink':
7500        this.buffer = _pinkNoise;
7501        break;
7502
7503      case 'brown':
7504        this.buffer = _brownNoise;
7505        break;
7506
7507      default:
7508        this.buffer = _whiteNoise;
7509    }
7510
7511    if (this.started) {
7512      var now = p5sound.audiocontext.currentTime;
7513      this.stop(now);
7514      this.start(now + .01);
7515    }
7516  };
7517
7518  p5.Noise.prototype.getType = function () {
7519    return this.buffer.type;
7520  };
7521
7522  p5.Noise.prototype.start = function () {
7523    if (this.started) {
7524      this.stop();
7525    }
7526
7527    this.noise = p5sound.audiocontext.createBufferSource();
7528    this.noise.buffer = this.buffer;
7529    this.noise.loop = true;
7530    this.noise.connect(this.output);
7531    var now = p5sound.audiocontext.currentTime;
7532    this.noise.start(now);
7533    this.started = true;
7534  };
7535
7536  p5.Noise.prototype.stop = function () {
7537    var now = p5sound.audiocontext.currentTime;
7538
7539    if (this.noise) {
7540      this.noise.stop(now);
7541      this.started = false;
7542    }
7543  };
7544
7545  p5.Noise.prototype.dispose = function () {
7546    var now = p5sound.audiocontext.currentTime; 
7547
7548    var index = p5sound.soundArray.indexOf(this);
7549    p5sound.soundArray.splice(index, 1);
7550
7551    if (this.noise) {
7552      this.noise.disconnect();
7553      this.stop(now);
7554    }
7555
7556    if (this.output) {
7557      this.output.disconnect();
7558    }
7559
7560    if (this.panner) {
7561      this.panner.disconnect();
7562    }
7563
7564    this.output = null;
7565    this.panner = null;
7566    this.buffer = null;
7567    this.noise = null;
7568  };
7569}).call(exports, __webpack_require__, exports, module),
7570				__WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));
7571
7572 }),
7573 (function(module, exports, __webpack_require__) {
7574
7575"use strict";
7576var __WEBPACK_AMD_DEFINE_RESULT__;
7577
7578!(__WEBPACK_AMD_DEFINE_RESULT__ = (function (require) {
7579  var p5sound = __webpack_require__(1); 
7580
7581
7582  p5sound.inputSources = [];
7583  /**
7584   *  <p>Get audio from an input, i.e. your computer's microphone.</p>
7585   *
7586   *  <p>Turn the mic on/off with the start() and stop() methods. When the mic
7587   *  is on, its volume can be measured with getLevel or by connecting an
7588   *  FFT object.</p>
7589   *
7590   *  <p>If you want to hear the AudioIn, use the .connect() method.
7591   *  AudioIn does not connect to p5.sound output by default to prevent
7592   *  feedback.</p>
7593   *
7594   *  <p><em>Note: This uses the <a href="http://caniuse.com/stream">getUserMedia/
7595   *  Stream</a> API, which is not supported by certain browsers. Access in Chrome browser
7596   *  is limited to localhost and https, but access over http may be limited.</em></p>
7597   *
7598   *  @class p5.AudioIn
7599   *  @constructor
7600   *  @param {Function} [errorCallback] A function to call if there is an error
7601   *                                    accessing the AudioIn. For example,
7602   *                                    Safari and iOS devices do not
7603   *                                    currently allow microphone access.
7604   *  @example
7605   *  <div><code>
7606   *  let mic;
7607   *
7608   *   function setup(){
7609   *    let cnv = createCanvas(100, 100);
7610   *    cnv.mousePressed(userStartAudio);
7611   *    textAlign(CENTER);
7612   *    mic = new p5.AudioIn();
7613   *    mic.start();
7614   *  }
7615   *
7616   *  function draw(){
7617   *    background(0);
7618   *    fill(255);
7619   *    text('tap to start', width/2, 20);
7620   *
7621   *    micLevel = mic.getLevel();
7622   *    let y = height - micLevel * height;
7623   *    ellipse(width/2, y, 10, 10);
7624   *  }
7625   *  </code></div>
7626   */
7627
7628  p5.AudioIn = function (errorCallback) {
7629
7630    /**
7631     * @property {GainNode} input
7632     */
7633    this.input = p5sound.audiocontext.createGain();
7634    /**
7635     * @property {GainNode} output
7636     */
7637
7638    this.output = p5sound.audiocontext.createGain();
7639    /**
7640     * @property {MediaStream|null} stream
7641     */
7642
7643    this.stream = null;
7644    /**
7645     * @property {MediaStreamAudioSourceNode|null} mediaStream
7646     */
7647
7648    this.mediaStream = null;
7649    /**
7650     * @property {Number|null} currentSource
7651     */
7652
7653    this.currentSource = null;
7654    /**
7655     *  Client must allow browser to access their microphone / audioin source.
7656     *  Default: false. Will become true when the client enables access.
7657     *
7658     *  @property {Boolean} enabled
7659     */
7660
7661    this.enabled = false;
7662    /**
7663     * Input amplitude, connect to it by default but not to master out
7664     *
7665     *  @property {p5.Amplitude} amplitude
7666     */
7667
7668    this.amplitude = new p5.Amplitude();
7669    this.output.connect(this.amplitude.input);
7670
7671    if (!window.MediaStreamTrack || !window.navigator.mediaDevices || !window.navigator.mediaDevices.getUserMedia) {
7672      errorCallback ? errorCallback() : window.alert('This browser does not support MediaStreamTrack and mediaDevices');
7673    } 
7674
7675
7676    p5sound.soundArray.push(this);
7677  };
7678  /**
7679   *  Start processing audio input. This enables the use of other
7680   *  AudioIn methods like getLevel(). Note that by default, AudioIn
7681   *  is not connected to p5.sound's output. So you won't hear
7682   *  anything unless you use the connect() method.<br/>
7683   *
7684   *  Certain browsers limit access to the user's microphone. For example,
7685   *  Chrome only allows access from localhost and over https. For this reason,
7686   *  you may want to include an errorCallback—a function that is called 
7686in case
7687   *  the browser won't provide mic access.
7688   *
7689   *  @method start
7690   *  @for p5.AudioIn
7691   *  @param {Function} [successCallback] Name of a function to call on
7692   *                                    success.
7693   *  @param {Function} [errorCallback] Name of a function to call if
7694   *                                    there was an error. For example,
7695   *                                    some browsers do not support
7696   *                                    getUserMedia.
7697   */
7698
7699
7700  p5.AudioIn.prototype.start = function (successCallback, errorCallback) {
7701    var self = this;
7702
7703    if (this.stream) {
7704      this.stop();
7705    } 
7706
7707
7708    var audioSource = p5sound.inputSources[self.currentSource];
7709    var constraints = {
7710      audio: {
7711        sampleRate: p5sound.audiocontext.sampleRate,
7712        echoCancellation: false
7713      }
7714    }; 
7715
7716    if (p5sound.inputSources[this.currentSource]) {
7717      constraints.audio.deviceId = audioSource.deviceId;
7718    }
7719
7720    window.navigator.mediaDevices.getUserMedia(constraints).then(function (stream) {
7721      self.stream = stream;
7722      self.enabled = true; 
7723
7724      self.mediaStream = p5sound.audiocontext.createMediaStreamSource(stream);
7725      self.mediaStream.connect(self.output); 
7726
7727      self.amplitude.setInput(self.output);
7728      if (successCallback) successCallback();
7729    })["catch"](function (err) {
7730      if (errorCallback) errorCallback(err);else console.error(err);
7731    });
7732  };
7733  /**
7734   *  Turn the AudioIn off. If the AudioIn is stopped, it cannot getLevel().
7735   *  If re-starting, the user may be prompted for permission access.
7736   *
7737   *  @method stop
7738   *  @for p5.AudioIn
7739   */
7740
7741
7742  p5.AudioIn.prototype.stop = function () {
7743    if (this.stream) {
7744      this.stream.getTracks().forEach(function (track) {
7745        track.stop();
7746      });
7747      this.mediaStream.disconnect();
7748      delete this.mediaStream;
7749      delete this.stream;
7750    }
7751  };
7752  /**
7753   *  Connect to an audio unit. If no parameter is provided, will
7754   *  connect to the master output (i.e. your speakers).<br/>
7755   *
7756   *  @method  connect
7757   *  @for p5.AudioIn
7758   *  @param  {Object} [unit] An object that accepts audio input,
7759   *                          such as an FFT
7760   */
7761
7762
7763  p5.AudioIn.prototype.connect = function (unit) {
7764    if (unit) {
7765      if (unit.hasOwnProperty('input')) {
7766        this.output.connect(unit.input);
7767      } else if (unit.hasOwnProperty('analyser')) {
7768        this.output.connect(unit.analyser);
7769      } else {
7770        this.output.connect(unit);
7771      }
7772    } else {
7773      this.output.connect(p5sound.input);
7774    }
7775  };
7776  /**
7777   *  Disconnect the AudioIn from all audio units. For example, if
7778   *  connect() had been called, disconnect() will stop sending
7779   *  signal to your speakers.<br/>
7780   *
7781   *  @method  disconnect
7782   *  @for p5.AudioIn
7783   */
7784
7785
7786  p5.AudioIn.prototype.disconnect = function () {
7787    if (this.output) {
7788      this.output.disconnect(); 
7789
7790      this.output.connect(this.amplitude.input);
7791    }
7792  };
7793  /**
7794   *  Read the Amplitude (volume level) of an AudioIn. The AudioIn
7795   *  class contains its own instance of the Amplitude class to help
7796   *  make it easy to get a microphone's volume level. Accepts an
7797   *  optional smoothing value (0.0 < 1.0). <em>NOTE: AudioIn must
7798   *  .start() before using .getLevel().</em><br/>
7799   *
7800   *  @method  getLevel
7801   *  @for p5.AudioIn
7802   *  @param  {Number} [smoothing] Smoothing is 0.0 by default.
7803   *                               Smooths values based on previous values.
7804   *  @return {Number}           Volume level (between 0.0 and 1.0)
7805   */
7806
7807
7808  p5.AudioIn.prototype.getLevel = function (smoothing) {
7809    if (smoothing) {
7810      this.amplitude.smoothing = smoothing;
7811    }
7812
7813    return this.amplitude.getLevel();
7814  };
7815  /**
7816   *  Set amplitude (volume) of a mic input between 0 and 1.0. <br/>
7817   *
7818   *  @method  amp
7819   *  @for p5.AudioIn
7820   *  @param  {Number} vol between 0 and 1.0
7821   *  @param {Number} [time] ramp time (optional)
7822   */
7823
7824
7825  p5.AudioIn.prototype.amp = function (vol, t) {
7826    if (t) {
7827      var rampTime = t || 0;
7828      var currentVol = this.output.gain.value;
7829      this.output.gain.cancelScheduledValues(p5sound.audiocontext.currentTime);
7830      this.output.gain.setValueAtTime(currentVol, p5sound.audiocontext.currentTime);
7831      this.output.gain.linearRampToValueAtTime(vol, rampTime + p5sound.audiocontext.currentTime);
7832    } else {
7833      this.output.gain.cancelScheduledValues(p5sound.audiocontext.currentTime);
7834      this.output.gain.setValueAtTime(vol, p5sound.audiocontext.currentTime);
7835    }
7836  };
7837  /**
7838   * Returns a list of available input sources. This is a wrapper
7839   * for <a title="MediaDevices.enumerateDevices() - Web APIs | MDN" target="_blank" href=
7840   *  "https://developer.mozilla.org/en-US/docs/Web/API/MediaDevices/enumerateDevices"
7841   *  > and it returns a Promise.
7842   *
7843   * @method  getSources
7844   * @for p5.AudioIn
7845   * @param  {Function} [successCallback] This callback function handles the sources when they
7846   *                                      have been enumerated. The callback function
7847   *                                      receives the deviceList array as its only argument
7848   * @param  {Function} [errorCallback] This optional callback receives the error
7849   *                                    message as its argument.
7850   * @returns {Promise} Returns a Promise that can be used in place of the callbacks, similar
7851   *                            to the enumerateDevices() method
7852   * @example
7853   *  <div><code>
7854   *  let audioIn;
7855   *
7856   *  function setup(){
7857   *    text('getting sources...', 0, 20);
7858   *    audioIn = new p5.AudioIn();
7859   *    audioIn.getSources(gotSources);
7860   *  }
7861   *
7862   *  function gotSources(deviceList) {
7863   *    if (deviceList.length > 0) {
7864   *      //set the source to the first item in the deviceList array
7865   *      audioIn.setSource(0);
7866   *      let currentSource = deviceList[audioIn.currentSource];
7867   *      text('set source to: ' + currentSource.deviceId, 5, 20, width);
7868   *    }
7869   *  }
7870   *  </code></div>
7871   */
7872
7873
7874  p5.AudioIn.prototype.getSources = function (onSuccess, onError) {
7875    return new Promise(function (resolve, reject) {
7876      window.navigator.mediaDevices.enumerateDevices().then(function (devices) {
7877        p5sound.inputSources = devices.filter(function (device) {
7878          return device.kind === 'audioinput';
7879        });
7880        resolve(p5sound.inputSources);
7881
7882        if (onSuccess) {
7883          onSuccess(p5sound.inputSources);
7884        }
7885      })["catch"](function (error) {
7886        reject(error);
7887
7888        if (onError) {
7889          onError(error);
7890        } else {
7891          console.error('This browser does not support MediaStreamTrack.getSources()');
7892        }
7893      });
7894    });
7895  };
7896  /**
7897   *  Set the input source. Accepts a number representing a
7898   *  position in the array returned by getSources().
7899   *  This is only available in browsers that support
7900   *  <a title="MediaDevices.enumerateDevices() - Web APIs | MDN" target="_blank" href=
7901   *  "https://developer.mozilla.org/en-US/docs/Web/API/MediaDevices/enumerateDevices"
7902   *  >navigator.mediaDevices.enumerateDevices()</a>.<br/>
7903   *
7904   *  @method setSource
7905   *  @for p5.AudioIn
7906   *  @param {number} num position of input source in the array
7907   *  @example
7908   *  <div><code>
7909   *  let audioIn;
7910   *
7911   *  function setup(){
7912   *    text('getting sources...', 0, 20);
7913   *    audioIn = new p5.AudioIn();
7914   *    audioIn.getSources(gotSources);
7915   *  }
7916   *
7917   *  function gotSources(deviceList) {
7918   *    if (deviceList.length > 0) {
7919   *      //set the source to the first item in the deviceList array
7920   *      audioIn.setSource(0);
7921   *      let currentSource = deviceList[audioIn.currentSource];
7922   *      text('set source to: ' + currentSource.deviceId, 5, 20, width);
7923   *    }
7924   *  }
7925   *  </code></div>
7926   */
7927
7928
7929  p5.AudioIn.prototype.setSource = function (num) {
7930    if (p5sound.inputSources.length > 0 && num < p5sound.inputSources.length) {
7931      this.currentSource = num;
7932      console.log('set source to ', p5sound.inputSources[this.currentSource]);
7933    } else {
7934      console.log('unable to set input source');
7935    } 
7936
7937
7938    if (this.stream && this.stream.active) {
7939      this.start();
7940    }
7941  }; 
7942
7943
7944  p5.AudioIn.prototype.dispose = function () {
7945    var index = p5sound.soundArray.indexOf(this);
7946    p5sound.soundArray.splice(index, 1);
7947    this.stop();
7948
7949    if (this.output) {
7950      this.output.disconnect();
7951    }
7952
7953    if (this.amplitude) {
7954      this.amplitude.disconnect();
7955    }
7956
7957    delete this.amplitude;
7958    delete this.output;
7959  };
7960}).call(exports, __webpack_require__, exports, module),
7961				__WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));
7962
7963 }),
7964 (function(module, exports, __webpack_require__) {
7965
7966var __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__),
7967				__WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));
7968
7969 }),
7970 (function(module, exports, __webpack_require__) {
7971
7972var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;!(__WEBPACK_AMD_DEFINE_ARRAY__ = [__webpack_require__(0),__webpack_require__(7),__webpack_require__(16),__webpack_require__(3),__webpack_require__(53),__webpack_require__(26),__webpack_require__(54),__webpack_require__(25),__webpack_require__(55),__webpack_require__(56),__webpack_require__(57)], __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<e;r++)this.input[r]=this.context.createGain();var t,o=this._parseTree(n);try{t=this._eval(o)}catch(e){throw this._disposeNodes(),new Error("Tone.Expr: Could evaluate expression: "+n)}this.output=t},p.extend(p.Expr,p.SignalBase),p.Expr._Expressions={value:{signal:{regexp:/^\d+\.\d+|^\d+/,method:function(e){return new p.Signal(o(e))}},input:{regexp:/^\$\d/,method:function(e,n){return n.input[o(e.substr(1))]}}},glue:{"(":{regexp:/^\(/},")":{regexp:/^\)/},",":{regexp:/^,/}},func:{abs:{regexp:/^abs/,method:t.bind(this,p.Abs)},mod:{regexp:/^mod/,method:function(e,n){var r=i(e[1]),t=new p.Modulo(r);return n._eval(e[0]).connect(t),t}},pow:{regexp:/^pow/,method:function(e,n){var r=i(e[1]),t=new p.Pow(r);return n._eval(e[0]).connect(t),t}},a2g:{regexp:/^a2g/,method:function(e,n){var r=new p.AudioToGain;return n._eval(e[0]).connect(r),r}}},binary:{"+":{regexp:/^\+/,precedence:1,method:r.bind(this,p.Add)},"-":{regexp:/^\-/,precedence:1,method:function(e,n){return 1===e.length?t(p.Negate,e,n):r(p.Subtract,e,n)}},"*":{regexp:/^\*/,precedence:0,method:r.bind(this,p.Multiply)}},unary:{"-":{regexp:/^\-/,method:t.bind(this,p.Negate)},"!":{regexp:/^\!/,method:t.bind(this,p.NOT)}}},p.Expr.prototype._parseInputs=function(e){var n=e.match(/\$\d/g),r=0;if(null!==n)for(var t=0;t<n.length;t++){var o=parseInt(n[t].substr(1))+1;r=Math.max(r,o)}return r},p.Expr.prototype._replacements=function(e){for(var n=e.shift(),r=0;r<e.length;r++)n=n.replace(/\%/i,e[r]);return n},p.Expr.prototype._tokenize=function(e){for(var n=-1,r=[];0<e.length;){var t=o(e=e.trim());r.push(t),e=e.substr(t.value.length)}function o(e){for(var n in p.Expr._Expressions){var r=p.Expr._Expressions[n];for(var t in r){var o=r[t],i=o.regexp,a=e.match(i);if(null!==a)return{type:n,value:a[0],method:o.method}}}throw new SyntaxError("Tone.Expr: Unexpected token "+e)}return{next:function(){return r[++n]},peek:function(){return r[n+1]}}},p.Expr.prototype._parseTree=function(e){var t=this._tokenize(e),a=this.isUndef.bind(this);function r(e,n){return!a(e)&&"glue"===e.type&&e.value===n}
7972function o(e,n,r){var t=p.Expr._Expressions[n];if(!a(e))for(var o in t){var i=t[o];if(i.regexp.test(e.value)){if(a(r))return!0;if(i.precedence===r)return!0}}return!1}function i(e){var n;a(e)&&(e=5),n=e<0?function e(){var n,r;n=t.peek();if(o(n,"unary"))return n=t.next(),r=e(),{operator:n.value,method:n.method,args:[r]};return s()}():i(e-1);for(var r=t.peek();o(r,"binary",e);)n={operator:(r=t.next()).value,method:r.method,args:[n,i(e-1)]},r=t.peek();return n}function s(){var e,n;if(e=t.peek(),a(e))throw new SyntaxError("Tone.Expr: Unexpected termination of expression");if("func"===e.type)return function(e){var n=[];if(!r(t.next(),"("))throw new SyntaxError('Tone.Expr: Expected ( in a function call "'+e.value+'"');r(t.peek(),")")||(n=function(){var e,n=[];for(;e=i(),!a(e)&&(n.push(e),r(t.peek(),","));)t.next();return n}());if(r(t.next(),")"))return{method:e.method,args:n,name:name};throw new SyntaxError('Tone.Expr: Expected ) in a function call "'+e.value+'"')}(e=t.next());if("value"===e.type)return{method:(e=t.next()).method,args:e.value};if(r(e,"(")){if(t.next(),n=i(),!r(e=t.next(),")"))throw new SyntaxError("Expected )");return n}throw new SyntaxError("Tone.Expr: Parse error, cannot process token "+e.value)}return i()},p.Expr.prototype._eval=function(e){if(!this.isUndef(e)){var n=e.method(e.args,this);return this._nodes.push(n),n}},p.Expr.prototype._disposeNodes=function(){for(var e=0;e<this._nodes.length;e++){var n=this._nodes[e];this.isFunction(n.dispose)?n.dispose():this.isFunction(n.disconnect)&&n.disconnect(),n=null,this._nodes[e]=null}this._nodes=null},p.Expr.prototype.dispose=function(){p.prototype.dispose.call(this),this._disposeNodes()},p.Expr}).apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__),
7973				__WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));
7974
7975 }),
7976 (function(module, exports, __webpack_require__) {
7977
7978var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;!(__WEBPACK_AMD_DEFINE_ARRAY__ = [__webpack_require__(0),__webpack_require__(26),__webpack_require__(16),__webpack_require__(2)], __WEBPACK_AMD_DEFINE_RESULT__ = (function(e){"use strict";return e.GreaterThan=function(t){this.createInsOuts(2,0),this._param=this.input[0]=new e.Subtract(t),this.input[1]=this._param.input[1],this._gtz=this.output=new e.GreaterThanZero,this._param.connect(this._gtz)},e.extend(e.GreaterThan,e.Signal),e.GreaterThan.prototype.dispose=function(){return e.prototype.dispose.call(this),this._param.dispose(),this._param=null,this._gtz.dispose(),this._gtz=null,this},e.GreaterThan}).apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__),
7979				__WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));
7980
7981 }),
7982 (function(module, exports, __webpack_require__) {
7983
7984var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;!(__WEBPACK_AMD_DEFINE_ARRAY__ = [__webpack_require__(0),__webpack_require__(5),__webpack_require__(19)], __WEBPACK_AMD_DEFINE_RESULT__ = (function(s){"use strict";return s.Abs=function(){this._abs=this.input=this.output=new s.WaveShaper(function(s){return 0===s?0:Math.abs(s)},127)},s.extend(s.Abs,s.SignalBase),s.Abs.prototype.dispose=function(){return s.prototype.dispose.call(this),this._abs.dispose(),this._abs=null,this},s.Abs}).apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__),
7985				__WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));
7986
7987 }),
7988 (function(module, exports, __webpack_require__) {
7989
7990var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;!(__WEBPACK_AMD_DEFINE_ARRAY__ = [__webpack_require__(0),__webpack_require__(5),__webpack_require__(3),__webpack_require__(16)], __WEBPACK_AMD_DEFINE_RESULT__ = (function(i){"use strict";return i.Modulo=function(t){this.createInsOuts(1,0),this._shaper=new i.WaveShaper(Math.pow(2,16)),this._multiply=new i.Multiply,this._subtract=this.output=new i.Subtract,this._modSignal=new i.Signal(t),this.input.fan(this._shaper,this._subtract),this._modSignal.connect(this._multiply,0,0),this._shaper.connect(this._multiply,0,1),this._multiply.connect(this._subtract,0,1),this._setWaveShaper(t)},i.extend(i.Modulo,i.SignalBase),i.Modulo.prototype._setWaveShaper=function(i){this._shaper.setMap(function(t){return Math.floor((t+1e-4)/i)})}
7990,Object.defineProperty(i.Modulo.prototype,"value",{get:function(){return this._modSignal.value},set:function(t){this._modSignal.value=t,this._setWaveShaper(t)}}),i.Modulo.prototype.dispose=function(){return i.prototype.dispose.call(this),this._shaper.dispose(),this._shaper=null,this._multiply.dispose(),this._multiply=null,this._subtract.dispose(),this._subtract=null,this._modSignal.dispose(),this._modSignal=null,this},i.Modulo}).apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__),
7991				__WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));
7992
7993 }),
7994 (function(module, exports, __webpack_require__) {
7995
7996var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;!(__WEBPACK_AMD_DEFINE_ARRAY__ = [__webpack_require__(0),__webpack_require__(5)], __WEBPACK_AMD_DEFINE_RESULT__ = (function(t){"use strict";return t.Pow=function(e){this._exp=this.defaultArg(e,1),this._expScaler=this.input=this.output=new t.WaveShaper(this._expFunc(this._exp),8192)},t.extend(t.Pow,t.SignalBase),Object.defineProperty(t.Pow.prototype,"value",{get:function(){return this._exp},set:function(e){this._exp=e,this._expScaler.setMap(this._expFunc(this._exp))}}),t.Pow.prototype._expFunc=function(t){return function(e){return Math.pow(Math.abs(e),t)}},t.Pow.prototype.dispose=function(){return t.prototype.dispose.call(this),this._expScaler.dispose(),this._expScaler=null,this},t.Pow}).apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__),
7997				__WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));
7998
7999 }),
8000 (function(module, exports, __webpack_require__) {
8001
8002var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;!(__WEBPACK_AMD_DEFINE_ARRAY__ = [__webpack_require__(0),__webpack_require__(5),__webpack_require__(2)], __WEBPACK_AMD_DEFINE_RESULT__ = (function(n){"use strict";return n.AudioToGain=function(){this._norm=this.input=this.output=new n.WaveShaper(function(n){return(n+1)/2})},n.extend(n.AudioToGain,n.SignalBase),n.AudioToGain.prototype.dispose=function(){return n.prototype.dispose.call(this),this._norm.dispose(),this._norm=null,this},n.AudioToGain}).apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__),
8003				__WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));
8004
8005 }),
8006 (function(module, exports, __webpack_require__) {
8007
8008var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;!(__WEBPACK_AMD_DEFINE_ARRAY__ = [__webpack_require__(0),__webpack_require__(5)], __WEBPACK_AMD_DEFINE_RESULT__ = (function(e){"use strict";return e.EqualPowerGain=function(){this._eqPower=this.input=this.output=new e.WaveShaper(function(e){return Math.abs(e)<.001?0:this.equalPowerScale(e)}.bind(this),4096)},e.extend(e.EqualPowerGain,e.SignalBase),e.EqualPowerGain.prototype.dispose=function(){return e.prototype.dispose.call(this),this._eqPower.dispose(),this._eqPower=null,this},e.EqualPowerGain}).apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__),
8009				__WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));
8010
8011 }),
8012 (function(module, exports, __webpack_require__) {
8013
8014"use strict";
8015var __WEBPACK_AMD_DEFINE_RESULT__;
8016
8017!(__WEBPACK_AMD_DEFINE_RESULT__ = (function (require) {
8018  var Effect = __webpack_require__(4);
8019
8020  var EQFilter = __webpack_require__(60);
8021  /**
8022   * p5.EQ is an audio effect that performs the function of a multiband
8023   * audio equalizer. Equalization is used to adjust the balance of
8024   * frequency compoenents of an audio signal. This process is commonly used
8025   * in sound production and recording to change the waveform before it reaches
8026   * a sound output device. EQ can also be used as an audio effect to create
8027   * interesting distortions by filtering out parts of the spectrum. p5.EQ is
8028   * built using a chain of Web Audio Biquad Filter Nodes and can be
8029   * instantiated with 3 or 8 bands. Bands can be added or removed from
8030   * the EQ by directly modifying p5.EQ.bands (the array that stores filters).
8031   *
8032   * This class extends <a href = "/reference/#/p5.Effect">p5.Effect</a>.
8033   * Methods <a href = "/reference/#/p5.Effect/amp">amp()</a>, <a href = "/reference/#/p5.Effect/chain">chain()</a>,
8034   * <a href = "/reference/#/p5.Effect/drywet">drywet()</a>, <a href = "/reference/#/p5.Effect/connect">connect()</a>, and
8035   * <a href = "/reference/#/p5.Effect/disconnect">disconnect()</a> are available.
8036   *
8037   * @class p5.EQ
8038   * @constructor
8039   * @extends p5.Effect
8040   * @param {Number} [_eqsize] Constructor will accept 3 or 8, defaults to 3
8041   * @return {Object} p5.EQ object
8042   *
8043   * @example
8044   * <div><code>
8045   * let eq, soundFile
8046   * let eqBandIndex = 0;
8047   * let eqBandNames = ['lows', 'mids', 'highs'];
8048   *
8049   * function preload() {
8050   *   soundFormats('mp3', 'ogg');
8051   *   soundFile = loadSound('assets/beat');
8052   * }
8053   *
8054   * function setup() {
8055   *   let cnv = createCanvas(100, 100);
8056   *   cnv.mousePressed(toggleSound);
8057   *
8058   *   eq = new p5.EQ(eqBandNames.length);
8059   *   soundFile.disconnect();
8060   *   eq.process(soundFile);
8061   * }
8062   *
8063   * function draw() {
8064   *   background(30);
8065   *   noStroke();
8066   *   fill(255);
8067   *   textAlign(CENTER);
8068   *   text('filtering ', 50, 25);
8069   *
8070   *   fill(255, 40, 255);
8071   *   textSize(26);
8072   *   text(eqBandNames[eqBandIndex], 50, 55);
8073   *
8074   *   fill(255);
8075   *   textSize(9);
8076   *
8077   *   if (!soundFile.isPlaying()) {
8078   *     text('tap to play', 50, 80);
8079   *   } else {
8080   *     text('tap to filter next band', 50, 80)
8081   *   }
8082   * }
8083   *
8084   * function toggleSound() {
8085   *   if (!soundFile.isPlaying()) {
8086   *     soundFile.play();
8087   *   } else {
8088   *     eqBandIndex = (eqBandIndex + 1) % eq.bands.length;
8089   *   }
8090   *
8091   *   for (let i = 0; i < eq.bands.length; i++) {
8092   *     eq.bands[i].gain(0);
8093   *   }
8094   *   // filter the band we want to filter
8095   *   eq.bands[eqBandIndex].gain(-40);
8096   * }
8097   * </code></div>
8098   */
8099
8100
8101  p5.EQ = function (_eqsize) {
8102    Effect.call(this); 
8103
8104    _eqsize = _eqsize === 3 || _eqsize === 8 ? _eqsize : 3;
8105    var factor;
8106    _eqsize === 3 ? factor = Math.pow(2, 3) : factor = 2;
8107    /**
8108      *  The p5.EQ is built with abstracted p5.Filter objects.
8109      *  To modify any bands, use methods of the <a
8110      *  href="/reference/#/p5.Filter" title="p5.Filter reference">
8111      *  p5.Filter</a> API, especially `gain` and `freq`.
8112      *  Bands are stored in an array, with indices 0 - 3, or 0 - 7
8113      *  @property {Array}  bands
8114      *
8115    */
8116
8117    this.bands = [];
8118    var freq, res;
8119
8120    for (var i = 0; i < _eqsize; i++) {
8121      if (i === _eqsize - 1) {
8122        freq = 21000;
8123        res = .01;
8124      } else if (i === 0) {
8125        freq = 100;
8126        res = .1;
8127      } else if (i === 1) {
8128        freq = _eqsize === 3 ? 360 * factor : 360;
8129        res = 1;
8130      } else {
8131        freq = this.bands[i - 1].freq() * factor;
8132        res = 1;
8133      }
8134
8135      this.bands[i] = this._newBand(freq, res);
8136
8137      if (i > 0) {
8138        this.bands[i - 1].connect(this.bands[i].biquad);
8139      } else {
8140        this.input.connect(this.bands[i].biquad);
8141      }
8142    }
8143
8144    this.bands[_eqsize - 1].connect(this.output);
8145  };
8146
8147  p5.EQ.prototype = Object.create(Effect.prototype);
8148  /**
8149   * Process an input by connecting it to the EQ
8150   * @method  process
8151   * @param  {Object} src Audio source
8152   */
8153
8154  p5.EQ.prototype.process = function (src) {
8155    src.connect(this.input);
8156  }; 
8157  //   * Set the frequency and gain of each band in the EQ. This method should be
8158  //   * called with 3 or 8 frequency and gain pairs, depending on the size of the EQ.
8159  //   * ex. eq.set(freq0, gain0, freq1, gain1, freq2, gain2);
8160  //   *
8161  //   * @method  set
8162  //   * @for p5.EQ
8163  //   * @param {Number} [freq0] Frequency value for band with index 0
8164  //   * @param {Number} [gain0] Gain value for band with index 0
8165  //   * @param {Number} [freq1] Frequency value for band with index 1
8166  //   * @param {Number} [gain1] Gain value for band with index 1
8167  //   * @param {Number} [freq2] Frequency value for band with index 2
8168  //   * @param {Number} [gain2] Gain value for band with index 2
8169  //   * @param {Number} [freq3] Frequency value for band with index 3
8170  //   * @param {Number} [gain3] Gain value for band with index 3
8171  //   * @param {Number} [freq4] Frequency value for band with index 4
8172  //   * @param {Number} [gain4] Gain value for band with index 4
8173  //   * @param {Number} [freq5] Frequency value for band with index 5
8174  //   * @param {Number} [gain5] Gain value for band with index 5
8175  //   * @param {Number} [freq6] Frequency value for band with index 6
8176  //   * @param {Number} [gain6] Gain value for band with index 6
8177  //   * @param {Number} [freq7] Frequency value for band with index 7
8178  //   * @param {Number} [gain7] Gain value for band with index 7
8179  //   */
8180
8181
8182  p5.EQ.prototype.set = function () {
8183    if (arguments.length === this.bands.length * 2) {
8184      for (var i = 0; i < arguments.length; i += 2) {
8185        this.bands[i / 2].freq(arguments[i]);
8186        this.bands[i / 2].gain(arguments[i + 1]);
8187      }
8188    } else {
8189      console.error('Argument mismatch. .set() should be called with ' + this.bands.length * 2 + ' arguments. (one frequency and gain value pair for each band of the eq)');
8190    }
8191  };
8192  /**
8193   * Add a new band. Creates a p5.Filter and strips away everything but
8194   * the raw biquad filter. This method returns an abstracted p5.Filter,
8195   * which can be added to p5.EQ.bands, in order to create new EQ bands.
8196   * @private
8197   * @for p5.EQ
8198   * @method  _newBand
8199   * @param  {Number} freq
8200   * @param  {Number} res
8201   * @return {Object}      Abstracted Filter
8202   */
8203
8204
8205  p5.EQ.prototype._newBand = function (freq, res) {
8206    return new EQFilter(freq, res);
8207  };
8208
8209  p5.EQ.prototype.dispose = function () {
8210    Effect.prototype.dispose.apply(this);
8211
8212    if (this.bands) {
8213      while (this.bands.length > 0) {
8214        delete this.bands.pop().dispose();
8215      }
8216
8217      delete this.bands;
8218    }
8219  };
8220
8221  return p5.EQ;
8222}).call(exports, __webpack_require__, exports, module),
8223				__WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));
8224
8225 }),
8226 (function(module, exports, __webpack_require__) {
8227
8228"use strict";
8229var __WEBPACK_AMD_DEFINE_RESULT__;
8230
8231!(__WEBPACK_AMD_DEFINE_RESULT__ = (function (require) {
8232  var Filter = __webpack_require__(15);
8233
8234  var p5sound = __webpack_require__(1);
8235  /**
8236   *  EQFilter extends p5.Filter with constraints
8237   *  necessary for the p5.EQ
8238   *
8239   *  @private
8240   */
8241
8242
8243  var EQFilter = function EQFilter(freq, res) {
8244    Filter.call(this, 'peaking');
8245    this.disconnect();
8246    this.set(freq, res);
8247    this.biquad.gain.value = 0;
8248    delete this.input;
8249    delete this.output;
8250    delete this._drywet;
8251    delete this.wet;
8252  };
8253
8254  EQFilter.prototype = Object.create(Filter.prototype);
8255
8256  EQFilter.prototype.amp = function () {
8257    console.warn('`amp()` is not available for p5.EQ bands. Use `.gain()`');
8258  };
8259
8260  EQFilter.prototype.drywet = function () {
8261    console.warn('`drywet()` is not available for p5.EQ bands.');
8262  };
8263
8264  EQFilter.prototype.connect = function (unit) {
8265    var u = unit || p5.soundOut.input;
8266
8267    if (this.biquad) {
8268      this.biquad.connect(u.input ? u.input : u);
8269    } else {
8270      this.output.connect(u.input ? u.input : u);
8271    }
8272  };
8273
8274  EQFilter.prototype.disconnect = function () {
8275    if (this.biquad) {
8276      this.biquad.disconnect();
8277    }
8278  };
8279
8280  EQFilter.prototype.dispose = function () {
8281    var index = p5sound.soundArray.indexOf(this);
8282    p5sound.soundArray.splice(index, 1);
8283    this.disconnect();
8284    delete this.biquad;
8285  };
8286
8287  return EQFilter;
8288}).call(exports, __webpack_require__, exports, module),
8289				__WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));
8290
8291 }),
8292 (function(module, exports, __webpack_require__) {
8293
8294"use strict";
8295var __WEBPACK_AMD_DEFINE_RESULT__;
8296
8297!(__WEBPACK_AMD_DEFINE_RESULT__ = (function (require) {
8298  var p5sound = __webpack_require__(1);
8299
8300  var Effect = __webpack_require__(4);
8301  /**
8302   * Panner3D is based on the <a title="Web Audio Panner docs"  href=
8303   * "https://developer.mozilla.org/en-US/docs/Web/API/PannerNode">
8304   * Web Audio Spatial Panner Node</a>.
8305   * This panner is a spatial processing node that allows audio to be positioned
8306   * and oriented in 3D space.
8307   *
8308   * The position is relative to an <a title="Web Audio Listener docs" href=
8309   * "https://developer.mozilla.org/en-US/docs/Web/API/AudioListener">
8310   * Audio Context Listener</a>, which can be accessed
8311   * by <code>p5.soundOut.audiocontext.listener</code>
8312   *
8313   *
8314   * @class p5.Panner3D
8315   * @constructor
8316   */
8317
8318
8319  p5.Panner3D = function () {
8320    Effect.call(this);
8321    /**
8322     *  <a title="Web Audio Panner docs"  href=
8323     *  "https://developer.mozilla.org/en-US/docs/Web/API/PannerNode">
8324     *  Web Audio Spatial Panner Node</a>
8325     *
8326     *  Properties include
8327     *    -  <a title="w3 spec for Panning Model"
8328     *    href="https://www.w3.org/TR/webaudio/#idl-def-PanningModelType"
8329     *    >panningModel</a>: "equal power" or "HRTF"
8330     *    -  <a title="w3 spec for Distance Model"
8331     *    href="https://www.w3.org/TR/webaudio/#idl-def-DistanceModelType"
8332     *    >distanceModel</a>: "linear", "inverse", or "exponential"
8333     *
8334     *  @property {AudioNode} panner
8335     *
8336     */
8337
8338    this.panner = this.ac.createPanner();
8339    this.panner.panningModel = 'HRTF';
8340    this.panner.distanceModel = 'linear';
8341    this.panner.connect(this.output);
8342    this.input.connect(this.panner);
8343  };
8344
8345  p5.Panner3D.prototype = Object.create(Effect.prototype);
8346  /**
8347   * Connect an audio sorce
8348   *
8349   * @method  process
8350   * @for p5.Panner3D
8351   * @param  {Object} src Input source
8352   */
8353
8354  p5.Panner3D.prototype.process = function (src) {
8355    src.connect(this.input);
8356  };
8357  /**
8358   * Set the X,Y,Z position of the Panner
8359   * @method set
8360   * @for p5.Panner3D
8361   * @param  {Number} xVal
8362   * @param  {Number} yVal
8363   * @param  {Number} zVal
8364   * @param  {Number} time
8365   * @return {Array}      Updated x, y, z values as an array
8366   */
8367
8368
8369  p5.Panner3D.prototype.set = function (xVal, yVal, zVal, time) {
8370    this.positionX(xVal, time);
8371    this.positionY(yVal, time);
8372    this.positionZ(zVal, time);
8373    return [this.panner.positionX.value, this.panner.positionY.value, this.panner.positionZ.value];
8374  };
8375  /**
8376   * Getter and setter methods for position coordinates
8377   * @method positionX
8378   * @for p5.Panner3D
8379   * @return {Number}      updated coordinate value
8380   */
8381
8382  /**
8383   * Getter and setter methods for position coordinates
8384   * @method positionY
8385   * @for p5.Panner3D
8386   * @return {Number}      updated coordinate value
8387   */
8388
8389  /**
8390   * Getter and setter methods for position coordinates
8391   * @method positionZ
8392   * @for p5.Panner3D
8393   * @return {Number}      updated coordinate value
8394   */
8395
8396
8397  p5.Panner3D.prototype.positionX = function (xVal, time) {
8398    var t = time || 0;
8399
8400    if (typeof xVal === 'number') {
8401      this.panner.positionX.value = xVal;
8402      this.panner.positionX.cancelScheduledValues(this.ac.currentTime + 0.01 + t);
8403      this.panner.positionX.linearRampToValueAtTime(xVal, this.ac.currentTime + 0.02 + t);
8404    } else if (xVal) {
8405      xVal.connect(this.panner.positionX);
8406    }
8407
8408    return this.panner.positionX.value;
8409  };
8410
8411  p5.Panner3D.prototype.positionY = function (yVal, time) {
8412    var t = time || 0;
8413
8414    if (typeof yVal === 'number') {
8415      this.panner.positionY.value = yVal;
8416      this.panner.positionY.cancelScheduledValues(this.ac.currentTime + 0.01 + t);
8417      this.panner.positionY.linearRampToValueAtTime(yVal, this.ac.currentTime + 0.02 + t);
8418    } else if (yVal) {
8419      yVal.connect(this.panner.positionY);
8420    }
8421
8422    return this.panner.positionY.value;
8423  };
8424
8425  p5.Panner3D.prototype.positionZ = function (zVal, time) {
8426    var t = time || 0;
8427
8428    if (typeof zVal === 'number') {
8429      this.panner.positionZ.value = zVal;
8430      this.panner.positionZ.cancelScheduledValues(this.ac.currentTime + 0.01 + t);
8431      this.panner.positionZ.linearRampToValueAtTime(zVal, this.ac.currentTime + 0.02 + t);
8432    } else if (zVal) {
8433      zVal.connect(this.panner.positionZ);
8434    }
8435
8436    return this.panner.positionZ.value;
8437  };
8438  /**
8439   * Set the X,Y,Z position of the Panner
8440   * @method  orient
8441   * @for p5.Panner3D
8442   * @param  {Number} xVal
8443   * @param  {Number} yVal
8444   * @param  {Number} zVal
8445   * @param  {Number} time
8446   * @return {Array}      Updated x, y, z values as an array
8447   */
8448
8449
8450  p5.Panner3D.prototype.orient = function (xVal, yVal, zVal, time) {
8451    this.orientX(xVal, time);
8452    this.orientY(yVal, time);
8453    this.orientZ(zVal, time);
8454    return [this.panner.orientationX.value, this.panner.orientationY.value, this.panner.orientationZ.value];
8455  };
8456  /**
8457   * Getter and setter methods for orient coordinates
8458   * @method orientX
8459   * @for p5.Panner3D
8460   * @return {Number}      updated coordinate value
8461   */
8462
8463  /**
8464   * Getter and setter methods for orient coordinates
8465   * @method orientY
8466   * @for p5.Panner3D
8467   * @return {Number}      updated coordinate value
8468   */
8469
8470  /**
8471   * Getter and setter methods for orient coordinates
8472   * @method orientZ
8473   * @for p5.Panner3D
8474   * @return {Number}      updated coordinate value
8475   */
8476
8477
8478  p5.Panner3D.prototype.orientX = function (xVal, time) {
8479    var t = time || 0;
8480
8481    if (typeof xVal === 'number') {
8482      this.panner.orientationX.value = xVal;
8483      this.panner.orientationX.cancelScheduledValues(this.ac.currentTime + 0.01 + t);
8484      this.panner.orientationX.linearRampToValueAtTime(xVal, this.ac.currentTime + 0.02 + t);
8485    } else if (xVal) {
8486      xVal.connect(this.panner.orientationX);
8487    }
8488
8489    return this.panner.orientationX.value;
8490  };
8491
8492  p5.Panner3D.prototype.orientY = function (yVal, time) {
8493    var t = time || 0;
8494
8495    if (typeof yVal === 'number') {
8496      this.panner.orientationY.value = yVal;
8497      this.panner.orientationY.cancelScheduledValues(this.ac.currentTime + 0.01 + t);
8498      this.panner.orientationY.linearRampToValueAtTime(yVal, this.ac.currentTime + 0.02 + t);
8499    } else if (yVal) {
8500      yVal.connect(this.panner.orientationY);
8501    }
8502
8503    return this.panner.orientationY.value;
8504  };
8505
8506  p5.Panner3D.prototype.orientZ = function (zVal, time) {
8507    var t = time || 0;
8508
8509    if (typeof zVal === 'number') {
8510      this.panner.orientationZ.value = zVal;
8511      this.panner.orientationZ.cancelScheduledValues(this.ac.currentTime + 0.01 + t);
8512      this.panner.orientationZ.linearRampToValueAtTime(zVal, this.ac.currentTime + 0.02 + t);
8513    } else if (zVal) {
8514      zVal.connect(this.panner.orientationZ);
8515    }
8516
8517    return this.panner.orientationZ.value;
8518  };
8519  /**
8520   * Set the rolloff factor and max distance
8521   * @method  setFalloff
8522   * @for p5.Panner3D
8523   * @param {Number} [maxDistance]
8524   * @param {Number} [rolloffFactor]
8525   */
8526
8527
8528  p5.Panner3D.prototype.setFalloff = function (maxDistance, rolloffFactor) {
8529    this.maxDist(maxDistance);
8530    this.rolloff(rolloffFactor);
8531  };
8532  /**
8533   * Maxium distance between the source and the listener
8534   * @method  maxDist
8535   * @for p5.Panner3D
8536   * @param  {Number} maxDistance
8537   * @return {Number} updated value
8538   */
8539
8540
8541  p5.Panner3D.prototype.maxDist = function (maxDistance) {
8542    if (typeof maxDistance === 'number') {
8543      this.panner.maxDistance = maxDistance;
8544    }
8545
8546    return this.panner.maxDistance;
8547  };
8548  /**
8549   * How quickly the volume is reduced as the source moves away from the listener
8550   * @method  rollof
8551   * @for p5.Panner3D
8552   * @param  {Number} rolloffFactor
8553   * @return {Number} updated value
8554   */
8555
8556
8557  p5.Panner3D.prototype.rolloff = function (rolloffFactor) {
8558    if (typeof rolloffFactor === 'number') {
8559      this.panner.rolloffFactor = rolloffFactor;
8560    }
8561
8562    return this.panner.rolloffFactor;
8563  };
8564
8565  p5.Panner3D.dispose = function () {
8566    Effect.prototype.dispose.apply(this);
8567
8568    if (this.panner) {
8569      this.panner.disconnect();
8570      delete this.panner;
8571    }
8572  };
8573
8574  return p5.Panner3D;
8575}).call(exports, __webpack_require__, exports, module),
8576				__WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));
8577
8578 }),
8579 (function(module, exports, __webpack_require__) {
8580
8581"use strict";
8582var __WEBPACK_AMD_DEFINE_RESULT__;
8583
8584!(__WEBPACK_AMD_DEFINE_RESULT__ = (function (require) {
8585  var p5sound = __webpack_require__(1);
8586
8587  var Effect = __webpack_require__(4); 
8588  //   * listener is a class that can construct both a Spatial Panner
8589  //   * and a Spatial Listener. The panner is based on the 
8590  //   * Web Audio Spatial Panner Node
8591  //   * https://www.w3.org/TR/webaudio/#the-listenernode-interface
8592  //   * This panner is a spatial processing node that allows audio to be positioned
8593  //   * and oriented in 3D space. 
8594  //   *
8595  //   * The Listener modifies the properties of the Audio Context Listener. 
8596  //   * Both objects types use the same methods. The default is a spatial panner.
8597  //   *
8598  //   * <code>p5.Panner3D</code> - Constructs a Spatial Panner<br/>
8599  //   * <code>p5.Listener3D</code> - Constructs a Spatial Listener<br/>
8600  //   *
8601  //   * @class listener
8602  //   * @constructor
8603  //   * @return {Object} p5.Listener3D Object
8604  //   *
8605  //   * @param {Web Audio Node} listener Web Audio Spatial Panning Node
8606  //   * @param {AudioParam} listener.panningModel "equal power" or "HRTF"
8607  //   * @param {AudioParam} listener.distanceModel "linear", "inverse", or "exponential"
8608  //   * @param {String} [type] [Specify construction of a spatial panner or listener]
8609  //   */
8610
8611
8612  p5.Listener3D = function (type) {
8613    this.ac = p5sound.audiocontext;
8614    this.listener = this.ac.listener;
8615  }; 
8616  //   * Connect an audio sorce
8617  //   * @param  {Object} src Input source
8618  //   */
8619
8620
8621  p5.Listener3D.prototype.process = function (src) {
8622    src.connect(this.input);
8623  }; 
8624  //   * Set the X,Y,Z position of the Panner
8625  //   * @param  {[Number]} xVal
8626  //   * @param  {[Number]} yVal
8627  //   * @param  {[Number]} zVal
8628  //   * @param  {[Number]} time
8629  //   * @return {[Array]}      [Updated x, y, z values as an array]
8630  //   */
8631
8632
8633  p5.Listener3D.prototype.position = function (xVal, yVal, zVal, time) {
8634    this.positionX(xVal, time);
8635    this.positionY(yVal, time);
8636    this.positionZ(zVal, time);
8637    return [this.listener.positionX.value, this.listener.positionY.value, this.listener.positionZ.value];
8638  }; 
8639  //   * Getter and setter methods for position coordinates
8640  //   * @return {Number}      [updated coordinate value]
8641  //   */
8642
8643
8644  p5.Listener3D.prototype.positionX = function (xVal, time) {
8645    var t = time || 0;
8646
8647    if (typeof xVal === 'number') {
8648      this.listener.positionX.value = xVal;
8649      this.listener.positionX.cancelScheduledValues(this.ac.currentTime + 0.01 + t);
8650      this.listener.positionX.linearRampToValueAtTime(xVal, this.ac.currentTime + 0.02 + t);
8651    } else if (xVal) {
8652      xVal.connect(this.listener.positionX);
8653    }
8654
8655    return this.listener.positionX.value;
8656  };
8657
8658  p5.Listener3D.prototype.positionY = function (yVal, time) {
8659    var t = time || 0;
8660
8661    if (typeof yVal === 'number') {
8662      this.listener.positionY.value = yVal;
8663      this.listener.positionY.cancelScheduledValues(this.ac.currentTime + 0.01 + t);
8664      this.listener.positionY.linearRampToValueAtTime(yVal, this.ac.currentTime + 0.02 + t);
8665    } else if (yVal) {
8666      yVal.connect(this.listener.positionY);
8667    }
8668
8669    return this.listener.positionY.value;
8670  };
8671
8672  p5.Listener3D.prototype.positionZ = function (zVal, time) {
8673    var t = time || 0;
8674
8675    if (typeof zVal === 'number') {
8676      this.listener.positionZ.value = zVal;
8677      this.listener.positionZ.cancelScheduledValues(this.ac.currentTime + 0.01 + t);
8678      this.listener.positionZ.linearRampToValueAtTime(zVal, this.ac.currentTime + 0.02 + t);
8679    } else if (zVal) {
8680      zVal.connect(this.listener.positionZ);
8681    }
8682
8683    return this.listener.positionZ.value;
8684  }; 
8685  //   * Overrides the listener orient() method because Listener has slightly
8686  //   * different params. In human terms, Forward vectors are the direction the 
8687  //   * nose is pointing. Up vectors are the direction of the top of the head.
8688  //   *
8689  //   * @method orient
8690  //   * @param  {Number} xValF  Forward vector X direction
8691  //   * @param  {Number} yValF  Forward vector Y direction
8692  //   * @param  {Number} zValF  Forward vector Z direction
8693  //   * @param  {Number} xValU  Up vector X direction
8694  //   * @param  {Number} yValU  Up vector Y direction
8695  //   * @param  {Number} zValU  Up vector Z direction
8696  //   * @param  {Number} time  
8697  //   * @return {Array}       All orienation params
8698  //   */
8699
8700
8701  p5.Listener3D.prototype.orient = function (xValF, yValF, zValF, xValU, yValU, zValU, time) {
8702    if (arguments.length === 3 || arguments.length === 4) {
8703      time = arguments[3];
8704      this.orientForward(xValF, yValF, zValF, time);
8705    } else if (arguments.length === 6 || arguments === 7) {
8706      this.orientForward(xValF, yValF, zValF);
8707      this.orientUp(xValU, yValU, zValU, time);
8708    }
8709
8710    return [this.listener.forwardX.value, this.listener.forwardY.value, this.listener.forwardZ.value, this.listener.upX.value, this.listener.upY.value, this.listener.upZ.value];
8711  };
8712
8713  p5.Listener3D.prototype.orientForward = function (xValF, yValF, zValF, time) {
8714    this.forwardX(xValF, time);
8715    this.forwardY(yValF, time);
8716    this.forwardZ(zValF, time);
8717    return [this.listener.forwardX, this.listener.forwardY, this.listener.forwardZ];
8718  };
8719
8720  p5.Listener3D.prototype.orientUp = function (xValU, yValU, zValU, time) {
8721    this.upX(xValU, time);
8722    this.upY(yValU, time);
8723    this.upZ(zValU, time);
8724    return [this.listener.upX, this.listener.upY, this.listener.upZ];
8725  }; 
8726  //   * Getter and setter methods for orient coordinates
8727  //   * @return {Number}      [updated coordinate value]
8728  //   */
8729
8730
8731  p5.Listener3D.prototype.forwardX = function (xVal, time) {
8732    var t = time || 0;
8733
8734    if (typeof xVal === 'number') {
8735      this.listener.forwardX.value = xVal;
8736      this.listener.forwardX.cancelScheduledValues(this.ac.currentTime + 0.01 + t);
8737      this.listener.forwardX.linearRampToValueAtTime(xVal, this.ac.currentTime + 0.02 + t);
8738    } else if (xVal) {
8739      xVal.connect(this.listener.forwardX);
8740    }
8741
8742    return this.listener.forwardX.value;
8743  };
8744
8745  p5.Listener3D.prototype.forwardY = function (yVal, time) {
8746    var t = time || 0;
8747
8748    if (typeof yVal === 'number') {
8749      this.listener.forwardY.value = yVal;
8750      this.listener.forwardY.cancelScheduledValues(this.ac.currentTime + 0.01 + t);
8751      this.listener.forwardY.linearRampToValueAtTime(yVal, this.ac.currentTime + 0.02 + t);
8752    } else if (yVal) {
8753      yVal.connect(this.listener.forwardY);
8754    }
8755
8756    return this.listener.forwardY.value;
8757  };
8758
8759  p5.Listener3D.prototype.forwardZ = function (zVal, time) {
8760    var t = time || 0;
8761
8762    if (typeof zVal === 'number') {
8763      this.listener.forwardZ.value = zVal;
8764      this.listener.forwardZ.cancelScheduledValues(this.ac.currentTime + 0.01 + t);
8765      this.listener.forwardZ.linearRampToValueAtTime(zVal, this.ac.currentTime + 0.02 + t);
8766    } else if (zVal) {
8767      zVal.connect(this.listener.forwardZ);
8768    }
8769
8770    return this.listener.forwardZ.value;
8771  };
8772
8773  p5.Listener3D.prototype.upX = function (xVal, time) {
8774    var t = time || 0;
8775
8776    if (typeof xVal === 'number') {
8777      this.listener.upX.value = xVal;
8778      this.listener.upX.cancelScheduledValues(this.ac.currentTime + 0.01 + t);
8779      this.listener.upX.linearRampToValueAtTime(xVal, this.ac.currentTime + 0.02 + t);
8780    } else if (xVal) {
8781      xVal.connect(this.listener.upX);
8782    }
8783
8784    return this.listener.upX.value;
8785  };
8786
8787  p5.Listener3D.prototype.upY = function (yVal, time) {
8788    var t = time || 0;
8789
8790    if (typeof yVal === 'number') {
8791      this.listener.upY.value = yVal;
8792      this.listener.upY.cancelScheduledValues(this.ac.currentTime + 0.01 + t);
8793      this.listener.upY.linearRampToValueAtTime(yVal, this.ac.currentTime + 0.02 + t);
8794    } else if (yVal) {
8795      yVal.connect(this.listener.upY);
8796    }
8797
8798    return this.listener.upY.value;
8799  };
8800
8801  p5.Listener3D.prototype.upZ = function (zVal, time) {
8802    var t = time || 0;
8803
8804    if (typeof zVal === 'number') {
8805      this.listener.upZ.value = zVal;
8806      this.listener.upZ.cancelScheduledValues(this.ac.currentTime + 0.01 + t);
8807      this.listener.upZ.linearRampToValueAtTime(zVal, this.ac.currentTime + 0.02 + t);
8808    } else if (zVal) {
8809      zVal.connect(this.listener.upZ);
8810    }
8811
8812    return this.listener.upZ.value;
8813  };
8814
8815  return p5.Listener3D;
8816}).call(exports, __webpack_require__, exports, module),
8817				__WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));
8818
8819 }),
8820 (function(module, exports, __webpack_require__) {
8821
8822"use strict";
8823var __WEBPACK_AMD_DEFINE_RESULT__;
8824
8825!(__WEBPACK_AMD_DEFINE_RESULT__ = (function (require) {
8826  var Filter = __webpack_require__(15);
8827
8828  var Effect = __webpack_require__(4);
8829  /**
8830   *  Delay is an echo effect. It processes an existing sound source,
8831   *  and outputs a delayed version of that sound. The p5.Delay can
8832   *  produce different effects depending on the delayTime, feedback,
8833   *  filter, and type. In the example below, a feedback of 0.5 (the
8834   *  default value) will produce a looping delay that decreases in
8835   *  volume by 50% each repeat. A filter will cut out the high
8836   *  frequencies so that the delay does not sound as piercing as the
8837   *  original source.
8838   *
8839   *
8840   *  This class extends <a href = "/reference/#/p5.Effect">p5.Effect</a>.
8841   *  Methods <a href = "/reference/#/p5.Effect/amp">amp()</a>, <a href = "/reference/#/p5.Effect/chain">chain()</a>,
8842   *  <a href = "/reference/#/p5.Effect/drywet">drywet()</a>, <a href = "/reference/#/p5.Effect/connect">connect()</a>, and
8843   *  <a href = "/reference/#/p5.Effect/disconnect">disconnect()</a> are available.
8844   *  @class p5.Delay
8845   *  @extends p5.Effect
8846   *  @constructor
8847   *  @example
8848   *  <div><code>
8849   *  let osc;
8850   *
8851   *  function setup() {
8852   *    let cnv = createCanvas(100, 100);
8853   *    background(220);
8854   *    textAlign(CENTER);
8855   *    text('tap to play', width/2, height/2);
8856   *
8857   *    osc = new p5.Oscillator('square');
8858   *    osc.amp(0.5);
8859   *    delay = new p5.Delay();
8860   *
8861   *    // delay.process() accepts 4 parameters:
8862   *    // source, delayTime (in seconds), feedback, filter frequency
8863   *    delay.process(osc, 0.12, .7, 2300);
8864   *
8865   *    cnv.mousePressed(oscStart);
8866   *  }
8867   *
8868   *  function oscStart() {
8869   *    osc.start();
8870   *  }
8871   *
8872   *  function mouseReleased() {
8873   *    osc.stop();
8874   *  }
8875   *  </code></div>
8876   */
8877
8878
8879  p5.Delay = function () {
8880    Effect.call(this);
8881    this._split = this.ac.createChannelSplitter(2);
8882    this._merge = this.ac.createChannelMerger(2);
8883    this._leftGain = this.ac.createGain();
8884    this._rightGain = this.ac.createGain();
8885    /**
8886     *  The p5.Delay is built with two
8887     *  <a href="http://www.w3.org/TR/webaudio/#DelayNode">
8888     *  Web Audio Delay Nodes</a>, one for each stereo channel.
8889     *
8890     *  @for p5.Delay
8891     *  @property {DelayNode} leftDelay
8892     */
8893
8894    this.leftDelay = this.ac.createDelay();
8895    /**
8896     *  The p5.Delay is built with two
8897     *  <a href="http://www.w3.org/TR/webaudio/#DelayNode">
8898     *  Web Audio Delay Nodes</a>, one for each stereo channel.
8899     *  @for p5.Delay
8900     *  @property {DelayNode} rightDelay
8901     */
8902
8903    this.rightDelay = this.ac.createDelay();
8904    this._leftFilter = new Filter();
8905    this._rightFilter = new Filter();
8906
8907    this._leftFilter.disconnect();
8908
8909    this._rightFilter.disconnect();
8910
8911    this._leftFilter.biquad.frequency.setValueAtTime(1200, this.ac.currentTime);
8912
8913    this._rightFilter.biquad.frequency.setValueAtTime(1200, this.ac.currentTime);
8914
8915    this._leftFilter.biquad.Q.setValueAtTime(0.3, this.ac.currentTime);
8916
8917    this._rightFilter.biquad.Q.setValueAtTime(0.3, this.ac.currentTime); 
8918
8919
8920    this.input.connect(this._split);
8921    this.leftDelay.connect(this._leftGain);
8922    this.rightDelay.connect(this._rightGain);
8923
8924    this._leftGain.connect(this._leftFilter.input);
8925
8926    this._rightGain.connect(this._rightFilter.input);
8927
8928    this._merge.connect(this.wet);
8929
8930    this._leftFilter.biquad.gain.setValueAtTime(1, this.ac.currentTime);
8931
8932    this._rightFilter.biquad.gain.setValueAtTime(1, this.ac.currentTime); 
8933
8934
8935    this.setType(0);
8936    this._maxDelay = this.leftDelay.delayTime.maxValue; 
8937
8938    this.feedback(0.5);
8939  };
8940
8941  p5.Delay.prototype = Object.create(Effect.prototype);
8942  /**
8943   *  Add delay to an audio signal according to a set
8944   *  of delay parameters.
8945   *
8946   *  @method  process
8947   *  @for p5.Delay
8948   *  @param  {Object} Signal  An object that outputs audio
8949   *  @param  {Number} [delayTime] Time (in seconds) of the delay/echo.
8950   *                               Some browsers limit delayTime to
8951   *                               1 second.
8952   *  @param  {Number} [feedback]  sends the delay back through itself
8953   *                               in a loop that decreases in volume
8954   *                               each time.
8955   *  @param  {Number} [lowPass]   Cutoff frequency. Only frequencies
8956   *                               below the lowPass will be part of the
8957   *                               delay.
8958   */
8959
8960  p5.Delay.prototype.process = function (src, _delayTime, _feedback, _filter) {
8961    var feedback = _feedback || 0;
8962    var delayTime = _delayTime || 0;
8963
8964    if (feedback >= 1.0) {
8965      throw new Error('Feedback value will force a positive feedback loop.');
8966    }
8967
8968    if (delayTime >= this._maxDelay) {
8969      throw new Error('Delay Time exceeds maximum delay time of ' + this._maxDelay + ' second.');
8970    }
8971
8972    src.connect(this.input);
8973    this.leftDelay.delayTime.setValueAtTime(delayTime, this.ac.currentTime);
8974    this.rightDelay.delayTime.setValueAtTime(delayTime, this.ac.currentTime);
8975    this._leftGain.gain.value = feedback;
8976    this._rightGain.gain.value = feedback;
8977
8978    if (_filter) {
8979      this._leftFilter.freq(_filter);
8980
8981      this._rightFilter.freq(_filter);
8982    }
8983  };
8984  /**
8985   *  Set the delay (echo) time, in seconds. Usually this value will be
8986   *  a floating point number between 0.0 and 1.0.
8987   *
8988   *  @method  delayTime
8989   *  @for p5.Delay
8990   *  @param {Number} delayTime Time (in seconds) of the delay
8991   */
8992
8993
8994  p5.Delay.prototype.delayTime = function (t) {
8995    if (typeof t !== 'number') {
8996      t.connect(this.leftDelay.delayTime);
8997      t.connect(this.rightDelay.delayTime);
8998    } else {
8999      this.leftDelay.delayTime.cancelScheduledValues(this.ac.currentTime);
9000      this.rightDelay.delayTime.cancelScheduledValues(this.ac.currentTime);
9001      this.leftDelay.delayTime.linearRampToValueAtTime(t, this.ac.currentTime);
9002      this.rightDelay.delayTime.linearRampToValueAtTime(t, this.ac.currentTime);
9003    }
9004  };
9005  /**
9006   *  Feedback occurs when Delay sends its signal back through its input
9007   *  in a loop. The feedback amount determines how much signal to send each
9008   *  time through the loop. A feedback greater than 1.0 is not desirable because
9009   *  it will increase the overall output each time through the loop,
9010   *  creating an infinite feedback loop. The default value is 0.5
9011   *
9012   *  @method  feedback
9013   *  @for p5.Delay
9014   *  @param {Number|Object} feedback 0.0 to 1.0, or an object such as an
9015   *                                  Oscillator that can be used to
9016   *                                  modulate this param
9017   *  @returns {Number} Feedback value
9018   *
9019   */
9020
9021
9022  p5.Delay.prototype.feedback = function (f) {
9023    if (f && typeof f !== 'number') {
9024      f.connect(this._leftGain.gain);
9025      f.connect(this._rightGain.gain);
9026    } else if (f >= 1.0) {
9027      throw new Error('Feedback value will force a positive feedback loop.');
9028    } else if (typeof f === 'number') {
9029      this._leftGain.gain.value = f;
9030      this._rightGain.gain.value = f;
9031    } 
9032
9033
9034    return this._leftGain.gain.value;
9035  };
9036  /**
9037   *  Set a lowpass filter frequency for the delay. A lowpass filter
9038   *  will cut off any frequencies higher than the filter frequency.
9039   *
9040   *  @method  filter
9041   *  @for p5.Delay
9042   *  @param {Number|Object} cutoffFreq  A lowpass filter will cut off any
9043   *                              frequencies higher than the filter frequency.
9044   *  @param {Number|Object} res  Resonance of the filter frequency
9045   *                              cutoff, or an object (i.e. a p5.Oscillator)
9046   *                              that can be used to modulate this parameter.
9047   *                              High numbers (i.e. 15) will produce a resonance,
9048   *                              low numbers (i.e. .2) will produce a slope.
9049   */
9050
9051
9052  p5.Delay.prototype.filter = function (freq, q) {
9053    this._leftFilter.set(freq, q);
9054
9055    this._rightFilter.set(freq, q);
9056  };
9057  /**
9058   *  Choose a preset type of delay. 'pingPong' bounces the signal
9059   *  from the left to the right channel to produce a stereo effect.
9060   *  Any other parameter will revert to the default delay setting.
9061   *
9062   *  @method  setType
9063   *  @for p5.Delay
9064   *  @param {String|Number} type 'pingPong' (1) or 'default' (0)
9065   */
9066
9067
9068  p5.Delay.prototype.setType = function (t) {
9069    if (t === 1) {
9070      t = 'pingPong';
9071    }
9072
9073    this._split.disconnect();
9074
9075    this._leftFilter.disconnect();
9076
9077    this._rightFilter.disconnect();
9078
9079    this._split.connect(this.leftDelay, 0);
9080
9081    this._split.connect(this.rightDelay, 1);
9082
9083    switch (t) {
9084      case 'pingPong':
9085        this._rightFilter.setType(this._leftFilter.biquad.type);
9086
9087        this._leftFilter.output.connect(this._merge, 0, 0);
9088
9089        this._rightFilter.output.connect(this._merge, 0, 1);
9090
9091        this._leftFilter.output.connect(this.rightDelay);
9092
9093        this._rightFilter.output.connect(this.leftDelay);
9094
9095        break;
9096
9097      default:
9098        this._leftFilter.output.connect(this._merge, 0, 0);
9099
9100        this._rightFilter.output.connect(this._merge, 0, 1);
9101
9102        this._leftFilter.output.connect(this.leftDelay);
9103
9104        this._rightFilter.output.connect(this.rightDelay);
9105
9106    }
9107  }; 
9108
9109  /**
9110   *  Set the output level of the delay effect.
9111   *
9112   *  @method  amp
9113   *  @for p5.Delay
9114   *  @param  {Number} volume amplitude between 0 and 1.0
9115   *  @param {Number} [rampTime] create a fade that lasts rampTime
9116   *  @param {Number} [timeFromNow] schedule this event to happen
9117   *                                seconds from now
9118   */
9119
9120  /**
9121   *  Send output to a p5.sound or web audio object
9122   *
9123   *  @method  connect
9124   *  @for p5.Delay
9125   *  @param  {Object} unit
9126   */
9127
9128  /**
9129   *  Disconnect all output.
9130   *
9131   *  @method disconnect
9132   *  @for p5.Delay
9133   */
9134
9135
9136  p5.Delay.prototype.dispose = function () {
9137    Effect.prototype.dispose.apply(this);
9138
9139    this._split.disconnect();
9140
9141    this._leftFilter.dispose();
9142
9143    this._rightFilter.dispose();
9144
9145    this._merge.disconnect();
9146
9147    this._leftGain.disconnect();
9148
9149    this._rightGain.disconnect();
9150
9151    this.leftDelay.disconnect();
9152    this.rightDelay.disconnect();
9153    this._split = undefined;
9154    this._leftFilter = undefined;
9155    this._rightFilter = undefined;
9156    this._merge = undefined;
9157    this._leftGain = undefined;
9158    this._rightGain = undefined;
9159    this.leftDelay = undefined;
9160    this.rightDelay = undefined;
9161  };
9162}).call(exports, __webpack_require__, exports, module),
9163				__WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));
9164
9165 }),
9166 (function(module, exports, __webpack_require__) {
9167
9168"use strict";
9169var __WEBPACK_AMD_DEFINE_RESULT__;
9170
9171!(__WEBPACK_AMD_DEFINE_RESULT__ = (function (require) {
9172  var CustomError = __webpack_require__(11);
9173
9174  var Effect = __webpack_require__(4);
9175  /**
9176   *  Reverb adds depth to a sound through a large number of decaying
9177   *  echoes. It creates the perception that sound is occurring in a
9178   *  physical space. The p5.Reverb has paramters for Time (how long does the
9179   *  reverb last) and decayRate (how much the sound decays with each echo)
9180   *  that can be set with the .set() or .process() methods. The p5.Convolver
9181   *  extends p5.Reverb allowing you to recreate the sound of actual physical
9182   *  spaces through convolution.
9183   *
9184   *  This class extends <a href = "/reference/#/p5.Effect">p5.Effect</a>.
9185   *  Methods <a href = "/reference/#/p5.Effect/amp">amp()</a>, <a href = "/reference/#/p5.Effect/chain">chain()</a>,
9186   *  <a href = "/reference/#/p5.Effect/drywet">drywet()</a>, <a href = "/reference/#/p5.Effect/connect">connect()</a>, and
9187   *  <a href = "/reference/#/p5.Effect/disconnect">disconnect()</a> are available.
9188   *
9189   *  @class p5.Reverb
9190   *  @extends p5.Effect
9191   *  @constructor
9192   *  @example
9193   *  <div><code>
9194   *  let soundFile, reverb;
9195   *  function preload() {
9196   *    soundFile = loadSound('assets/Damscray_DancingTiger.mp3');
9197   *  }
9198   *
9199   *  function setup() {
9200   *    let cnv = createCanvas(100, 100);
9201   *    cnv.mousePressed(playSound);
9202   *
9203   *    reverb = new p5.Reverb();
9204   *    soundFile.disconnect(); // so we'll only hear reverb...
9205   *
9206   *    // connect soundFile to reverb, process w/
9207   *    // 3 second reverbTime, decayRate of 2%
9208   *    reverb.process(soundFile, 3, 2);
9209   *  }
9210   *
9211   *  function draw() {
9212   *    let dryWet = constrain(map(mouseX, 0, width, 0, 1), 0, 1);
9213   *    // 1 = all reverb, 0 = no reverb
9214   *    reverb.drywet(dryWet);
9215   *
9216   *    background(220);
9217   *    text('tap to play', 10, 20);
9218   *    text('dry/wet: ' + round(dryWet * 100) + '%', 10, height - 20);
9219   *  }
9220   *
9221   *  function playSound() {
9222   *    soundFile.play();
9223   *  }
9224   *  </code></div>
9225   */
9226
9227
9228  p5.Reverb = function () {
9229    Effect.call(this);
9230
9231    this._initConvolverNode(); 
9232
9233
9234    this.input.gain.value = 0.5; 
9235
9236    this._seconds = 3;
9237    this._decay = 2;
9238    this._reverse = false;
9239
9240    this._buildImpulse();
9241  };
9242
9243  p5.Reverb.prototype = Object.create(Effect.prototype);
9244
9245  p5.Reverb.prototype._initConvolverNode = function () {
9246    this.convolverNode = this.ac.createConvolver();
9247    this.input.connect(this.convolverNode);
9248    this.convolverNode.connect(this.wet);
9249  };
9250
9251  p5.Reverb.prototype._teardownConvolverNode = function () {
9252    if (this.convolverNode) {
9253      this.convolverNode.disconnect();
9254      delete this.convolverNode;
9255    }
9256  };
9257
9258  p5.Reverb.prototype._setBuffer = function (audioBuffer) {
9259    this._teardownConvolverNode();
9260
9261    this._initConvolverNode();
9262
9263    this.convolverNode.buffer = audioBuffer;
9264  };
9265  /**
9266   *  Connect a source to the reverb, and assign reverb parameters.
9267   *
9268   *  @method  process
9269   *  @for p5.Reverb
9270   *  @param  {Object} src     p5.sound / Web Audio object with a sound
9271   *                           output.
9272   *  @param  {Number} [seconds] Duration of the reverb, in seconds.
9273   *                           Min: 0, Max: 10. Defaults to 3.
9274   *  @param  {Number} [decayRate] Percentage of decay with each echo.
9275   *                            Min: 0, Max: 100. Defaults to 2.
9276   *  @param  {Boolean} [reverse] Play the reverb backwards or forwards.
9277   */
9278
9279
9280  p5.Reverb.prototype.process = function (src, seconds, decayRate, reverse) {
9281    src.connect(this.input);
9282    var rebuild = false;
9283
9284    if (seconds) {
9285      this._seconds = seconds;
9286      rebuild = true;
9287    }
9288
9289    if (decayRate) {
9290      this._decay = decayRate;
9291    }
9292
9293    if (reverse) {
9294      this._reverse = reverse;
9295    }
9296
9297    if (rebuild) {
9298      this._buildImpulse();
9299    }
9300  };
9301  /**
9302   *  Set the reverb settings. Similar to .process(), but without
9303   *  assigning a new input.
9304   *
9305   *  @method  set
9306   *  @for p5.Reverb
9307   *  @param  {Number} [seconds] Duration of the reverb, in seconds.
9308   *                           Min: 0, Max: 10. Defaults to 3.
9309   *  @param  {Number} [decayRate] Percentage of decay with each echo.
9310   *                            Min: 0, Max: 100. Defaults to 2.
9311   *  @param  {Boolean} [reverse] Play the reverb backwards or forwards.
9312   */
9313
9314
9315  p5.Reverb.prototype.set = function (seconds, decayRate, reverse) {
9316    var rebuild = false;
9317
9318    if (seconds) {
9319      this._seconds = seconds;
9320      rebuild = true;
9321    }
9322
9323    if (decayRate) {
9324      this._decay = decayRate;
9325    }
9326
9327    if (reverse) {
9328      this._reverse = reverse;
9329    }
9330
9331    if (rebuild) {
9332      this._buildImpulse();
9333    }
9334  }; 
9335
9336  /**
9337   *  Set the output level of the reverb effect.
9338   *
9339   *  @method  amp
9340   *  @for p5.Reverb
9341   *  @param  {Number} volume amplitude between 0 and 1.0
9342   *  @param  {Number} [rampTime] create a fade that lasts rampTime
9343   *  @param  {Number} [timeFromNow] schedule this event to happen
9344   *                                seconds from now
9345   */
9346
9347  /**
9348   *  Send output to a p5.sound or web audio object
9349   *
9350   *  @method  connect
9351   *  @for p5.Reverb
9352   *  @param  {Object} unit
9353   */
9354
9355  /**
9356   *  Disconnect all output.
9357   *
9358   *  @method disconnect
9359   *  @for p5.Reverb
9360   */
9361
9362  /**
9363   *  Inspired by Simple Reverb by Jordan Santell
9364   *  https://github.com/web-audio-components/simple-reverb/blob/master/index.js
9365   *
9366   *  Utility function for building an impulse response
9367   *  based on the module parameters.
9368   *
9369   *  @private
9370   */
9371
9372
9373  p5.Reverb.prototype._buildImpulse = function () {
9374    var rate = this.ac.sampleRate;
9375    var length = rate * this._seconds;
9376    var decay = this._decay;
9377    var impulse = this.ac.createBuffer(2, length, rate);
9378    var impulseL = impulse.getChannelData(0);
9379    var impulseR = impulse.getChannelData(1);
9380    var n, i;
9381
9382    for (i = 0; i < length; i++) {
9383      n = this._reverse ? length - i : i;
9384      impulseL[i] = (Math.random() * 2 - 1) * Math.pow(1 - n / length, decay);
9385      impulseR[i] = (Math.random() * 2 - 1) * Math.pow(1 - n / length, decay);
9386    }
9387
9388    this._setBuffer(impulse);
9389  };
9390
9391  p5.Reverb.prototype.dispose = function () {
9392    Effect.prototype.dispose.apply(this);
9393
9394    this._teardownConvolverNode();
9395  }; 
9396
9397  /**
9398   *  <p>p5.Convolver extends p5.Reverb. It can emulate the sound of real
9399   *  physical spaces through a process called <a href="
9400   *  https://en.wikipedia.org/wiki/Convolution_reverb#Real_space_simulation">
9401   *  convolution</a>.</p>
9402   *
9403   *  <p>Convolution multiplies any audio input by an "impulse response"
9404   *  to simulate the dispersion of sound over time. The impulse response is
9405   *  generated from an audio file that you provide. One way to
9406   *  generate an impulse response is to pop a balloon in a reverberant space
9407   *  and record the echo. Convolution can also be used to experiment with
9408   *  sound.</p>
9409   *
9410   *  <p>Use the method <code>createConvolution(path)</code> to instantiate a
9411   *  p5.Convolver with a path to your impulse response audio file.</p>
9412   *
9413   *  @class p5.Convolver
9414   *  @extends p5.Effect
9415   *  @constructor
9416   *  @param  {String}   path     path to a sound file
9417   *  @param  {Function} [callback] function to call when loading succeeds
9418   *  @param  {Function} [errorCallback] function to call if loading fails.
9419   *                                     This function will receive an error or
9420   *                                     XMLHttpRequest object with information
9421   *                                     about what went wrong.
9422   *  @example
9423   *  <div><code>
9424   *  let cVerb, sound;
9425   *  function preload() {
9426   *    // We have both MP3 and OGG versions of all sound assets
9427   *    soundFormats('ogg', 'mp3');
9428   *
9429   *    // Try replacing 'bx-spring' with other soundfiles like
9430   *    // 'concrete-tunnel' 'small-plate' 'drum' 'beatbox'
9431   *    cVerb = createConvolver('assets/bx-spring.mp3');
9432   *
9433   *    // Try replacing 'Damscray_DancingTiger' with
9434   *    // 'beat', 'doorbell', lucky_dragons_-_power_melody'
9435   *    sound = loadSound('assets/Damscray_DancingTiger.mp3');
9436   *  }
9437   *
9438   *  function setup() {
9439   *    let cnv = createCanvas(100, 100);
9440   *    cnv.mousePressed(playSound);
9441   *    background(220);
9442   *    text('tap to play', 20, 20);
9443   *
9444   *    // disconnect from master output...
9445   *    sound.disconnect();
9446   *
9447   *    // ...and process with cVerb
9448   *    // so that we only hear the convolution
9449   *    cVerb.process(sound);
9450   *  }
9451   *
9452   *  function playSound() {
9453   *    sound.play();
9454   *  }
9455   *  </code></div>
9456   */
9457
9458
9459  p5.Convolver = function (path, callback, errorCallback) {
9460    p5.Reverb.call(this);
9461    /**
9462     *  Internally, the p5.Convolver uses the a
9463     *  <a href="http://www.w3.org/TR/webaudio/#ConvolverNode">
9464     *  Web Audio Convolver Node</a>.
9465     *
9466     *  @property {ConvolverNode} convolverNode
9467     */
9468
9469    this._initConvolverNode(); 
9470
9471
9472    this.input.gain.value = 0.5;
9473
9474    if (path) {
9475      this.impulses = [];
9476
9477      this._loadBuffer(path, callback, errorCallback);
9478    } else {
9479      this._seconds = 3;
9480      this._decay = 2;
9481      this._reverse = false;
9482
9483      this._buildImpulse();
9484    }
9485  };
9486
9487  p5.Convolver.prototype = Object.create(p5.Reverb.prototype);
9488  p5.prototype.registerPreloadMethod('createConvolver', p5.prototype);
9489  /**
9490   *  Create a p5.Convolver. Accepts a path to a soundfile
9491   *  that will be used to generate an impulse response.
9492   *
9493   *  @method  createConvolver
9494   *  @for p5
9495   *  @param  {String}   path     path to a sound file
9496   *  @param  {Function} [callback] function to call if loading is successful.
9497   *                                The object will be passed in as the argument
9498   *                                to the callback function.
9499   *  @param  {Function} [errorCallback] function to call if loading is not successful.
9500   *                                A custom error will be passed in as the argument
9501   *                                to the callback function.
9502   *  @return {p5.Convolver}
9503   *  @example
9504   *  <div><code>
9505   *  let cVerb, sound;
9506   *  function preload() {
9507   *    // We have both MP3 and OGG versions of all sound assets
9508   *    soundFormats('ogg', 'mp3');
9509   *
9510   *    // Try replacing 'bx-spring' with other soundfiles like
9511   *    // 'concrete-tunnel' 'small-plate' 'drum' 'beatbox'
9512   *    cVerb = createConvolver('assets/bx-spring.mp3');
9513   *
9514   *    // Try replacing 'Damscray_DancingTiger' with
9515   *    // 'beat', 'doorbell', lucky_dragons_-_power_melody'
9516   *    sound = loadSound('assets/Damscray_DancingTiger.mp3');
9517   *  }
9518   *
9519   *  function setup() {
9520   *    let cnv = createCanvas(100, 100);
9521   *    cnv.mousePressed(playSound);
9522   *    background(220);
9523   *    text('tap to play', 20, 20);
9524   *
9525   *    // disconnect from master output...
9526   *    sound.disconnect();
9527   *
9528   *    // ...and process with cVerb
9529   *    // so that we only hear the convolution
9530   *    cVerb.process(sound);
9531   *  }
9532   *
9533   *  function playSound() {
9534   *    sound.play();
9535   *  }
9536   *  </code></div>
9537   */
9538
9539  p5.prototype.createConvolver = function (path, callback, errorCallback) {
9540    if (window.location.origin.indexOf('file://') > -1 && window.cordova === 'undefined') {
9541      alert('This sketch may require a server to load external files. Please see http://bit.ly/1qcInwS');
9542    }
9543
9544    var self = this;
9545    var cReverb = new p5.Convolver(path, function (buffer) {
9546      if (typeof callback === 'function') {
9547        callback(buffer);
9548      }
9549
9550      if (typeof self._decrementPreload === 'function') {
9551        self._decrementPreload();
9552      }
9553    }, errorCallback);
9554    cReverb.impulses = [];
9555    return cReverb;
9556  };
9557  /**
9558   *  Private method to load a buffer as an Impulse Response,
9559   *  assign it to the convolverNode, and add to the Array of .impulses.
9560   *
9561   *  @param   {String}   path
9562   *  @param   {Function} callback
9563   *  @param   {Function} errorCallback
9564   *  @private
9565   */
9566
9567
9568  p5.Convolver.prototype._loadBuffer = function (path, callback, errorCallback) {
9569    var path = p5.prototype._checkFileFormats(path);
9570
9571    var self = this;
9572    var errorTrace = new Error().stack;
9573    var ac = p5.prototype.getAudioContext();
9574    var request = new XMLHttpRequest();
9575    request.open('GET', path, true);
9576    request.responseType = 'arraybuffer';
9577
9578    request.onload = function () {
9579      if (request.status === 200) {
9580        ac.decodeAudioData(request.response, function (buff) {
9581          var buffer = {};
9582          var chunks = path.split('/');
9583          buffer.name = chunks[chunks.length - 1];
9584          buffer.audioBuffer = buff;
9585          self.impulses.push(buffer);
9586
9587          self._setBuffer(buffer.audioBuffer);
9588
9589          if (callback) {
9590            callback(buffer);
9591          }
9592        }, 
9593        function () {
9594          var err = new CustomError('decodeAudioData', errorTrace, self.url);
9595          var msg = 'AudioContext error at decodeAudioData for ' + self.url;
9596
9597          if (errorCallback) {
9598            err.msg = msg;
9599            errorCallback(err);
9600          } else {
9601            console.error(msg + '\n The error stack trace includes: \n' + err.stack);
9602          }
9603        });
9604      } 
9605      else {
9606          var err = new CustomError('loadConvolver', errorTrace, self.url);
9607          var msg = 'Unable to load ' + self.url + '. The request status was: ' + request.status + ' (' + request.statusText + ')';
9608
9609          if (errorCallback) {
9610            err.message = msg;
9611            errorCallback(err);
9612          } else {
9613            console.error(msg + '\n The error stack trace includes: \n' + err.stack);
9614          }
9615        }
9616    }; 
9617
9618
9619    request.onerror = function () {
9620      var err = new CustomError('loadConvolver', errorTrace, self.url);
9621      var msg = 'There was no response from the server at ' + self.url + '. Check the url and internet connectivity.';
9622
9623      if (errorCallback) {
9624        err.message = msg;
9625        errorCallback(err);
9626      } else {
9627        console.error(msg + '\n The error stack trace includes: \n' + err.stack);
9628      }
9629    };
9630
9631    request.send();
9632  };
9633
9634  p5.Convolver.prototype.set = null;
9635  /**
9636   *  Connect a source to the convolver.
9637   *
9638   *  @method  process
9639   *  @for p5.Convolver
9640   *  @param  {Object} src     p5.sound / Web Audio object with a sound
9641   *                           output.
9642   *  @example
9643   *  <div><code>
9644   *  let cVerb, sound;
9645   *  function preload() {
9646   *    // We have both MP3 and OGG versions of all sound assets
9647   *    soundFormats('ogg', 'mp3');
9648   *
9649   *    // Try replacing 'bx-spring' with other soundfiles like
9650   *    // 'concrete-tunnel' 'small-plate' 'drum' 'beatbox'
9651   *    cVerb = createConvolver('assets/bx-spring.mp3');
9652   *
9653   *    // Try replacing 'Damscray_DancingTiger' with
9654   *    // 'beat', 'doorbell', lucky_dragons_-_power_melody'
9655   *    sound = loadSound('assets/Damscray_DancingTiger.mp3');
9656   *  }
9657   *
9658   *  function setup() {
9659   *    let cnv = createCanvas(100, 100);
9660   *    cnv.mousePressed(playSound);
9661   *    background(220);
9662   *    text('tap to play', 20, 20);
9663   *
9664   *    // disconnect from master output...
9665   *    sound.disconnect();
9666   *
9667   *    // ...and process with cVerb
9668   *    // so that we only hear the convolution
9669   *    cVerb.process(sound);
9670   *  }
9671   *
9672   *  function playSound() {
9673   *    sound.play();
9674   *  }
9675   *
9676   *  </code></div>
9677   */
9678
9679  p5.Convolver.prototype.process = function (src) {
9680    src.connect(this.input);
9681  };
9682  /**
9683   *  If you load multiple impulse files using the .addImpulse method,
9684   *  they will be stored as Objects in this Array. Toggle between them
9685   *  with the <code>toggleImpulse(id)</code> method.
9686   *
9687   *  @property {Array} impulses
9688   *  @for p5.Convolver
9689   */
9690
9691
9692  p5.Convolver.prototype.impulses = [];
9693  /**
9694   *  Load and assign a new Impulse Response to the p5.Convolver.
9695   *  The impulse is added to the <code>.impulses</code> array. Previous
9696   *  impulses can be accessed with the <code>.toggleImpulse(id)</code>
9697   *  method.
9698   *
9699   *  @method  addImpulse
9700   *  @for p5.Convolver
9701   *  @param  {String}   path     path to a sound file
9702   *  @param  {Function} callback function (optional)
9703   *  @param  {Function} errorCallback function (optional)
9704   */
9705
9706  p5.Convolver.prototype.addImpulse = function (path, callback, errorCallback) {
9707    if (window.location.origin.indexOf('file://') > -1 && window.cordova === 'undefined') {
9708      alert('This sketch may require a server to load external files. Please see http://bit.ly/1qcInwS');
9709    }
9710
9711    this._loadBuffer(path, callback, errorCallback);
9712  };
9713  /**
9714   *  Similar to .addImpulse, except that the <code>.impulses</code>
9715   *  Array is reset to save memory. A new <code>.impulses</code>
9716   *  array is created with this impulse as the only item.
9717   *
9718   *  @method  resetImpulse
9719   *  @for p5.Convolver
9720   *  @param  {String}   path     path to a sound file
9721   *  @param  {Function} callback function (optional)
9722   *  @param  {Function} errorCallback function (optional)
9723   */
9724
9725
9726  p5.Convolver.prototype.resetImpulse = function (path, callback, errorCallback) {
9727    if (window.location.origin.indexOf('file://') > -1 && window.cordova === 'undefined') {
9728      alert('This sketch may require a server to load external files. Please see http://bit.ly/1qcInwS');
9729    }
9730
9731    this.impulses = [];
9732
9733    this._loadBuffer(path, callback, errorCallback);
9734  };
9735  /**
9736   *  If you have used <code>.addImpulse()</code> to add multiple impulses
9737   *  to a p5.Convolver, then you can use this method to toggle between
9738   *  the items in the <code>.impulses</code> Array. Accepts a parameter
9739   *  to identify which impulse you wish to use, identified either by its
9740   *  original filename (String) or by its position in the <code>.impulses
9741   *  </code> Array (Number).<br/>
9742   *  You can access the objects in the .impulses Array directly. Each
9743   *  Object has two attributes: an <code>.audioBuffer</code> (type:
9744   *  Web Audio <a href="
9745   *  http://webaudio.github.io/web-audio-api/#the-audiobuffer-interface">
9746   *  AudioBuffer)</a> and a <code>.name</code>, a String that corresponds
9747   *  with the original filename.
9748   *
9749   *  @method toggleImpulse
9750   *  @for p5.Convolver
9751   *  @param {String|Number} id Identify the impulse by its original filename
9752   *                            (String), or by its position in the
9753   *                            <code>.impulses</code> Array (Number).
9754   */
9755
9756
9757  p5.Convolver.prototype.toggleImpulse = function (id) {
9758    if (typeof id === 'number' && id < this.impulses.length) {
9759      this._setBuffer(this.impulses[id].audioBuffer);
9760    }
9761
9762    if (typeof id === 'string') {
9763      for (var i = 0; i < this.impulses.length; i++) {
9764        if (this.impulses[i].name === id) {
9765          this._setBuffer(this.impulses[i].audioBuffer);
9766
9767          break;
9768        }
9769      }
9770    }
9771  };
9772
9773  p5.Convolver.prototype.dispose = function () {
9774    p5.Reverb.prototype.dispose.apply(this); 
9775
9776    for (var i in this.impulses) {
9777      if (this.impulses[i]) {
9778        this.impulses[i] = null;
9779      }
9780    }
9781  };
9782}).call(exports, __webpack_require__, exports, module),
9783				__WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));
9784
9785 }),
9786 (function(module, exports, __webpack_require__) {
9787
9788"use strict";
9789var __WEBPACK_AMD_DEFINE_RESULT__;
9790
9791!(__WEBPACK_AMD_DEFINE_RESULT__ = (function (require) {
9792  var p5sound = __webpack_require__(1); 
9793
9794
9795  var Clock = __webpack_require__(27);
9796
9797  p5.Metro = function () {
9798    this.clock = new Clock({
9799      'callback': this.ontick.bind(this)
9800    });
9801    this.syncedParts = [];
9802    this.bpm = 120; 
9803
9804    this._init();
9805
9806    this.prevTick = 0;
9807    this.tatumTime = 0;
9808
9809    this.tickCallback = function () {};
9810  };
9811
9812  p5.Metro.prototype.ontick = function (tickTime) {
9813    var elapsedTime = tickTime - this.prevTick;
9814    var secondsFromNow = tickTime - p5sound.audiocontext.currentTime;
9815
9816    if (elapsedTime - this.tatumTime <= -0.02) {
9817      return;
9818    } else {
9819      this.prevTick = tickTime; 
9820
9821      var self = this;
9822      this.syncedParts.forEach(function (thisPart) {
9823        if (!thisPart.isPlaying) return;
9824        thisPart.incrementStep(secondsFromNow); 
9825
9826        thisPart.phrases.forEach(function (thisPhrase) {
9827          var phraseArray = thisPhrase.sequence;
9828          var bNum = self.metroTicks % phraseArray.length;
9829
9830          if (phraseArray[bNum] !== 0 && (self.metroTicks < phraseArray.length || !thisPhrase.looping)) {
9831            thisPhrase.callback(secondsFromNow, phraseArray[bNum]);
9832          }
9833        });
9834      });
9835      this.metroTicks += 1;
9836      this.tickCallback(secondsFromNow);
9837    }
9838  };
9839
9840  p5.Metro.prototype.setBPM = function (bpm, rampTime) {
9841    var beatTime = 60 / (bpm * this.tatums);
9842    var now = p5sound.audiocontext.currentTime;
9843    this.tatumTime = beatTime;
9844    var rampTime = rampTime || 0;
9845    this.clock.frequency.setValueAtTime(this.clock.frequency.value, now);
9846    this.clock.frequency.linearRampToValueAtTime(bpm, now + rampTime);
9847    this.bpm = bpm;
9848  };
9849
9850  p5.Metro.prototype.getBPM = function () {
9851    return this.clock.getRate() / this.tatums * 60;
9852  };
9853
9854  p5.Metro.prototype._init = function () {
9855    this.metroTicks = 0; 
9856  }; 
9857
9858
9859  p5.Metro.prototype.resetSync = function (part) {
9860    this.syncedParts = [part];
9861  }; 
9862
9863
9864  p5.Metro.prototype.pushSync = function (part) {
9865    this.syncedParts.push(part);
9866  };
9867
9868  p5.Metro.prototype.start = function (timeFromNow) {
9869    var t = timeFromNow || 0;
9870    var now = p5sound.audiocontext.currentTime;
9871    this.clock.start(now + t);
9872    this.setBPM(this.bpm);
9873  };
9874
9875  p5.Metro.prototype.stop = function (timeFromNow) {
9876    var t = timeFromNow || 0;
9877    var now = p5sound.audiocontext.currentTime;
9878    this.clock.stop(now + t);
9879  };
9880
9881  p5.Metro.prototype.beatLength = function (tatums) {
9882    this.tatums = 1 / tatums / 4; 
9883  };
9884}).call(exports, __webpack_require__, exports, module),
9885				__WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));
9886
9887 }),
9888 (function(module, exports, __webpack_require__) {
9889
9890var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;!(__WEBPACK_AMD_DEFINE_ARRAY__ = [__webpack_require__(0),__webpack_require__(24),__webpack_require__(8)], __WEBPACK_AMD_DEFINE_RESULT__ = (function(t){"use strict";return t.TimelineState=function(e){t.Timeline.call(this),this._initial=e},t.extend(t.TimelineState,t.Timeline),t.TimelineState.prototype.getValueAtTime=function(e){var t=this.get(e);return null!==t?t.state:this._initial},t.TimelineState.prototype.setStateAtTime=function(e,t){this.add({state:e,time:t})},t.TimelineState}).apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__),
9891				__WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));
9892
9893 }),
9894 (function(module, exports, __webpack_require__) {
9895
9896"use strict";
9897var __WEBPACK_AMD_DEFINE_RESULT__;
9898
9899!(__WEBPACK_AMD_DEFINE_RESULT__ = (function (require) {
9900  var p5sound = __webpack_require__(1);
9901
9902  var BPM = 120;
9903  /**
9904   *  Set the global tempo, in beats per minute, for all
9905   *  p5.Parts. This method will impact all active p5.Parts.
9906   *
9907   *  @method setBPM
9908   *  @for p5
9909   *  @param {Number} BPM      Beats Per Minute
9910   *  @param {Number} rampTime Seconds from now
9911   */
9912
9913  p5.prototype.setBPM = function (bpm, rampTime) {
9914    BPM = bpm;
9915
9916    for (var i in p5sound.parts) {
9917      if (p5sound.parts[i]) {
9918        p5sound.parts[i].setBPM(bpm, rampTime);
9919      }
9920    }
9921  };
9922  /**
9923   *  <p>A phrase is a pattern of musical events over time, i.e.
9924   *  a series of notes and rests.</p>
9925   *
9926   *  <p>Phrases must be added to a p5.Part for playback, and
9927   *  each part can play multiple phrases at the same time.
9928   *  For example, one Phrase might be a kick drum, another
9929   *  could be a snare, and another could be the bassline.</p>
9930   *
9931   *  <p>The first parameter is a name so that the phrase can be
9932   *  modified or deleted later. The callback is a a function that
9933   *  this phrase will call at every step—for example it might be
9934   *  called <code>playNote(value){}</code>. The array determines
9935   *  which value is passed into the callback at each step of the
9936   *  phrase. It can be numbers, an object with multiple numbers,
9937   *  or a zero (0) indicates a rest so the callback won't be called).</p>
9938   *
9939   *  @class p5.Phrase
9940   *  @constructor
9941   *  @param {String}   name     Name so that you can access the Phrase.
9942   *  @param {Function} callback The name of a function that this phrase
9943   *                             will call. Typically it will play a sound,
9944   *                             and accept two parameters: a time at which
9945   *                             to play the sound (in seconds from now),
9946   *                             and a value from the sequence array. The
9947   *                             time should be passed into the play() or
9948   *                             start() method to ensure precision.
9949   *  @param {Array}   sequence    Array of values to pass into the callback
9950   *                            at each step of the phrase.
9951   *  @example
9952   *  <div><code>
9953   *  let mySound, myPhrase, myPart;
9954   *  let pattern = [1,0,0,2,0,2,0,0];
9955   *
9956   *  function preload() {
9957   *    mySound = loadSound('assets/beatbox.mp3');
9958   *  }
9959   *
9960   *  function setup() {
9961   *    let cnv = createCanvas(100, 100);
9962   *    cnv.mousePressed(playMyPart);
9963   *    background(220);
9964   *    text('tap to play', width/2, height/2);
9965   *    textAlign(CENTER, CENTER);
9966   *
9967   *    myPhrase = new p5.Phrase('bbox', onEachStep, pattern);
9968   *    myPart = new p5.Part();
9969   *    myPart.addPhrase(myPhrase);
9970   *    myPart.setBPM(60);
9971   *  }
9972   *
9973   *  function onEachStep(time, playbackRate) {
9974   *    mySound.rate(playbackRate);
9975   *    mySound.play(time);
9976   *  }
9977   *
9978   *  function playMyPart() {
9979   *    userStartAudio();
9980   *    myPart.start();
9981   *  }
9982   *  </code></div>
9983   */
9984
9985
9986  p5.Phrase = function (name, callback, sequence) {
9987    this.phraseStep = 0;
9988    this.name = name;
9989    this.callback = callback;
9990    /**
9991     * Array of values to pass into the callback
9992     * at each step of the phrase. Depending on the callback
9993     * function's requirements, these values may be numbers,
9994     * strings, or an object with multiple parameters.
9995     * Zero (0) indicates a rest.
9996     *
9997     * @property {Array} sequence
9998     */
9999
10000    this.sequence = sequence;
10001  };
10002  /**
10003   *  <p>A p5.Part plays back one or more p5.Phrases. Instantiate a part
10004   *  with steps and tatums. By default, each step represents a 1/16th note.</p>
10005   *
10006   *  <p>See p5.Phrase for more about musical timing.</p>
10007   *
10008   *  @class p5.Part
10009   *  @constructor
10010   *  @param {Number} [steps]   Steps in the part
10011   *  @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)
10012   *  @example
10013   *  <div><code>
10014   *  let box, drum, myPart;
10015   *  let boxPat = [1,0,0,2,0,2,0,0];
10016   *  let drumPat = [0,1,1,0,2,0,1,0];
10017   *
10018   *  function preload() {
10019   *    box = loadSound('assets/beatbox.mp3');
10020   *    drum = loadSound('assets/drum.mp3');
10021   *  }
10022   *
10023   *  function setup() {
10024   *    let cnv = createCanvas(100, 100);
10025   *    cnv.mousePressed(playMyPart);
10026   *    background(220);
10027   *    textAlign(CENTER, CENTER);
10028   *    text('tap to play', width/2, height/2);
10029   *
10030   *    let boxPhrase = new p5.Phrase('box', playBox, boxPat);
10031   *    let drumPhrase = new p5.Phrase('drum', playDrum, drumPat);
10032   *    myPart = new p5.Part();
10033   *    myPart.addPhrase(boxPhrase);
10034   *    myPart.addPhrase(drumPhrase);
10035   *    myPart.setBPM(60);
10036   *  }
10037   *
10038   *  function playBox(time, playbackRate) {
10039   *    box.rate(playbackRate);
10040   *    box.play(time);
10041   *  }
10042   *
10043   *  function playDrum(time, playbackRate) {
10044   *    drum.rate(playbackRate);
10045   *    drum.play(time);
10046   *  }
10047   *
10048   *  function playMyPart() {
10049   *    userStartAudio();
10050   *
10051   *    myPart.start();
10052   *  }
10053   *  </code></div>
10054   */
10055
10056
10057  p5.Part = function (steps, bLength) {
10058    this.length = steps || 0; 
10059
10060    this.partStep = 0;
10061    this.phrases = [];
10062    this.isPlaying = false;
10063    this.noLoop();
10064    this.tatums = bLength || 0.0625; 
10065
10066    this.metro = new p5.Metro();
10067
10068    this.metro._init();
10069
10070    this.metro.beatLength(this.tatums);
10071    this.metro.setBPM(BPM);
10072    p5sound.parts.push(this);
10073
10074    this.callback = function () {};
10075  };
10076  /**
10077   *  Set the tempo of this part, in Beats Per Minute.
10078   *
10079   *  @method  setBPM
10080   *  @for p5.Part
10081   *  @param {Number} BPM      Beats Per Minute
10082   *  @param {Number} [rampTime] Seconds from now
10083   */
10084
10085
10086  p5.Part.prototype.setBPM = function (tempo, rampTime) {
10087    this.metro.setBPM(tempo, rampTime);
10088  };
10089  /**
10090   *  Returns the tempo, in Beats Per Minute, of this part.
10091   *
10092   *  @method getBPM
10093   *  @for p5.Part
10094   *  @return {Number}
10095   */
10096
10097
10098  p5.Part.prototype.getBPM = function () {
10099    return this.metro.getBPM();
10100  };
10101  /**
10102   *  Start playback of this part. It will play
10103   *  through all of its phrases at a speed
10104   *  determined by setBPM.
10105   *
10106   *  @method  start
10107   *  @for p5.Part
10108   *  @param  {Number} [time] seconds from now
10109   */
10110
10111
10112  p5.Part.prototype.start = function (time) {
10113    if (!this.isPlaying) {
10114      this.isPlaying = true;
10115      this.metro.resetSync(this);
10116      var t = time || 0;
10117      this.metro.start(t);
10118    }
10119  };
10120  /**
10121   *  Loop playback of this part. It will begin
10122   *  looping through all of its phrases at a speed
10123   *  determined by setBPM.
10124   *
10125   *  @method  loop
10126   *  @for p5.Part
10127   *  @param  {Number} [time] seconds from now
10128   */
10129
10130
10131  p5.Part.prototype.loop = function (time) {
10132    this.looping = true; 
10133
10134    this.onended = function () {
10135      this.partStep = 0;
10136    };
10137
10138    var t = time || 0;
10139    this.start(t);
10140  };
10141  /**
10142   *  Tell the part to stop looping.
10143   *
10144   *  @method  noLoop
10145   *  @for p5.Part
10146   */
10147
10148
10149  p5.Part.prototype.noLoop = function () {
10150    this.looping = false; 
10151
10152    this.onended = function () {
10153      this.stop();
10154    };
10155  };
10156  /**
10157   *  Stop the part and cue it to step 0. Playback will resume from the begining of the Part when it is played again.
10158   *
10159   *  @method  stop
10160   *  @for p5.Part
10161   *  @param  {Number} [time] seconds from now
10162   */
10163
10164
10165  p5.Part.prototype.stop = function (time) {
10166    this.partStep = 0;
10167    this.pause(time);
10168  };
10169  /**
10170   *  Pause the part. Playback will resume
10171   *  from the current step.
10172   *
10173   *  @method  pause
10174   *  @for p5.Part
10175   *  @param  {Number} time seconds from now
10176   */
10177
10178
10179  p5.Part.prototype.pause = function (time) {
10180    this.isPlaying = false;
10181    var t = time || 0;
10182    this.metro.stop(t);
10183  };
10184  /**
10185   *  Add a p5.Phrase to this Part.
10186   *
10187   *  @method  addPhrase
10188   *  @for p5.Part
10189   *  @param {p5.Phrase}   phrase   reference to a p5.Phrase
10190   */
10191
10192
10193  p5.Part.prototype.addPhrase = function (name, callback, array) {
10194    var p;
10195
10196    if (arguments.length === 3) {
10197      p = new p5.Phrase(name, callback, array);
10198    } else if (arguments[0] instanceof p5.Phrase) {
10199      p = arguments[0];
10200    } else {
10201      throw 'invalid input. addPhrase accepts name, callback, array or a p5.Phrase';
10202    }
10203
10204    this.phrases.push(p); 
10205
10206    if (p.sequence.length > this.length) {
10207      this.length = p.sequence.length;
10208    }
10209  };
10210  /**
10211   *  Remove a phrase from this part, based on the name it was
10212   *  given when it was created.
10213   *
10214   *  @method  removePhrase
10215   *  @for p5.Part
10216   *  @param  {String} phraseName
10217   */
10218
10219
10220  p5.Part.prototype.removePhrase = function (name) {
10221    for (var i in this.phrases) {
10222      if (this.phrases[i].name === name) {
10223        this.phrases.splice(i, 1);
10224      }
10225    }
10226  };
10227  /**
10228   *  Get a phrase from this part, based on the name it was
10229   *  given when it was created. Now you can modify its array.
10230   *
10231   *  @method  getPhrase
10232   *  @for p5.Part
10233   *  @param  {String} phraseName
10234   */
10235
10236
10237  p5.Part.prototype.getPhrase = function (name) {
10238    for (var i in this.phrases) {
10239      if (this.phrases[i].name === name) {
10240        return this.phrases[i];
10241      }
10242    }
10243  };
10244  /**
10245   *  Find all sequences with the specified name, and replace their patterns with the specified array.
10246   *
10247   *  @method  replaceSequence
10248   *  @for p5.Part
10249   *  @param  {String} phraseName
10250   *  @param  {Array} sequence  Array of values to pass into the callback
10251   *                            at each step of the phrase.
10252   */
10253
10254
10255  p5.Part.prototype.replaceSequence = function (name, array) {
10256    for (var i in this.phrases) {
10257      if (this.phrases[i].name === name) {
10258        this.phrases[i].sequence = array;
10259      }
10260    }
10261  };
10262
10263  p5.Part.prototype.incrementStep = function (time) {
10264    if (this.partStep < this.length - 1) {
10265      this.callback(time);
10266      this.partStep += 1;
10267    } else {
10268      if (!this.looping && this.partStep === this.length - 1) {
10269        this.onended();
10270      }
10271    }
10272  };
10273  /**
10274   *  Set the function that will be called at every step. This will clear the previous function.
10275   *
10276   *  @method onStep
10277   *  @for p5.Part
10278   *  @param  {Function} callback The name of the callback
10279   *                              you want to fire
10280   *                              on every beat/tatum.
10281   */
10282
10283
10284  p5.Part.prototype.onStep = function (callback) {
10285    this.callback = callback;
10286  }; 
10287
10288  /**
10289   *  A Score consists of a series of Parts. The parts will
10290   *  be played back in order. For example, you could have an
10291   *  A part, a B part, and a C part, and play them back in this order
10292   *  <code>new p5.Score(a, a, b, a, c)</code>
10293   *
10294   *  @class p5.Score
10295   *  @constructor
10296   *  @param {p5.Part} [...parts] One or multiple parts, to be played in sequence.
10297   */
10298
10299
10300  p5.Score = function () {
10301    this.parts = [];
10302    this.currentPart = 0;
10303    var thisScore = this;
10304
10305    for (var i in arguments) {
10306      if (arguments[i] && this.parts[i]) {
10307        this.parts[i] = arguments[i];
10308        this.parts[i].nextPart = this.parts[i + 1];
10309
10310        this.parts[i].onended = function () {
10311          thisScore.resetPart(i);
10312          playNextPart(thisScore);
10313        };
10314      }
10315    }
10316
10317    this.looping = false;
10318  };
10319
10320  p5.Score.prototype.onended = function () {
10321    if (this.looping) {
10322      this.parts[0].start();
10323    } else {
10324      this.parts[this.parts.length - 1].onended = function () {
10325        this.stop();
10326        this.resetParts();
10327      };
10328    }
10329
10330    this.currentPart = 0;
10331  };
10332  /**
10333   *  Start playback of the score.
10334   *
10335   *  @method  start
10336   *  @for p5.Score
10337   */
10338
10339
10340  p5.Score.prototype.start = function () {
10341    this.parts[this.currentPart].start();
10342    this.scoreStep = 0;
10343  };
10344  /**
10345   *  Stop playback of the score.
10346   *
10347   *  @method  stop
10348   *  @for p5.Score
10349   */
10350
10351
10352  p5.Score.prototype.stop = function () {
10353    this.parts[this.currentPart].stop();
10354    this.currentPart = 0;
10355    this.scoreStep = 0;
10356  };
10357  /**
10358   *  Pause playback of the score.
10359   *
10360   *  @method  pause
10361   *  @for p5.Score
10362   */
10363
10364
10365  p5.Score.prototype.pause = function () {
10366    this.parts[this.currentPart].stop();
10367  };
10368  /**
10369   *  Loop playback of the score.
10370   *
10371   *  @method  loop
10372   *  @for p5.Score
10373   */
10374
10375
10376  p5.Score.prototype.loop = function () {
10377    this.looping = true;
10378    this.start();
10379  };
10380  /**
10381   *  Stop looping playback of the score. If it
10382   *  is currently playing, this will go into effect
10383   *  after the current round of playback completes.
10384   *
10385   *  @method  noLoop
10386   *  @for p5.Score
10387   */
10388
10389
10390  p5.Score.prototype.noLoop = function () {
10391    this.looping = false;
10392  };
10393
10394  p5.Score.prototype.resetParts = function () {
10395    var self = this;
10396    this.parts.forEach(function (part) {
10397      self.resetParts[part];
10398    });
10399  };
10400
10401  p5.Score.prototype.resetPart = function (i) {
10402    this.parts[i].stop();
10403    this.parts[i].partStep = 0;
10404
10405    for (var p in this.parts[i].phrases) {
10406      if (this.parts[i]) {
10407        this.parts[i].phrases[p].phraseStep = 0;
10408      }
10409    }
10410  };
10411  /**
10412   *  Set the tempo for all parts in the score
10413   *
10414   *  @method setBPM
10415   *  @for p5.Score
10416   *  @param {Number} BPM      Beats Per Minute
10417   *  @param {Number} rampTime Seconds from now
10418   */
10419
10420
10421  p5.Score.prototype.setBPM = function (bpm, rampTime) {
10422    for (var i in this.parts) {
10423      if (this.parts[i]) {
10424        this.parts[i].setBPM(bpm, rampTime);
10425      }
10426    }
10427  };
10428
10429  function playNextPart(aScore) {
10430    aScore.currentPart++;
10431
10432    if (aScore.currentPart >= aScore.parts.length) {
10433      aScore.scoreStep = 0;
10434      aScore.onended();
10435    } else {
10436      aScore.scoreStep = 0;
10437      aScore.parts[aScore.currentPart - 1].stop();
10438      aScore.parts[aScore.currentPart].start();
10439    }
10440  }
10441}).call(exports, __webpack_require__, exports, module),
10442				__WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));
10443
10444 }),
10445 (function(module, exports, __webpack_require__) {
10446
10447"use strict";
10448var __WEBPACK_AMD_DEFINE_RESULT__;
10449
10450!(__WEBPACK_AMD_DEFINE_RESULT__ = (function (require) {
10451  var p5sound = __webpack_require__(1);
10452
10453  var Clock = __webpack_require__(27);
10454  /**
10455   * SoundLoop
10456   *
10457   * @class p5.SoundLoop
10458   * @constructor
10459   *
10460   * @param {Function} callback this function will be called on each iteration of theloop
10461   * @param {Number|String} [interval] amount of time (if a number) or beats (if a string, following <a href = "https://github.com/Tonejs/Tone.js/wiki/Time">Tone.Time</a> convention) for each iteration of the loop. Defaults to 1 second.
10462   *
10463   * @example
10464   * <div><code>
10465   *  let synth, soundLoop;
10466   *  let notePattern = [60, 62, 64, 67, 69, 72];
10467   *
10468   *  function setup() {
10469   *    let cnv = createCanvas(100, 100);
10470   *    cnv.mousePressed(canvasPressed);
10471   *    colorMode(HSB);
10472   *    background(0, 0, 86);
10473   *    text('tap to start/stop', 10, 20);
10474   *
10475   *    //the looper's callback is passed the timeFromNow
10476   *    //this value should be used as a reference point from
10477   *    //which to schedule sounds
10478   *    let intervalInSeconds = 0.2;
10479   *    soundLoop = new p5.SoundLoop(onSoundLoop, intervalInSeconds);
10480   *
10481   *    synth = new p5.MonoSynth();
10482   * }
10483   *
10484   * function canvasPressed() {
10485   *   // ensure audio is enabled
10486   *   userStartAudio();
10487   *
10488   *   if (soundLoop.isPlaying) {
10489   *     soundLoop.stop();
10490   *   } else {
10491   *     // start the loop
10492   *     soundLoop.start();
10493   *   }
10494   * }
10495   *
10496   * function onSoundLoop(timeFromNow) {
10497   *   let noteIndex = (soundLoop.iterations - 1) % notePattern.length;
10498   *   let note = midiToFreq(notePattern[noteIndex]);
10499   *   synth.play(note, 0.5, timeFromNow);
10500   *   background(noteIndex * 360 / notePattern.length, 50, 100);
10501   * }
10502   * </code></div>
10503   */
10504
10505
10506  p5.SoundLoop = function (callback, interval) {
10507    this.callback = callback;
10508    /**
10509     * musicalTimeMode uses <a href = "https://github.com/Tonejs/Tone.js/wiki/Time">Tone.Time</a> convention
10510     * true if string, false if number
10511     * @property {Boolean} musicalTimeMode
10512     */
10513
10514    this.musicalTimeMode = typeof this._interval === 'number' ? false : true;
10515    this._interval = interval || 1;
10516    /**
10517     * musicalTimeMode variables
10518     * modify these only when the interval is specified in musicalTime format as a string
10519     */
10520
10521    this._timeSignature = 4;
10522    this._bpm = 60;
10523    this.isPlaying = false;
10524    /**
10525     * Set a limit to the number of loops to play. defaults to Infinity
10526     * @property {Number} maxIterations
10527     */
10528
10529    this.maxIterations = Infinity;
10530    var self = this;
10531    this.clock = new Clock({
10532      'callback': function callback(time) {
10533        var timeFromNow = time - p5sound.audiocontext.currentTime;
10534        /**
10535         * Do not initiate the callback if timeFromNow is < 0
10536         * This ususually occurs for a few milliseconds when the page
10537         * is not fully loaded
10538         *
10539         * The callback should only be called until maxIterations is reached
10540         */
10541
10542        if (timeFromNow > 0 && self.iterations <= self.maxIterations) {
10543          self.callback(timeFromNow);
10544        }
10545      },
10546      'frequency': this._calcFreq()
10547    });
10548  };
10549  /**
10550   * Start the loop
10551   * @method  start
10552   * @for p5.SoundLoop
10553   * @param  {Number} [timeFromNow] schedule a starting time
10554   */
10555
10556
10557  p5.SoundLoop.prototype.start = function (timeFromNow) {
10558    var t = timeFromNow || 0;
10559    var now = p5sound.audiocontext.currentTime;
10560
10561    if (!this.isPlaying) {
10562      this.clock.start(now + t);
10563      this.isPlaying = true;
10564    }
10565  };
10566  /**
10567   * Stop the loop
10568   * @method  stop
10569   * @for p5.SoundLoop
10570   * @param  {Number} [timeFromNow] schedule a stopping time
10571   */
10572
10573
10574  p5.SoundLoop.prototype.stop = function (timeFromNow) {
10575    var t = timeFromNow || 0;
10576    var now = p5sound.audiocontext.currentTime;
10577
10578    if (this.isPlaying) {
10579      this.clock.stop(now + t);
10580      this.isPlaying = false;
10581    }
10582  };
10583  /**
10584   * Pause the loop
10585   * @method pause
10586   * @for p5.SoundLoop
10587   * @param  {Number} [timeFromNow] schedule a pausing time
10588   */
10589
10590
10591  p5.SoundLoop.prototype.pause = function (timeFromNow) {
10592    var t = timeFromNow || 0;
10593    var now = p5sound.audiocontext.currentTime;
10594
10595    if (this.isPlaying) {
10596      this.clock.pause(now + t);
10597      this.isPlaying = false;
10598    }
10599  };
10600  /**
10601   * Synchronize loops. Use this method to start two more more loops in synchronization
10602   * or to start a loop in synchronization with a loop that is already playing
10603   * This method will schedule the implicit loop in sync with the explicit master loop
10604   * i.e. loopToStart.syncedStart(loopToSyncWith)
10605   *
10606   * @method  syncedStart
10607   * @for p5.SoundLoop
10608   * @param  {Object} otherLoop   a p5.SoundLoop to sync with
10609   * @param  {Number} [timeFromNow] Start the loops in sync after timeFromNow seconds
10610   */
10611
10612
10613  p5.SoundLoop.prototype.syncedStart = function (otherLoop, timeFromNow) {
10614    var t = timeFromNow || 0;
10615    var now = p5sound.audiocontext.currentTime;
10616
10617    if (!otherLoop.isPlaying) {
10618      otherLoop.clock.start(now + t);
10619      otherLoop.isPlaying = true;
10620      this.clock.start(now + t);
10621      this.isPlaying = true;
10622    } else if (otherLoop.isPlaying) {
10623      var time = otherLoop.clock._nextTick - p5sound.audiocontext.currentTime;
10624      this.clock.start(now + time);
10625      this.isPlaying = true;
10626    }
10627  };
10628  /**
10629   * Updates frequency value, reflected in next callback
10630   * @private
10631   * @for p5.SoundLoop
10632   * @method  _update
10633   */
10634
10635
10636  p5.SoundLoop.prototype._update = function () {
10637    this.clock.frequency.value = this._calcFreq();
10638  };
10639  /**
10640   * Calculate the frequency of the clock's callback based on bpm, interval, and timesignature
10641   * @private
10642   * @for p5.SoundLoop
10643   * @method  _calcFreq
10644   * @return {Number} new clock frequency value
10645   */
10646
10647
10648  p5.SoundLoop.prototype._calcFreq = function () {
10649    if (typeof this._interval === 'number') {
10650      this.musicalTimeMode = false;
10651      return 1 / this._interval;
10652    } 
10653    else if (typeof this._interval === 'string') {
10654        this.musicalTimeMode = true;
10655        return this._bpm / 60 / this._convertNotation(this._interval) * (this._timeSignature / 4);
10656      }
10657  };
10658  /**
10659   * Convert notation from musical time format to seconds
10660   * Uses <a href = "https://github.com/Tonejs/Tone.js/wiki/Time">Tone.Time</a> convention
10661   * @private
10662   * @for p5.SoundLoop
10663   * @method _convertNotation
10664   * @param  {String} value value to be converted
10665   * @return {Number}       converted value in seconds
10666   */
10667
10668
10669  p5.SoundLoop.prototype._convertNotation = function (value) {
10670    var type = value.slice(-1);
10671    value = Number(value.slice(0, -1));
10672
10673    switch (type) {
10674      case 'm':
10675        return this._measure(value);
10676
10677      case 'n':
10678        return this._note(value);
10679
10680      default:
10681        console.warn('Specified interval is not formatted correctly. See Tone.js ' + 'timing reference for more info: https://github.com/Tonejs/Tone.js/wiki/Time');
10682    }
10683  };
10684  /**
10685   * Helper conversion methods of measure and note
10686   * @private
10687   * @for p5.SoundLoop
10688   * @method  _measure
10689   */
10690
10691
10692  p5.SoundLoop.prototype._measure = function (value) {
10693    return value * this._timeSignature;
10694  };
10695  /**
10696   * @private
10697   * @method  _note
10698   * @for p5.SoundLoop
10699   */
10700
10701
10702  p5.SoundLoop.prototype._note = function (value) {
10703    return this._timeSignature / value;
10704  };
10705  /**
10706   * Getters and Setters, setting any paramter will result in a change in the clock's
10707   * frequency, that will be reflected after the next callback
10708   * beats per minute (defaults to 60)
10709   * @property {Number} bpm
10710   * @for p5.SoundLoop
10711   */
10712
10713
10714  Object.defineProperty(p5.SoundLoop.prototype, 'bpm', {
10715    get: function get() {
10716      return this._bpm;
10717    },
10718    set: function set(bpm) {
10719      if (!this.musicalTimeMode) {
10720        console.warn('Changing the BPM in "seconds" mode has no effect. ' + 'BPM is only relevant in musicalTimeMode ' + 'when the interval is specified as a string ' + '("2n", "4n", "1m"...etc)');
10721      }
10722
10723      this._bpm = bpm;
10724
10725      this._update();
10726    }
10727  });
10728  /**
10729   * number of quarter notes in a measure (defaults to 4)
10730   * @property {Number} timeSignature
10731   * @for p5.SoundLoop
10732   */
10733
10734  Object.defineProperty(p5.SoundLoop.prototype, 'timeSignature', {
10735    get: function get() {
10736      return this._timeSignature;
10737    },
10738    set: function set(timeSig) {
10739      if (!this.musicalTimeMode) {
10740        console.warn('Changing the timeSignature in "seconds" mode has no effect. ' + 'BPM is only relevant in musicalTimeMode ' + 'when the interval is specified as a string ' + '("2n", "4n", "1m"...etc)');
10741      }
10742
10743      this._timeSignature = timeSig;
10744
10745      this._update();
10746    }
10747  });
10748  /**
10749   * length of the loops interval
10750   * @property {Number|String} interval
10751   * @for p5.SoundLoop
10752   */
10753
10754  Object.defineProperty(p5.SoundLoop.prototype, 'interval', {
10755    get: function get() {
10756      return this._interval;
10757    },
10758    set: function set(interval) {
10759      this.musicalTimeMode = typeof interval === 'Number' ? false : true;
10760      this._interval = interval;
10761
10762      this._update();
10763    }
10764  });
10765  /**
10766   * how many times the callback has been called so far
10767   * @property {Number} iterations
10768   * @for p5.SoundLoop
10769   * @readonly
10770   */
10771
10772  Object.defineProperty(p5.SoundLoop.prototype, 'iterations', {
10773    get: function get() {
10774      return this.clock.ticks;
10775    }
10776  });
10777  return p5.SoundLoop;
10778}).call(exports, __webpack_require__, exports, module),
10779				__WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));
10780
10781 }),
10782 (function(module, exports, __webpack_require__) {
10783
10784var __WEBPACK_AMD_DEFINE_RESULT__;!(__WEBPACK_AMD_DEFINE_RESULT__ = (function (require) {
10785  'use strict';
10786
10787  var p5sound = __webpack_require__(1);
10788
10789  var Effect = __webpack_require__(4);
10790
10791  var CustomError = __webpack_require__(11);
10792  /**
10793   * Compressor is an audio effect class that performs dynamics compression
10794   * on an audio input source. This is a very commonly used technique in music
10795   * and sound production. Compression creates an overall louder, richer,
10796   * and fuller sound by lowering the volume of louds and raising that of softs.
10797   * Compression can be used to avoid clipping (sound distortion due to
10798   * peaks in volume) and is especially useful when many sounds are played
10799   * at once. Compression can be used on indivudal sound sources in addition
10800   * to the master output.
10801   *
10802   * This class extends <a href = "/reference/#/p5.Effect">p5.Effect</a>.
10803   * Methods <a href = "/reference/#/p5.Effect/amp">amp()</a>, <a href = "/reference/#/p5.Effect/chain">chain()</a>,
10804   * <a href = "/reference/#/p5.Effect/drywet">drywet()</a>, <a href = "/reference/#/p5.Effect/connect">connect()</a>, and
10805   * <a href = "/reference/#/p5.Effect/disconnect">disconnect()</a> are available.
10806   *
10807   * @class p5.Compressor
10808   * @constructor
10809   * @extends p5.Effect
10810   *
10811   *
10812   */
10813
10814
10815  p5.Compressor = function () {
10816    Effect.call(this);
10817    /**
10818     * The p5.Compressor is built with a <a href="https://www.w3.org/TR/webaudio/#the-dynamicscompressornode-interface"
10819    *   target="_blank" title="W3 spec for Dynamics Compressor Node">Web Audio Dynamics Compressor Node
10820    *   </a>
10821     * @property {AudioNode} compressor
10822     */
10823
10824    this.compressor = this.ac.createDynamicsCompressor();
10825    this.input.connect(this.compressor);
10826    this.compressor.connect(this.wet);
10827  };
10828
10829  p5.Compressor.prototype = Object.create(Effect.prototype);
10830  /**
10831   * Performs the same function as .connect, but also accepts
10832   * optional parameters to set compressor's audioParams
10833   * @method process
10834   * @for p5.Compressor
10835   *
10836   * @param {Object} src         Sound source to be connected
10837   *
10838   * @param {Number} [attack]     The amount of time (in seconds) to reduce the gain by 10dB,
10839   *                            default = .003, range 0 - 1
10840   * @param {Number} [knee]       A decibel value representing the range above the
10841   *                            threshold where the curve smoothly transitions to the "ratio" portion.
10842   *                            default = 30, range 0 - 40
10843   * @param {Number} [ratio]      The amount of dB change in input for a 1 dB change in output
10844   *                            default = 12, range 1 - 20
10845   * @param {Number} [threshold]  The decibel value above which the compression will start taking effect
10846   *                            default = -24, range -100 - 0
10847   * @param {Number} [release]    The amount of time (in seconds) to increase the gain by 10dB
10848   *                            default = .25, range 0 - 1
10849   */
10850
10851  p5.Compressor.prototype.process = function (src, attack, knee, ratio, threshold, release) {
10852    src.connect(this.input);
10853    this.set(attack, knee, ratio, threshold, release);
10854  };
10855  /**
10856   * Set the paramters of a compressor.
10857   * @method  set
10858   * @for p5.Compressor
10859   * @param {Number} attack     The amount of time (in seconds) to reduce the gain by 10dB,
10860   *                            default = .003, range 0 - 1
10861   * @param {Number} knee       A decibel value representing the range above the
10862   *                            threshold where the curve smoothly transitions to the "ratio" portion.
10863   *                            default = 30, range 0 - 40
10864   * @param {Number} ratio      The amount of dB change in input for a 1 dB change in output
10865   *                            default = 12, range 1 - 20
10866   * @param {Number} threshold  The decibel value above which the compression will start taking effect
10867   *                            default = -24, range -100 - 0
10868   * @param {Number} release    The amount of time (in seconds) to increase the gain by 10dB
10869   *                            default = .25, range 0 - 1
10870   */
10871
10872
10873  p5.Compressor.prototype.set = function (attack, knee, ratio, threshold, release) {
10874    if (typeof attack !== 'undefined') {
10875      this.attack(attack);
10876    }
10877
10878    if (typeof knee !== 'undefined') {
10879      this.knee(knee);
10880    }
10881
10882    if (typeof ratio !== 'undefined') {
10883      this.ratio(ratio);
10884    }
10885
10886    if (typeof threshold !== 'undefined') {
10887      this.threshold(threshold);
10888    }
10889
10890    if (typeof release !== 'undefined') {
10891      this.release(release);
10892    }
10893  };
10894  /**
10895   * Get current attack or set value w/ time ramp
10896   *
10897   *
10898   * @method attack
10899   * @for p5.Compressor
10900   * @param {Number} [attack] Attack is the amount of time (in seconds) to reduce the gain by 10dB,
10901   *                          default = .003, range 0 - 1
10902   * @param {Number} [time]  Assign time value to schedule the change in value
10903   */
10904
10905
10906  p5.Compressor.prototype.attack = function (attack, time) {
10907    var t = time || 0;
10908
10909    if (typeof attack == 'number') {
10910      this.compressor.attack.value = attack;
10911      this.compressor.attack.cancelScheduledValues(this.ac.currentTime + 0.01 + t);
10912      this.compressor.attack.linearRampToValueAtTime(attack, this.ac.currentTime + 0.02 + t);
10913    } else if (typeof attack !== 'undefined') {
10914      attack.connect(this.compressor.attack);
10915    }
10916
10917    return this.compressor.attack.value;
10918  };
10919  /**
10920    * Get current knee or set value w/ time ramp
10921    *
10922    * @method knee
10923    * @for p5.Compressor
10924    * @param {Number} [knee] A decibel value representing the range above the
10925    *                        threshold where the curve smoothly transitions to the "ratio" portion.
10926    *                        default = 30, range 0 - 40
10927    * @param {Number} [time]  Assign time value to schedule the change in value
10928    */
10929
10930
10931  p5.Compressor.prototype.knee = function (knee, time) {
10932    var t = time || 0;
10933
10934    if (typeof knee == 'number') {
10935      this.compressor.knee.value = knee;
10936      this.compressor.knee.cancelScheduledValues(this.ac.currentTime + 0.01 + t);
10937      this.compressor.knee.linearRampToValueAtTime(knee, this.ac.currentTime + 0.02 + t);
10938    } else if (typeof knee !== 'undefined') {
10939      knee.connect(this.compressor.knee);
10940    }
10941
10942    return this.compressor.knee.value;
10943  };
10944  /**
10945   * Get current ratio or set value w/ time ramp
10946   * @method ratio
10947   * @for p5.Compressor
10948   * @param {Number} [ratio]      The amount of dB change in input for a 1 dB change in output
10949   *                            default = 12, range 1 - 20
10950   * @param {Number} [time]  Assign time value to schedule the change in value
10951   */
10952
10953
10954  p5.Compressor.prototype.ratio = function (ratio, time) {
10955    var t = time || 0;
10956
10957    if (typeof ratio == 'number') {
10958      this.compressor.ratio.value = ratio;
10959      this.compressor.ratio.cancelScheduledValues(this.ac.currentTime + 0.01 + t);
10960      this.compressor.ratio.linearRampToValueAtTime(ratio, this.ac.currentTime + 0.02 + t);
10961    } else if (typeof ratio !== 'undefined') {
10962      ratio.connect(this.compressor.ratio);
10963    }
10964
10965    return this.compressor.ratio.value;
10966  };
10967  /**
10968   * Get current threshold or set value w/ time ramp
10969   * @method threshold
10970   * @for p5.Compressor
10971   * @param {Number} threshold  The decibel value above which the compression will start taking effect
10972   *                            default = -24, range -100 - 0
10973   * @param {Number} [time]  Assign time value to schedule the change in value
10974   */
10975
10976
10977  p5.Compressor.prototype.threshold = function (threshold, time) {
10978    var t = time || 0;
10979
10980    if (typeof threshold == 'number') {
10981      this.compressor.threshold.value = threshold;
10982      this.compressor.threshold.cancelScheduledValues(this.ac.currentTime + 0.01 + t);
10983      this.compressor.threshold.linearRampToValueAtTime(threshold, this.ac.currentTime + 0.02 + t);
10984    } else if (typeof threshold !== 'undefined') {
10985      threshold.connect(this.compressor.threshold);
10986    }
10987
10988    return this.compressor.threshold.value;
10989  };
10990  /**
10991   * Get current release or set value w/ time ramp
10992   * @method release
10993   * @for p5.Compressor
10994   * @param {Number} release    The amount of time (in seconds) to increase the gain by 10dB
10995   *                            default = .25, range 0 - 1
10996   *
10997   * @param {Number} [time]  Assign time value to schedule the change in value
10998   */
10999
11000
11001  p5.Compressor.prototype.release = function (release, time) {
11002    var t = time || 0;
11003
11004    if (typeof release == 'number') {
11005      this.compressor.release.value = release;
11006      this.compressor.release.cancelScheduledValues(this.ac.currentTime + 0.01 + t);
11007      this.compressor.release.linearRampToValueAtTime(release, this.ac.currentTime + 0.02 + t);
11008    } else if (typeof number !== 'undefined') {
11009      release.connect(this.compressor.release);
11010    }
11011
11012    return this.compressor.release.value;
11013  };
11014  /**
11015   * Return the current reduction value
11016   *
11017   * @method reduction
11018   * @for p5.Compressor
11019   * @return {Number} Value of the amount of gain reduction that is applied to the signal
11020   */
11021
11022
11023  p5.Compressor.prototype.reduction = function () {
11024    return this.compressor.reduction.value;
11025  };
11026
11027  p5.Compressor.prototype.dispose = function () {
11028    Effect.prototype.dispose.apply(this);
11029
11030    if (this.compressor) {
11031      this.compressor.disconnect();
11032      delete this.compressor;
11033    }
11034  };
11035
11036  return p5.Compressor;
11037}).call(exports, __webpack_require__, exports, module),
11038				__WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));
11039
11040 }),
11041 (function(module, exports, __webpack_require__) {
11042
11043"use strict";
11044var __WEBPACK_AMD_DEFINE_RESULT__;
11045
11046!(__WEBPACK_AMD_DEFINE_RESULT__ = (function (require) {
11047  var p5sound = __webpack_require__(1);
11048
11049  var _require = __webpack_require__(6),
11050      convertToWav = _require.convertToWav,
11051      safeBufferSize = _require.safeBufferSize;
11052
11053  var processorNames = __webpack_require__(10);
11054
11055  var ac = p5sound.audiocontext;
11056  /**
11057   *  <p>
11057Record sounds for playback and/or to save as a .wav file.
11058   *  The p5.SoundRecorder records all sound output from your sketch,
11059   *  or can be assigned a specific source with setInput().</p>
11060   *  <p>The record() method accepts a p5.SoundFile as a parameter.
11061   *  When playback is stopped (either after the given amount of time,
11062   *  or with the stop() method), the p5.SoundRecorder will send its
11063   *  recording to that p5.SoundFile for playback.</p>
11064   *
11065   *  @class p5.SoundRecorder
11066   *  @constructor
11067   *  @example
11068   *  <div><code>
11069   *  let mic, recorder, soundFile;
11070   *  let state = 0;
11071   *
11072   *  function setup() {
11073   *    let cnv = createCanvas(100, 100);
11074   *    cnv.mousePressed(canvasPressed);
11075   *    background(220);
11076   *    textAlign(CENTER, CENTER);
11077   *
11078   *    // create an audio in
11079   *    mic = new p5.AudioIn();
11080   *
11081   *    // prompts user to enable their browser mic
11082   *    mic.start();
11083   *
11084   *    // create a sound recorder
11085   *    recorder = new p5.SoundRecorder();
11086   *
11087   *    // connect the mic to the recorder
11088   *    recorder.setInput(mic);
11089   *
11090   *    // this sound file will be used to
11091   *    // playback & save the recording
11092   *    soundFile = new p5.SoundFile();
11093   *
11094   *    text('tap to record', width/2, height/2);
11095   *  }
11096   *
11097   *  function canvasPressed() {
11098   *    // ensure audio is enabled
11099   *    userStartAudio();
11100   *
11101   *    // make sure user enabled the mic
11102   *    if (state === 0 && mic.enabled) {
11103   *
11104   *      // record to our p5.SoundFile
11105   *      recorder.record(soundFile);
11106   *
11107   *      background(255,0,0);
11108   *      text('Recording!', width/2, height/2);
11109   *      state++;
11110   *    }
11111   *    else if (state === 1) {
11112   *      background(0,255,0);
11113   *
11114   *      // stop recorder and
11115   *      // send result to soundFile
11116   *      recorder.stop();
11117   *
11118   *      text('Done! Tap to play and download', width/2, height/2, width - 20);
11119   *      state++;
11120   *    }
11121   *
11122   *    else if (state === 2) {
11123   *      soundFile.play(); // play the result!
11124   *      save(soundFile, 'mySound.wav');
11125   *      state++;
11126   *    }
11127   *  }
11128   *  </div></code>
11129   */
11130
11131  p5.SoundRecorder = function () {
11132    this.input = ac.createGain();
11133    this.output = ac.createGain();
11134    this._inputChannels = 2;
11135    this._outputChannels = 2; 
11136
11137    var workletBufferSize = safeBufferSize(1024);
11138    this._workletNode = new AudioWorkletNode(ac, processorNames.recorderProcessor, {
11139      outputChannelCount: [this._outputChannels],
11140      processorOptions: {
11141        numInputChannels: this._inputChannels,
11142        bufferSize: workletBufferSize
11143      }
11144    });
11145
11146    this._workletNode.port.onmessage = function (event) {
11147      if (event.data.name === 'buffers') {
11148        var buffers = [new Float32Array(event.data.leftBuffer), new Float32Array(event.data.rightBuffer)];
11149
11150        this._callback(buffers);
11151      }
11152    }.bind(this);
11153    /**
11154     *  callback invoked when the recording is over
11155     *  @private
11156     *  @type Function(Float32Array)
11157     */
11158
11159
11160    this._callback = function () {}; 
11161
11162
11163    this._workletNode.connect(p5.soundOut._silentNode);
11164
11165    this.setInput(); 
11166
11167    p5sound.soundArray.push(this);
11168  };
11169  /**
11170   *  Connect a specific device to the p5.SoundRecorder.
11171   *  If no parameter is given, p5.SoundRecorer will record
11172   *  all audible p5.sound from your sketch.
11173   *
11174   *  @method  setInput
11175   *  @for p5.SoundRecorder
11176   *  @param {Object} [unit] p5.sound object or a web audio unit
11177   *                         that outputs sound
11178   */
11179
11180
11181  p5.SoundRecorder.prototype.setInput = function (unit) {
11182    this.input.disconnect();
11183    this.input = null;
11184    this.input = ac.createGain();
11185    this.input.connect(this._workletNode);
11186    this.input.connect(this.output);
11187
11188    if (unit) {
11189      unit.connect(this.input);
11190    } else {
11191      p5.soundOut.output.connect(this.input);
11192    }
11193  };
11194  /**
11195   *  Start recording. To access the recording, provide
11196   *  a p5.SoundFile as the first parameter. The p5.SoundRecorder
11197   *  will send its recording to that p5.SoundFile for playback once
11198   *  recording is complete. Optional parameters include duration
11199   *  (in seconds) of the recording, and a callback function that
11200   *  will be called once the complete recording has been
11201   *  transfered to the p5.SoundFile.
11202   *
11203   *  @method  record
11204   *  @for p5.SoundRecorder
11205   *  @param  {p5.SoundFile}   soundFile    p5.SoundFile
11206   *  @param  {Number}   [duration] Time (in seconds)
11207   *  @param  {Function} [callback] The name of a function that will be
11208   *                                called once the recording completes
11209   */
11210
11211
11212  p5.SoundRecorder.prototype.record = function (sFile, duration, callback) {
11213    this._workletNode.port.postMessage({
11214      name: 'start',
11215      duration: duration
11216    });
11217
11218    if (sFile && callback) {
11219      this._callback = function (buffer) {
11220        sFile.setBuffer(buffer);
11221        callback();
11222      };
11223    } else if (sFile) {
11224      this._callback = function (buffer) {
11225        sFile.setBuffer(buffer);
11226      };
11227    }
11228  };
11229  /**
11230   *  Stop the recording. Once the recording is stopped,
11231   *  the results will be sent to the p5.SoundFile that
11232   *  was given on .record(), and if a callback function
11233   *  was provided on record, that function will be called.
11234   *
11235   *  @method  stop
11236   *  @for p5.SoundRecorder
11237   */
11238
11239
11240  p5.SoundRecorder.prototype.stop = function () {
11241    this._workletNode.port.postMessage({
11242      name: 'stop'
11243    });
11244  };
11245
11246  p5.SoundRecorder.prototype.dispose = function () {
11247    var index = p5sound.soundArray.indexOf(this);
11248    p5sound.soundArray.splice(index, 1);
11249
11250    this._callback = function () {};
11251
11252    if (this.input) {
11253      this.input.disconnect();
11254    }
11255
11256    this.input = null;
11257    this._workletNode = null;
11258  };
11259  /**
11260   * Save a p5.SoundFile as a .wav file. The browser will prompt the user
11261   * to download the file to their device.
11262   * For uploading audio to a server, use
11263   * <a href="/docs/reference/#/p5.SoundFile/saveBlob">`p5.SoundFile.saveBlob`</a>.
11264   *
11265   *  @for p5
11266   *  @method saveSound
11267   *  @param  {p5.SoundFile}
11267 soundFile p5.SoundFile that you wish to save
11268   *  @param  {String} fileName      name of the resulting .wav file.
11269   */
11270
11271
11272  p5.prototype.saveSound = function (soundFile, fileName) {
11273    var dataView = convertToWav(soundFile.buffer);
11274    p5.prototype.writeFile([dataView], fileName, 'wav');
11275  };
11276}).call(exports, __webpack_require__, exports, module),
11277				__WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));
11278
11279 }),
11280 (function(module, exports, __webpack_require__) {
11281
11282"use strict";
11283var __WEBPACK_AMD_DEFINE_RESULT__;
11284
11285!(__WEBPACK_AMD_DEFINE_RESULT__ = (function () {
11286  /**
11287   *  <p>PeakDetect works in conjunction with p5.FFT to
11288   *  look for onsets in some or all of the frequency spectrum.
11289   *  </p>
11290   *  <p>
11291   *  To use p5.PeakDetect, call <code>update</code> in the draw loop
11292   *  and pass in a p5.FFT object.
11293   *  </p>
11294   *  <p>
11295   *  You can listen for a specific part of the frequency spectrum by
11296   *  setting the range between <code>freq1</code> and <code>freq2</code>.
11297   *  </p>
11298   *
11299   *  <p><code>threshold</code> is the threshold for detecting a peak,
11300   *  scaled between 0 and 1. It is logarithmic, so 0.1 is half as loud
11301   *  as 1.0.</p>
11302   *
11303   *  <p>
11304   *  The update method is meant to be run in the draw loop, and
11305   *  <b>frames</b> determines how many loops must pass before
11306   *  another peak can be detected.
11307   *  For example, if the frameRate() = 60, you could detect the beat of a
11308   *  120 beat-per-minute song with this equation:
11309   *  <code> framesPerPeak = 60 / (estimatedBPM / 60 );</code>
11310   *  </p>
11311   *
11312   *  <p>
11313   *  Based on example contribtued by @b2renger, and a simple beat detection
11314   *  explanation by <a
11315   *  href="http://www.airtightinteractive.com/2013/10/making-audio-reactive-visuals/"
11316   *  target="_blank">Felix Turner</a>.
11317   *  </p>
11318   *
11319   *  @class  p5.PeakDetect
11320   *  @constructor
11321   *  @param {Number} [freq1]     lowFrequency - defaults to 20Hz
11322   *  @param {Number} [freq2]     highFrequency - defaults to 20000 Hz
11323   *  @param {Number} [threshold] Threshold for detecting a beat between 0 and 1
11324   *                            scaled logarithmically where 0.1 is 1/2 the loudness
11325   *                            of 1.0. Defaults to 0.35.
11326   *  @param {Number} [framesPerPeak]     Defaults to 20.
11327   *  @example
11328   *  <div><code>
11329   *
11330   *  var cnv, soundFile, fft, peakDetect;
11331   *  var ellipseWidth = 10;
11332   *
11333   *  function preload() {
11334   *    soundFile = loadSound('assets/beat.mp3');
11335   *  }
11336   *
11337   *  function setup() {
11338   *    background(0);
11339   *    noStroke();
11340   *    fill(255);
11341   *    textAlign(CENTER);
11342   *
11343   *    // p5.PeakDetect requires a p5.FFT
11344   *    fft = new p5.FFT();
11345   *    peakDetect = new p5.PeakDetect();
11346   *  }
11347   *
11348   *  function draw() {
11349   *    background(0);
11350   *    text('click to play/pause', width/2, height/2);
11351   *
11352   *    // peakDetect accepts an fft post-analysis
11353   *    fft.analyze();
11354   *    peakDetect.update(fft);
11355   *
11356   *    if ( peakDetect.isDetected ) {
11357   *      ellipseWidth = 50;
11358   *    } else {
11359   *      ellipseWidth *= 0.95;
11360   *    }
11361   *
11362   *    ellipse(width/2, height/2, ellipseWidth, ellipseWidth);
11363   *  }
11364   *
11365   *  // toggle play/stop when canvas is clicked
11366   *  function mouseClicked() {
11367   *    if (mouseX > 0 && mouseX < width && mouseY > 0 && mouseY < height) {
11368   *      if (soundFile.isPlaying() ) {
11369   *        soundFile.stop();
11370   *      } else {
11371   *        soundFile.play();
11372   *      }
11373   *    }
11374   *  }
11375   *  </code></div>
11376   */
11377  p5.PeakDetect = function (freq1, freq2, threshold, _framesPerPeak) {
11378    this.framesPerPeak = _framesPerPeak || 20;
11379    this.framesSinceLastPeak = 0;
11380    this.decayRate = 0.95;
11381    this.threshold = threshold || 0.35;
11382    this.cutoff = 0; 
11383
11384    this.cutoffMult = 1.5;
11385    this.energy = 0;
11386    this.penergy = 0; 
11387
11388    this.currentValue = 0;
11389    /**
11390     *  isDetected is set to true when a peak is detected.
11391     *
11392     *  @attribute isDetected {Boolean}
11393     *  @default  false
11394     */
11395
11396    this.isDetected = false;
11397    this.f1 = freq1 || 40;
11398    this.f2 = freq2 || 20000; 
11399
11400    this._onPeak = function () {};
11401  };
11402  /**
11403   *  The update method is run in the draw loop.
11404   *
11405   *  Accepts an FFT object. You must call .analyze()
11406   *  on the FFT object prior to updating the peakDetect
11407   *  because it relies on a completed FFT analysis.
11408   *
11409   *  @method  update
11410   *  @param  {p5.FFT} fftObject A p5.FFT object
11411   */
11412
11413
11414  p5.PeakDetect.prototype.update = function (fftObject) {
11415    var nrg = this.energy = fftObject.getEnergy(this.f1, this.f2) / 255;
11416
11417    if (nrg > this.cutoff && nrg > this.threshold && nrg - this.penergy > 0) {
11418      this._onPeak();
11419
11420      this.isDetected = true; 
11421
11422      this.cutoff = nrg * this.cutoffMult;
11423      this.framesSinceLastPeak = 0;
11424    } else {
11425      this.isDetected = false;
11426
11427      if (this.framesSinceLastPeak <= this.framesPerPeak) {
11428        this.framesSinceLastPeak++;
11429      } else {
11430        this.cutoff *= this.decayRate;
11431        this.cutoff = Math.max(this.cutoff, this.threshold);
11432      }
11433    }
11434
11435    this.currentValue = nrg;
11436    this.penergy = nrg;
11437  };
11438  /**
11439   *  onPeak accepts two arguments: a function to call when
11440   *  a peak is detected. The value of the peak,
11441   *  between 0.0 and 1.0, is passed to the callback.
11442   *
11443   *  @method  onPeak
11444   *  @param  {Function} callback Name of a function that will
11445   *                              be called when a peak is
11446   *                              detected.
11447   *  @param  {Object}   [val]    Optional value to pass
11448   *                              into the function when
11449   *                              a peak is detected.
11450   *  @example
11451   *  <div><code>
11452   *  var cnv, soundFile, fft, peakDetect;
11453   *  var ellipseWidth = 0;
11454   *
11455   *  function preload() {
11456   *    soundFile = loadSound('assets/beat.mp3');
11457   *  }
11458   *
11459   *  function setup() {
11460   *    cnv = createCanvas(100,100);
11461   *    textAlign(CENTER);
11462   *
11463   *    fft = new p5.FFT();
11464   *    peakDetect = new p5.PeakDetect();
11465   *
11466   *    setupSound();
11467   *
11468   *    // when a beat is detected, call triggerBeat()
11469   *    peakDetect.onPeak(triggerBeat);
11470   *  }
11471   *
11472   *  function draw() {
11473   *    background(0);
11474   *    fill(255);
11475   *    text('click to play', width/2, height/2);
11476   *
11477   *    fft.analyze();
11478   *    peakDetect.update(fft);
11479   *
11480   *    ellipseWidth *= 0.95;
11481   *    ellipse(width/2, height/2, ellipseWidth, ellipseWidth);
11482   *  }
11483   *
11484   *  // this function is called by peakDetect.onPeak
11485   *  function triggerBeat() {
11486   *    ellipseWidth = 50;
11487   *  }
11488   *
11489   *  // mouseclick starts/stops sound
11490   *  function setupSound() {
11491   *    cnv.mouseClicked( function() {
11492   *      if (soundFile.isPlaying() ) {
11493   *        soundFile.stop();
11494   *      } else {
11495   *        soundFile.play();
11496   *      }
11497   *    });
11498   *  }
11499   *  </code></div>
11500   */
11501
11502
11503  p5.PeakDetect.prototype.onPeak = function (callback, val) {
11504    var self = this;
11505
11506    self._onPeak = function () {
11507      callback(self.energy, val);
11508    };
11509  };
11510}).call(exports, __webpack_require__, exports, module),
11511				__WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));
11512
11513 }),
11514 (function(module, exports, __webpack_require__) {
11515
11516"use strict";
11517var __WEBPACK_AMD_DEFINE_RESULT__;
11518
11519!(__WEBPACK_AMD_DEFINE_RESULT__ = (function (require) {
11520  var p5sound = __webpack_require__(1);
11521  /**
11522   *  A gain node is usefull to set the relative volume of sound.
11523   *  It's typically used to build mixers.
11524   *
11525   *  @class p5.Gain
11526   *  @constructor
11527   *  @example
11528   *  <div><code>
11529   *
11530   *  // load two soundfile and crossfade beetween them
11531   *  let sound1,sound2;
11532   *  let sound1Gain, sound2Gain, masterGain;
11533   *  function preload(){
11534   *    soundFormats('ogg', 'mp3');
11535   *    sound1 = loadSound('assets/Damscray_-_Dancing_Tiger_01');
11536   *    sound2 = loadSound('assets/beat');
11537   *  }
11538   *  function setup() {
11539   *    let cnv = createCanvas(100, 100);
11540   *    cnv.mousePressed(startSound);
11541   *    // create a 'master' gain to which we will connect both soundfiles
11542   *    masterGain = new p5.Gain();
11543   *    masterGain.connect();
11544   *    sound1.disconnect(); // diconnect from p5 output
11545   *    sound1Gain = new p5.Gain(); // setup a gain node
11546   *    sound1Gain.setInput(sound1); // connect the first sound to its input
11547   *    sound1Gain.connect(masterGain); // connect its output to the 'master'
11548   *    sound2.disconnect();
11549   *    sound2Gain = new p5.Gain();
11550   *    sound2Gain.setInput(sound2);
11551   *    sound2Gain.connect(masterGain);
11552   *  }
11553   *  function startSound() {
11554   *    sound1.loop();
11555   *    sound2.loop();
11556   *    loop();
11557   *  }
11558   *  function mouseReleased() {
11559   *    sound1.stop();
11560   *    sound2.stop();
11561   *  }
11562   *  function draw(){
11563   *    background(220);
11564   *    textAlign(CENTER);
11565   *    textSize(11);
11566   *    fill(0);
11567   *    if (!sound1.isPlaying()) {
11568   *      text('tap and drag to play', width/2, height/2);
11569   *      return;
11570   *    }
11571   *    // map the horizontal position of the mouse to values useable for volume    *  control of sound1
11572   *    var sound1Volume = constrain(map(mouseX,width,0,0,1), 0, 1);
11573   *    var sound2Volume = 1-sound1Volume;
11574   *    sound1Gain.amp(sound1Volume);
11575   *    sound2Gain.amp(sound2Volume);
11576   *    // map the vertical position of the mouse to values useable for 'master    *  volume control'
11577   *    var masterVolume = constrain(map(mouseY,height,0,0,1), 0, 1);
11578   *    masterGain.amp(masterVolume);
11579   *    text('master', width/2, height - masterVolume * height * 0.9)
11580   *    fill(255, 0, 255);
11581   *    textAlign(LEFT);
11582   *    text('sound1', 5, height - sound1Volume * height * 0.9);
11583   *    textAlign(RIGHT);
11584   *    text('sound2', width - 5, height - sound2Volume * height * 0.9);
11585   *  }
11586   *</code></div>
11587   */
11588
11589
11590  p5.Gain = function () {
11591    this.ac = p5sound.audiocontext;
11592    this.input = this.ac.createGain();
11593    this.output = this.ac.createGain(); 
11594
11595    this.input.gain.value = 0.5;
11596    this.input.connect(this.output); 
11597
11598    p5sound.soundArray.push(this);
11599  };
11600  /**
11601   *  Connect a source to the gain node.
11602   *
11603   *  @method  setInput
11604   *  @for p5.Gain
11605   *  @param  {Object} src     p5.sound / Web Audio object with a sound
11606   *                           output.
11607   */
11608
11609
11610  p5.Gain.prototype.setInput = function (src) {
11611    src.connect(this.input);
11612  };
11613  /**
11614   *  Send output to a p5.sound or web audio object
11615   *
11616   *  @method  connect
11617   *  @for p5.Gain
11618   *  @param  {Object} unit
11619   */
11620
11621
11622  p5.Gain.prototype.connect = function (unit) {
11623    var u = unit || p5.soundOut.input;
11624    this.output.connect(u.input ? u.input : u);
11625  };
11626  /**
11627   *  Disconnect all output.
11628   *
11629   *  @method disconnect
11630   *  @for p5.Gain
11631   */
11632
11633
11634  p5.Gain.prototype.disconnect = function () {
11635    if (this.output) {
11636      this.output.disconnect();
11637    }
11638  };
11639  /**
11640   *  Set the output level of the gain node.
11641   *
11642   *  @method  amp
11643   *  @for p5.Gain
11644   *  @param  {Number} volume amplitude between 0 and 1.0
11645   *  @param  {Number} [rampTime] create a fade that lasts rampTime
11646   *  @param  {Number} [timeFromNow] schedule this event to happen
11647   *                                seconds from now
11648   */
11649
11650
11651  p5.Gain.prototype.amp = function (vol, rampTime, tFromNow) {
11652    var rampTime = rampTime || 0;
11653    var tFromNow = tFromNow || 0;
11654    var now = p5sound.audiocontext.currentTime;
11655    var currentVol = this.output.gain.value;
11656    this.output.gain.cancelScheduledValues(now);
11657    this.output.gain.linearRampToValueAtTime(currentVol, now + tFromNow);
11658    this.output.gain.linearRampToValueAtTime(vol, now + tFromNow + rampTime);
11659  };
11660
11661  p5.Gain.prototype.dispose = function () {
11662    var index = p5sound.soundArray.indexOf(this);
11663    p5sound.soundArray.splice(index, 1);
11664
11665    if (this.output) {
11666      this.output.disconnect();
11667      delete this.output;
11668    }
11669
11670    if (this.input) {
11671      this.input.disconnect();
11672      delete this.input;
11673    }
11674  };
11675}).call(exports, __webpack_require__, exports, module),
11676				__WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));
11677
11678 }),
11679 (function(module, exports, __webpack_require__) {
11680
11681"use strict";
11682var __WEBPACK_AMD_DEFINE_RESULT__;
11683
11684!(__WEBPACK_AMD_DEFINE_RESULT__ = (function (require) {
11685  var Effect = __webpack_require__(4);
11686
11687
11688  function makeDistortionCurve(amount) {
11689    var k = typeof amount === 'number' ? amount : 50;
11690    var numSamples = 44100;
11691    var curve = new Float32Array(numSamples);
11692    var deg = Math.PI / 180;
11693    var i = 0;
11694    var x;
11695
11696    for (; i < numSamples; ++i) {
11697      x = i * 2 / numSamples - 1;
11698      curve[i] = (3 + k) * x * 20 * deg / (Math.PI + k * Math.abs(x));
11699    }
11700
11701    return curve;
11702  }
11703  /**
11704   * A Distortion effect created with a Waveshaper Node,
11705   * with an approach adapted from
11706   * [Kevin Ennis](http://stackoverflow.com/questions/22312841/waveshaper-node
11706-in-webaudio-how-to-emulate-distortion)
11707   *
11708   * This class extends <a href = "/reference/#/p5.Effect">p5.Effect</a>.
11709   * Methods <a href = "/reference/#/p5.Effect/amp">amp()</a>, <a href = "/reference/#/p5.Effect/chain">chain()</a>,
11710   * <a href = "/reference/#/p5.Effect/drywet">drywet()</a>, <a href = "/reference/#/p5.Effect/connect">connect()</a>, and
11711   * <a href = "/reference/#/p5.Effect/disconnect">disconnect()</a> are available.
11712   *
11713   * @class p5.Distortion
11714   * @extends p5.Effect
11715   * @constructor
11716   * @param {Number} [amount=0.25] Unbounded distortion amount.
11717   *                                Normal values range from 0-1.
11718   * @param {String} [oversample='none'] 'none', '2x', or '4x'.
11719   *
11720   */
11721
11722
11723  p5.Distortion = function (amount, oversample) {
11724    Effect.call(this);
11725
11726    if (typeof amount === 'undefined') {
11727      amount = 0.25;
11728    }
11729
11730    if (typeof amount !== 'number') {
11731      throw new Error('amount must be a number');
11732    }
11733
11734    if (typeof oversample === 'undefined') {
11735      oversample = '2x';
11736    }
11737
11738    if (typeof oversample !== 'string') {
11739      throw new Error('oversample must be a String');
11740    }
11741
11742    var curveAmount = p5.prototype.map(amount, 0.0, 1.0, 0, 2000);
11743    /**
11744     *  The p5.Distortion is built with a
11745     *  <a href="http://www.w3.org/TR/webaudio/#WaveShaperNode">
11746     *  Web Audio WaveShaper Node</a>.
11747     *
11748     *  @property {AudioNode} WaveShaperNode
11749     */
11750
11751    this.waveShaperNode = this.ac.createWaveShaper();
11752    this.amount = curveAmount;
11753    this.waveShaperNode.curve = makeDistortionCurve(curveAmount);
11754    this.waveShaperNode.oversample = oversample;
11755    this.input.connect(this.waveShaperNode);
11756    this.waveShaperNode.connect(this.wet);
11757  };
11758
11759  p5.Distortion.prototype = Object.create(Effect.prototype);
11760  /**
11761   * Process a sound source, optionally specify amount and oversample values.
11762   *
11763   * @method process
11764   * @for p5.Distortion
11765   * @param {Number} [amount=0.25] Unbounded distortion amount.
11766   *                                Normal values range from 0-1.
11767   * @param {String} [oversample='none'] 'none', '2x', or '4x'.
11768   */
11769
11770  p5.Distortion.prototype.process = function (src, amount, oversample) {
11771    src.connect(this.input);
11772    this.set(amount, oversample);
11773  };
11774  /**
11775   * Set the amount and oversample of the waveshaper distortion.
11776   *
11777   * @method set
11778   * @for p5.Distortion
11779   * @param {Number} [amount=0.25] Unbounded distortion amount.
11780   *                                Normal values range from 0-1.
11781   * @param {String} [oversample='none'] 'none', '2x', or '4x'.
11782   */
11783
11784
11785  p5.Distortion.prototype.set = function (amount, oversample) {
11786    if (amount) {
11787      var curveAmount = p5.prototype.map(amount, 0.0, 1.0, 0, 2000);
11788      this.amount = curveAmount;
11789      this.waveShaperNode.curve = makeDistortionCurve(curveAmount);
11790    }
11791
11792    if (oversample) {
11793      this.waveShaperNode.oversample = oversample;
11794    }
11795  };
11796  /**
11797   *  Return the distortion amount, typically between 0-1.
11798   *
11799   *  @method  getAmount
11800   *  @for p5.Distortion
11801   *  @return {Number} Unbounded distortion amount.
11802   *                   Normal values range from 0-1.
11803   */
11804
11805
11806  p5.Distortion.prototype.getAmount = function () {
11807    return this.amount;
11808  };
11809  /**
11810   *  Return the oversampling.
11811   *
11812   *  @method getOversample
11813   *  @for p5.Distortion
11814   *  @return {String} Oversample can either be 'none', '2x', or '4x'.
11815   */
11816
11817
11818  p5.Distortion.prototype.getOversample = function () {
11819    return this.waveShaperNode.oversample;
11820  };
11821
11822  p5.Distortion.prototype.dispose = function () {
11823    Effect.prototype.dispose.apply(this);
11824
11825    if (this.waveShaperNode) {
11826      this.waveShaperNode.disconnect();
11827      this.waveShaperNode = null;
11828    }
11829  };
11830}).call(exports, __webpack_require__, exports, module),
11831				__WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));
11832
11833 })
11834 ]);

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.